2011-09-14 124 views
3

我正在从web加载图像到本地android手机。我写入文件的代码如下将BufferedInputStream转换为文件

 BufferedInputStream bisMBImage=null; 
     InputStream isImage = null; 
     URL urlImage = null; 
     URLConnection urlImageCon = null; 
     try 
     { 
       urlImage = new URL(imageURL); //you can write here any link 
       urlImageCon = urlImage.openConnection(); 
       isImage = urlImageCon.getInputStream(); 
       bisMBImage = new BufferedInputStream(isImage); 

       int dotPos = imageURL.lastIndexOf("."); 
       if (dotPos > 0) 
       { 
        imageExt = imageURL.substring(dotPos,imageURL.length());  
       } 

       imageFileName = PATH + "t1" + imageExt; 
       File file = new File(imageFileName); 
       if (file.exists()) 
       { 
        file.delete(); 
        Log.d("FD",imageFileName + " deleted"); 
       } 
       ByteArrayBuffer baf = new ByteArrayBuffer(255); 
       Log.d("IMAGEWRITE", "Start to write image to Disk"); 
       int current = 0; 
       try 
       { 
        while ((current = bisMBImage.read()) != -1) 
        { 
          baf.append((byte) current); 
        } 

        FileOutputStream fos = new FileOutputStream(file); 
        fos.write(baf.toByteArray()); 
        fos.close();  
        Log.d("IMAGEWRITE", "Image write to Disk done"); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       }      

       isImage.close(); 
     } 
     catch (IOException e) 
     { 
       Log.d("DownloadImage", "Error: " + e); 
     } 
     finally 
     { 
      isImage = null;   
      urlImageCon = null; 
      urlImage = null; 
     } 

由于某种原因,整个写入文件需要1分钟。有什么方法可以优化这个吗?

+0

这是一个很大的图像吗? – Otra

+0

与奥特拉所要求的相似 - 图像有多大?此外,我看到你已经把'android-emulator'标签放在这个问题上 - 虽然我不使用它,但模拟器对于某些东西可能会很慢,所以我不确定它是否包含文件下载/写入。你有没有在真实设备上试过这个,看看需要多长时间? – Squonk

+0

这是在主UI线程还是在单独的线程中运行? – WindsurferOak

回答

2

您的缓冲区非常小:255个字节。你可以把它变大1024倍(255千字节)。这是一个可以接受的尺寸,这肯定会加速这件事情。

此外,这是非常缓慢的,因为它读取的字节逐一:

while ((current = bisMBImage.read()) != -1) { 
    baf.append((byte) current); 
} 

你应该尝试使用array version of read()代替:read(byte[] buffer, int offset, int byteCount)有大如我所上述的阵列。

2

您应该使用Android HttpClient通过java URL连接获取文件。你的缓冲区也很小。 试试这个剪辑:

FileOutputStream f = new FileOutputStream(new File(root,"yourfile.dat")); 

DefaultHttpClient httpClient = new DefaultHttpClient(); 
HttpGet request = new HttpGet(urlString); 
HttpResponse response = httpClient.execute(request); 
InputStream is = response.getEntity().getContent(); 

byte[] buffer = new byte[1024]; 
int len1 = 0; 
while ((len1 = is.read(buffer)) > 0) { 
     f.write(buffer,0, len1); 
} 
f.close(); 
+2

我想补充一点,如果你正在做HttpGet/HttpClient,你可能会得到这些头文件,在这种情况下,你可以通过阅读Content-Length来确切知道你获得了多少字节,并且你可以使你的字节[]'正是这样的大小。 – Otra

+0

@Otra,另一方面,如果文件非常大,可能会出现OutOfMemoryError – dwbrito