Frage

Ich habe Probleme aus dem Internet eine Binärdatei (Video) in meiner App herunterzuladen. In Quicktime, wenn ich es direkt herunterladen es funktioniert gut, aber durch meine app es irgendwie herauf bekommen messed (obwohl sie das gleiche in einem Texteditor sehen genau). Hier ist ein Beispiel:

    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();
War es hilfreich?

Lösung

Ich weiß nicht, ob es das einzige Problem ist, aber Sie haben einen klassischen Java Glitch bekommen dort: Sie sind nicht auf der Tatsache zu zählen, die gelesen () ist immer erlaubt zurückzukehren weniger Bytes als Sie verlangen. So könnte Ihre Lese erhält weniger als 1024 Bytes, aber Ihre Schreib immer schreibt möglicherweise genau 1024 Bytes einschließlich Bytes aus der vorherige Schleifeniterationslatenzzeit.

Correct mit:

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

Vielleicht ist die höhere Latenz Vernetzung oder kleinere Paketgrößen von 3G auf Android verschärfen die Wirkung?

Andere Tipps

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

Ein Problem ist beim Lesen des Puffers. Wenn jeder Lese des Eingangsstroms nicht genau ein Vielfaches von 1024 ist, werden Sie schlechte Daten kopieren. Verwendung:

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

Ich reparierte den Code auf der Grundlage früheres Feedback auf diesem Thread. Getestet habe ich Eclipse und mehrere große Dateien verwenden. Es funktioniert gut. müssen nur kopieren und diese an Ihre Umgebung und ändern Sie den HTTP-Pfad und die Position, die Sie die Datei möchten werden heruntergeladen.

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

Viel Glück Alireza Aghamohammadi

Verwenden Sie einfach das Apache-Kopiermethode ( Apache Commons IO ) - den Vorteil der Verwendung von Java !

IOUtils.copy(is, os);

Vergessen Sie nicht die Ströme in einem finally-Block zu schließen:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top