Android descarga problemas de archivos binarios

Tengo problemas para descargar un archivo binario (video) en mi aplicación desde Internet. En Quicktime, si lo descargo directamente, funciona bien, pero a través de mi aplicación, de alguna manera, se arruina (aunque se ve exactamente igual en un editor de texto). Aquí hay 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(); 

No sé si es el único problema, pero tienes un error clásico de Java: no estás contando con el hecho de que read () siempre puede devolver menos bytes de los que pides. Por lo tanto, su lectura podría obtener menos de 1024 bytes, pero su escritura siempre escribe exactamente 1024 bytes, posiblemente incluyendo bytes de la iteración del bucle anterior.

Correcto con:

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

¿Tal vez la red de latencia más alta o los tamaños de paquete más pequeños de 3G en Android están exacerbando el efecto?

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

Un problema es tu lectura del buffer. Si cada lectura de la secuencia de entrada no es un múltiplo exacto de 1024, se copiarán los datos incorrectos. Utilizar:

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

Arreglé el código basado en retroalimentaciones previas en este hilo. Probé usando eclipse y múltiples archivos grandes. Está funcionando bien. Simplemente tiene que copiar y pegar esto en su entorno y cambiar la ruta http y la ubicación en la que desea que se descargue el archivo.

 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 Aghamohammadi

Simplemente use el método de copia de apache ( Apache Commons IO ) – ¡la ventaja de usar Java!

 IOUtils.copy(is, os); 

No te olvides de cerrar las transmisiones en un bloque finally:

 try{ ... } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); }