Domanda

Sto avendo problemi a scaricare un file binario (video) nella mia app da internet. In QuickTime, Se scarico direttamente funziona bene ma per la mia app in qualche modo ottenere di incasinato (anche se hanno esattamente lo stesso aspetto in un editor di testo). Ecco un esempio:

    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();
È stato utile?

Soluzione

Non so se è l'unico problema, ma ho un problema tecnico Java classico in là: Non stai contando sul fatto che leggere () è sempre il permesso di tornare meno byte di quello che chiedono. Così, il vostro lettura potrebbe ottenere meno di 1024 byte, ma la tua scrittura scrive sempre esattamente 1024 byte possibilmente includendo byte dal precedente iterazione del ciclo.

Una corretta con:

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

Forse la latenza di rete più alto o più piccole dimensioni dei pacchetti di 3G su Android stanno esacerbando l'effetto?

Altri suggerimenti

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

Un problema è la lettura del buffer. Se ogni lettura del flusso di input non è un multiplo esatto di 1024 si copiano dati non corretti. Usa:

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

ho fissato il codice basato su precedenti commenti su questo thread. Ho provato con file di grandi dimensioni eclissi e multiple. Si sta lavorando bene. Basta copiare e incollare questo al vostro ambiente e modificare il percorso http e la posizione che si desidera che il file da scaricare 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();
}

Buona fortuna Alireza Aghamohammadi

Basta usare il metodo copia di Apache ( Apache Commons IO ) - il vantaggio di utilizzare Java !

IOUtils.copy(is, os);

Non dimenticare di chiudere i flussi in un blocco finally:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top