Android下载二进制文件的问题

我在从互联网下载我的应用程序中的二进制文件(video)时遇到问题。 在Quicktime中,如果我直接下载,它可以正常工作,但是通过我的应用程序,它会被搞乱(即使它们在文本编辑器中看起来完全一样)。 这里是一个例子:

URL u = new URL("a.html"); 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(); 

我不知道这是否是唯一的问题,但是你有一个经典的Java故障在那里:你不指望read() 总是被允许返回less于你要求的字节。 因此,您的读取可能会less于1024个字节,但是您的写入总是正好写出1024个字节,可能包括前一个循环迭代中的字节。

正确的:

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

也许更高的延迟networking或更小的Android包装上的3G数据包正在恶化的影响?

 new DefaultHttpClient().execute(new HttpGet("a.html")) .getEntity().writeTo( new FileOutputStream(new File(root,"Video.mp4"))); 

一个问题是你读的缓冲区。 如果inputstream的每次读取都不是1024的精确倍数,则会复制错误的数据。 使用:

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

我根据之前在这个线程上的反馈修正了代码。 我使用eclipse和多个大文件进行testing。 它工作正常。 只需将其复制并粘贴到您的环境中,然后更改您希望将文件下载到的httppath和位置。

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

祝你好运Alireza Aghamohammadi

只需使用Apache的复制方法( Apache Commons IO ) – 使用Java的优势!

 IOUtils.copy(is, os); 

不要忘记在finally块中closuresstream:

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