descargar android problemas de archivo binario
-
05-09-2019 - |
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();
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);
}