Android скачать проблемы двоичный файл

голоса
69

У меня возникли проблемы с загрузкой двоичного файла (видео) в моем приложении из Интернета. В 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();
Задан 23/02/2009 в 05:18
источник пользователем
На других языках...                            


6 ответов

голоса
91

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

Корректное с:

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

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

Ответил 23/02/2009 d 05:45
источник пользователем

голоса
28
new DefaultHttpClient().execute(new HttpGet("http://www.path.to/a.mp4?video"))
        .getEntity().writeTo(
                new FileOutputStream(new File(root,"Video.mp4")));
Ответил 12/05/2011 d 16:04
источник пользователем

голоса
16

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

byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
  f.write(buffer,0, len1);
}
Ответил 23/02/2009 d 05:43
источник пользователем

голоса
14
 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.");
    } 
}
Ответил 10/12/2010 d 07:13
источник пользователем

голоса
4

Я установил код, основанный на предыдущем обратных по этой теме. Я тестировал с помощью затмений и несколько больших файлов. Это работает отлично. Просто скопировать и вставить это в вашу среду и изменить путь 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();
}

Успехов Реза Aghamohammadi

Ответил 20/04/2011 d 18:59
источник пользователем

голоса
2

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

IOUtils.copy(is, os);

Не забывайте закрывать потоки в блоке, наконец:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Ответил 20/04/2011 d 11:41
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more