Лучший способ разработать менеджер загрузки файлов Java

#java #download #io

#java #Скачать #io

Вопрос:

Я хотел бы написать simple Java Downloader для моего резервного веб-сайта. Что важно, апплет должен иметь возможность загружать много файлов одновременно.

Итак, вот моя проблема. Мне кажется, такой апплет легко взломать или заразить. Более того, для его запуска наверняка потребуется много системных ресурсов. Итак, я хотел бы услышать ваше мнение о том, какой способ является лучшим, наиболее оптимальным и наиболее безопасным для этого.

Я думал о чем-то вроде этого:

 //user chose directory to download his files
//fc is a FileChooser
//fc.showSaveDialog(this)==JFileChooser.APPROVE_OPTION
try {
    for(i=0;i<=urls.length-1;i  ){

         String fileName = '...';//obtaining filename and extension

         fileName=fileName.replaceAll(" ", "_");
         //I am not sure if line above resolves all problems with names of files...

         String path = file.getAbsolutePath()   File.separator   fileName;

         try{
              InputStream is=null;
              FileOutputStream os=new FileOutputStream(path);
              URLConnection uc = urls[i].openConnection();
              is = uc.getInputStream();

              int a=is.read();
              while(a!=-1){
                  os.write(a);
                  a=is.read();
              }
              is.close();
              os.close();
         }
         catch(InterruptedIOException iioe) {
              //TODO User cancelled.
         }
         catch(IOException ioe){
              //TODO
         }
     }
}
  

но я уверен, что есть лучшее решение.

Есть еще одна вещь — когда пользователь хочет загрузить действительно огромное количество файлов (например, 1000, от 10 МБ до 1 ГБ), возникнет несколько проблем. Итак, я подумал о том, чтобы установить для него ограничение, но я действительно не знаю, как решить, сколько файлов одновременно в порядке. Должен ли я проверять подключение пользователя к Интернету или загрузку компьютера?

Заранее спасибо

БроМан

Ответ №1:

Я хотел бы написать simple Java Downloader для моего резервного веб-сайта. Что важно, апплет должен иметь возможность загружать много файлов одновременно.

Я надеюсь, вы имеете в виду последовательно, как написан ваш код. В этой ситуации не было бы никакого преимущества в параллельном запуске нескольких потоков загрузки.

Мне кажется, такой апплет легко взломать или заразить.

Убедитесь, что ваш поток связи зашифрован. Поскольку похоже, что вы просто получаете доступ к URL-адресам на сервере, возможно, настройте свой сервер на использование HTTPS.

Более того, для его запуска наверняка потребуется много системных ресурсов.

Почему вы так предполагаете? Ограничивающим фактором будет пропускная способность сети. Вы не будете сильно нагружать свои другие ресурсы. Возможно, вы имели в виду избежать насыщения пропускной способности пользователя. Вы можете реализовать простое регулирование, предоставив пользователю настраиваемую задержку, которую вы вставляете между каждым файлом или даже каждой итерацией вашего цикла чтения / записи. Используйте Thread.sleep для реализации задержки.

Итак, я подумал о том, чтобы установить для него ограничение, но я действительно не знаю, как решить, сколько файлов одновременно в порядке.

Предполагая, что вы выполняете загрузку последовательно, установка ограничений не является техническим вопросом. Подробнее о том, какой сервис вы хотите предоставлять. Больше файлов просто означает, что загрузка занимает больше времени.

int a=is.read();

Ваша реализация потокового чтения / записи очень неэффективна. Вы хотите читать / записывать фрагментами, а не отдельными байтами. Посмотрите версии методов чтения / записи, которые принимают байт[].

Вот базовый логический поток для копирования данных из входного потока в выходной поток.

 InputStream in = null;
OutputStream out = null;

try
{
    in = ...
    out = ...

    final byte[] buf = new byte[ 1024 ];

    for( int count = in.read( buf ); count != -1; count = in.read( buf ) )
    {
        out.write( buf, 0, count );
    }
}
finally
{
    if( in != null )
    {
        in.close();
    }

    if( out != null )
    {
        out.close();
    }
}
  

Комментарии:

1. Большое вам спасибо за ответ. Ваш пост очень полезен для меня. Но одна вещь: я использую int a =is.read(); потому что я слышал, что использование sth типа buf = new byte [size]; os.write (buf); не может работать в Linux. Какую инструкцию вы бы использовали?

2. Почему это не будет работать в Linux? Это не имеет смысла. Вам действительно нужно тщательно подготовить контракт API и обратить внимание на возвращаемый счетчик байтов, но это не зависит от операционной системы.

3. Я знаю, что прошу многого, но не могли бы вы привести мне простейший пример этого? Или, по крайней мере, скажите мне, есть ли код отсюда forum.4programmers.net/Java / … будет ли работать правильно?

4. Сегодня утром я в хорошем настроении, поэтому я обновил сообщение нужным вам фрагментом. Внимательно изучите его и убедитесь, что понимаете, почему он делает все, что делает. Понимание того, как правильно использовать InputStream и OutputStream API, является фундаментальным для программирования на Java.