Pregunta

Estoy teniendo problemas con la descarga de un archivo binario (vídeo) en mi aplicación de Internet. En Quicktime, Si descargo directamente funciona bien, pero a través de mi aplicación de alguna manera llegar de mal estado (a pesar de que son exactamente los mismos en un editor de texto). He aquí un ejemplo:

    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();
¿Fue útil?

Solución

No sé si es el único problema, pero tienes un problema técnico de Java clásica allí: Usted no está contando con el hecho de que leer () es siempre les permitió regresar menos bytes que puede pedir. Por lo tanto, su lectura podría obtener menos de 1024 bytes, pero su escritura siempre se escribe exactamente 1.024 bytes posiblemente incluyendo bytes de la iteración anterior.

correcta con:

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

Tal vez la mayor de redes de latencia o tamaño de los paquetes más pequeños de 3G en Android están exacerbando el efecto?

Otros consejos

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

Uno de los problemas es su lectura de la memoria intermedia. Si cada lectura de la corriente de entrada no es un múltiplo exacto de 1024 va a copiar datos malos. Uso:

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.");
    } 
}

He arreglado el código basado en evaluaciones anteriores en este hilo. He probado el uso de archivos de gran tamaño y múltiples eclipses. Se está trabajando muy bien. Tan solo hay que copiar y pegar este a su entorno y cambiar la ruta de http y la ubicación que desea el archivo que desea descargar a.

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();
}

Buena suerte Alireza Aghamohamadi

Sólo tiene que usar método de copia de Apache ( Apache Commons IO ) - la ventaja de utilizar Java !

IOUtils.copy(is, os);

No se olvide de cerrar las corrientes en un bloque finally:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top