Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > загрузка содержимого N-хтмл страниц?


Автор: unkis 16.9.2006, 18:51
Ребята есть страница скажем http://vasya.ru/detalis.aspx?id=1123

Надо меняя id сгрузить следуюшие 100 страниц и сохранить их на диск, при етом очень важна скорость.

Канал 6 Mbit

Вот метод для скачивания страницы.
Код

public String UrlConaction(String Url) throws Exception {
        int c;
        String s2 = "";
        URL url = new URL(Url);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn .setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; .NET CLR 1.1.4322)");
        conn.setRequestMethod("GET");
        int len = conn.getContentLength();
        if (len > 0) {

            InputStream input = conn.getInputStream();
            while (((c = input.read()) != -1) && (--len > 0)) {
                s2 += (char) c;
            }
            input.close();
        } else {
            //System.out.println("Net sodergimogo ili no connection");
        }
        return s2;
    }


вот так я сохраняю на диск

Код

FileWriter f = new FileWriter(new File((i++)+".html"));
        f.write(s2);
        f.close();


можно ли ето все как-то ускорить (улучшеть)?

и как ето все сделать мултитредовым?


Зарания благодарен


Автор: y3u 16.9.2006, 20:39
используй NIO   smile 

Автор: LSD 16.9.2006, 21:23
Цитата(unkis @  16.9.2006,  19:51 Найти цитируемый пост)
можно ли ето все как-то ускорить (улучшеть)?
и как ето все сделать мултитредовым?

IMHO NIO тут не сильно поможет если машина достоточно мощная, тут просто узкое место не клиент, а канал. Надо его попытаться выжать на полную катушку. Так что мультипоточность может реально помочь.

А мультитредовым это сделать просто:
- содаешь метод downloadURL() который будет делать всю работу по загрузке нужной странички (он должен быть потокобезопасным)
- а дальше:
Код
public class MultiThread
{
  private BlockingQueue<URL> queue = new LinkedBlockingQueue<URL>();

  public void startDowloading(int threadCount)
  {
    if(threadCount <= 0)
      throw new IllegalArgumentException();

    fillURLS(queue);
    
    for(int i = 0; i < threadCount; i++)
      new Runner().start();
  }

  private void fillURLS(Collection collection)
  {
    //...
  }

  private void downloadURL(URL url) throws Exception
  {
    //...
  }

  private class Runner extends Thread
  {
    @Override
    public void run()
    {
      URL url;
      while((url = queue.poll()) != null)
      {
        try
        {
          downloadURL(url);
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
      }
    }
  }
}

Автор: unkis 17.9.2006, 11:58
не знаю правильно ли я ето делаю, но делаю я ето так.

Код

import java.io.File;
import java.io.FileWriter;

public class Test extends Thread
{
    private static A a = new A();
   
    public static void main(String [] args)
    {
        for (int i = 0; i < Integer.parseInt(args[0], 10); i++)
        {
            Test test = new Test();
            test.start();
        }
    }
    public void run()
    {
        doSomeWork();
    }
    
    public void doSomeWork() 
    {
        a.doWork();
    }
}
class A
{
    private static PageDownloaden page = new PageDownloaden();
    private static int a1 = 3927660, i=0;
    
  
    public void doWork() 
    {
      
        try
        {
            Thread.sleep((int) (100)); 
        }
        catch (InterruptedException ie)
        {
            System.out.println("Interrupted");
        }
        
       try {
        String url = "http://vasya.ru/detalis.aspx?id="+(a1++);
        String s2= page.UrlConaction(url);
        System.out.println(url);
        
        FileWriter f = new FileWriter(new File((i++)+".html"));
        f.write(s2);
        f.close();
        
    } catch (Exception e) {
        
        e.printStackTrace();
    }
        
        System.out.println("Thread:  " + Thread.currentThread().getName() + 
                      " :   a1 = " +a1 );
       
    }
}


ну ето уж очень медленно

Автор: powerOn 17.9.2006, 12:10
А зачем задержку делаешь? 

Цитата(unkis @  17.9.2006,  12:58 Найти цитируемый пост)
Thread.sleep((int) (100)); 


Автор: unkis 17.9.2006, 12:14
не знаю я с тредами первий раз разбираюсь, убрал задержку щсеравно медленно, прозесор грузится по полной а толку никакого.

может у меня метод для скачивания неправельний?

Автор: LSD 17.9.2006, 12:30
Цитата(unkis @  17.9.2006,  13:14 Найти цитируемый пост)
может у меня метод для скачивания неправельний?

Очень может быть, покажи код.

Автор: unkis 17.9.2006, 12:44
я же в верху написал
ну вот еше раз

Код

public String UrlConaction(String Url) throws Exception {
        int c;
        String s2 = "";
        URL url = new URL(Url);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn .setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; .NET CLR 1.1.4322)");
        conn.setRequestMethod("GET");
        int len = conn.getContentLength();
        if (len > 0) {
            InputStream input = conn.getInputStream();
            while (((c = input.read()) != -1) && (--len > 0)) {
                s2 += (char) c;
            }
            input.close();
        } else {
            //System.out.println("Net sodergimogo ili no connection");
        }
        return s2;
    }

Автор: unkis 17.9.2006, 13:25
вот исправил метод загрузки, теперь гараздо бистрее, и приетом канал на полную забит.
Код

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn .setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; .NET CLR 1.1.4322)");
    conn.setRequestMethod("GET");
     StringBuffer content = new StringBuffer();
      BufferedReader buffer_reader = new BufferedReader( new InputStreamReader(conn.getInputStream()));
      String line_separator = System.getProperty("line.separator");
      String next_line = new String();
      while((next_line = buffer_reader.readLine()) != null){
       content.append(next_line+line_separator);
      }

Автор: LSD 17.9.2006, 13:26
Ну конечно, ты же побайтово читаешь, это во первых. А во вторых зачем ты возвращаешь строку? Сразу пиши полученные данные в файл.
Код
public void downloadUrl(String Url, OutputStream out) throws Exception
{
  URL url = new URL(Url);
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn .setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; .NET CLR 1.1.4322)");
  conn.setRequestMethod("GET");
  int len = conn.getContentLength();
  if(len > 0)
  {
    InputStream input = conn.getInputStream();
    int read;
    byte[] buffer = new byte[16 * 1024];
    while((read = input.read(buffer)) != -1)
      out.write(buffer, 0, read);
    input.close();
    out.flush();
  }
  else
  {
    //System.out.println("Net sodergimogo ili no connection");
  }
}

где в качестве OutputStream передавай FileOutputStream куда надо записать данные.

Автор: unkis 17.9.2006, 13:30
а как с тредами посчитать вермыя виполнения.

при такой струкуре

Код

public class MultiThread
{
  private BlockingQueue<URL> queue = new LinkedBlockingQueue<URL>();
  public void startDowloading(int threadCount)
  {
    if(threadCount <= 0)
      throw new IllegalArgumentException();
    fillURLS(queue);
    
    for(int i = 0; i < threadCount; i++)
      new Runner().start();
  }
  private void fillURLS(Collection collection)
  {
    //...
  }
  private void downloadURL(URL url) throws Exception
  {
    //...
  }
  private class Runner extends Thread
  {
    @Override
    public void run()
    {
      URL url;
      while((url = queue.poll()) != null)
      {
        try
        {
          downloadURL(url);
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
      }
    }
  }
}

Автор: LSD 17.9.2006, 13:39
Код
  public void startDowloading(int threadCount)
  {
    if(threadCount <= 0)
      throw new IllegalArgumentException();

    fillURLS(queue);

    long time = System.currentTimeMillis();
    
    Runner[] runners = new Runner[threadCount];
    for(int i = 0; i < threadCount; i++)
    {
      runners[i] = new Runner();
      runners[i].start();
    }
    
    for(int i = 0; i < threadCount; i++)
    {
      try
      {
        runners[i].join();
      }
      catch(InterruptedException e)
      {}
    }
    
    time = System.currentTimeMillis() - time;
    System.out.println("Execution time " + time + " msec");
  }

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)