Вопрос

У меня возникли проблемы с загрузкой двоичного файла (видео) в мое приложение из Интернета.В Quicktime, если я загружаю его напрямую, он работает нормально, но через мое приложение каким-то образом получается путаница (хотя в текстовом редакторе они выглядят точно так же).Вот такой пример:

    URL u = new URL("http://www.path.to/a.mp4?video");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File(root,"Video.mp4"));


    InputStream in = c.getInputStream();

    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ( (len1 = in.read(buffer)) > 0 ) {
         f.write(buffer);
    }
    f.close();
Это было полезно?

Решение

Я не знаю, единственная ли это проблема, но у вас там классический Java-глюк:Вы не рассчитываете на тот факт, что read() является всегда разрешено возвращать меньше байтов, чем вы запрашиваете.Таким образом, ваше чтение может занять менее 1024 байт, но ваша запись всегда записывает ровно 1024 байта, возможно, включая байты из предыдущей итерации цикла.

Правильно с:

 while ( (len1 = in.read(buffer)) > 0 ) {
         f.write(buffer,0, len1);
 }

Возможно, более высокая задержка в сети или меньшие размеры пакетов 3G на Android усугубляют эффект?

Другие советы

new DefaultHttpClient().execute(new HttpGet("http://www.path.to/a.mp4?video"))
        .getEntity().writeTo(
                new FileOutputStream(new File(root,"Video.mp4")));

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

byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
  f.write(buffer,0, len1);
}
 public class download extends Activity {

     private static String fileName = "file.3gp";
     private static final String MY_URL = "Your download url goes here";

     @Override
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        try {
            URL url = new URL(MY_URL);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = Environment.getExternalStorageDirectory()
                + "/download/";
            Log.d("Abhan", "PATH: " + PATH);
            File file = new File(PATH);
            if(!file.exists()) {
               file.mkdirs();
            }
            File outputFile = new File(file, fileName);
            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = c.getInputStream();
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (IOException e) {
            Log.e("Abhan", "Error: " + e);
        }
        Log.i("Abhan", "Check Your File.");
    } 
}

Я исправил код, основанный на предыдущих отзывах в этой теме.Я тестировал с использованием eclipse и нескольких больших файлов.Это работает нормально.Просто нужно скопировать и вставить это в вашу среду и изменить http-путь и местоположение, в которое вы хотели бы загрузить файл.

try {
    //this is the file you want to download from the remote server
    String path ="http://localhost:8080/somefile.zip";
    //this is the name of the local file you will create
    String targetFileName
        boolean eof = false;
    URL u = new URL(path);
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("c:\\junk\\"+targetFileName));
        InputStream in = c.getInputStream();
        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ( (len1 = in.read(buffer)) > 0 ) {
        f.write(buffer,0, len1);
                 }
    f.close();
    } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (ProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Удачи Алиреза Агамохаммади

Просто используйте метод копирования apache (Ввод -вывод Apache Commons) - преимущество использования Java!

IOUtils.copy(is, os);

Не забудьте закрыть потоки в блоке finally:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top