Android ke stažení problémy binárních souborů

hlasů
69

Mám potíže se stahováním binární soubor (video) ve své aplikaci z internetu. V Quicktime, Kdybych ho stáhnout přímo to funguje dobře, ale díky mé aplikaci nějak dostat to zpackal (i když vypadají úplně stejně v textovém editoru). Zde je příklad:

    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();
Položena 23/02/2009 v 05:18
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
91

Nevím, jestli je to jediný problém, ale máte klasickou Java závada tam: Nejste počítá s tím, že read () je vždy dovoleno vrátit se méně bytů než žádat. Tak, vaše čtení mohl dostat menší než 1024 bajtů, ale vaše write vždy vypíše přesně 1024 bajtů případně včetně bytů z předchozího smyčky iterace.

Správná s:

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

Možná, že čím vyšší latence sítě nebo menší velikosti paketů 3G na Androidu se zhoršuje efekt?

Odpovězeno 23/02/2009 v 05:45
zdroj uživatelem

hlasů
28
new DefaultHttpClient().execute(new HttpGet("http://www.path.to/a.mp4?video"))
        .getEntity().writeTo(
                new FileOutputStream(new File(root,"Video.mp4")));
Odpovězeno 12/05/2011 v 16:04
zdroj uživatelem

hlasů
16

Jedním z problémů je váš čtení vyrovnávací paměti. Pokud by každá čtení ze vstupního proudu není přesným násobkem 1024 budete kopírovat chybná data. Použití:

byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
  f.write(buffer,0, len1);
}
Odpovězeno 23/02/2009 v 05:43
zdroj uživatelem

hlasů
14
 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.");
    } 
}
Odpovězeno 10/12/2010 v 07:13
zdroj uživatelem

hlasů
4

Opravil jsem kód na základě předchozích zpětných vazeb na toto vlákno. Testoval jsem s použitím zatmění a více velkých souborů. To je v pořádku. Stačí zkopírovat a vložit do svého prostředí a změnit cestu http a umístění, které chcete soubor ke stažení na.

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

Hodně štěstí Alireza Aghamohammadi

Odpovězeno 20/04/2011 v 18:59
zdroj uživatelem

hlasů
2

Stačí použít metodu Apache kopírování ( Apache Commons IO ) - tu výhodu, že v Javě!

IOUtils.copy(is, os);

Nezapomeňte zavřít proudy v bloku finally:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
Odpovězeno 20/04/2011 v 11:41
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more