从网络上下载图片的纠结

首先是从网络上获取输入流

url = URLDecoder.decode(url);

URL sourceUrl = new URL(url);

HttpURLConnection conn = (HttpURLConnection) sourceUrl.openConnection();   
conn.setDoInput(true);

 

 

InputStream is = conn.getInputStream();

拿到stream后有两种做法,

Bitmap bitmap = BitmapFactory.decodeStream(is);

存储图片

   OutputStream out = null;
   try {
    File file = new File(path+"/"+name);
    File filedic = new File(path);

    // 创建路径
    if (!filedic.exists()) {
     boolean flags = filedic.mkdirs();
     if (!flags) {
      return;
     }
    }
    // 创建文件
    if (!file.exists()) {
     if (!file.createNewFile()) {
      return;
     }
    }
    
    // 存储图片
    out = new FileOutputStream(file);
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    out.flush();
    out.close();

   } catch (FileNotFoundException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    if (out != null)
     try {
      out.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }

 

 

结果出现了常见的bitmap的oom,由于此出取到的图片不用直接引用,使用流直接写到文件,结果杯具产生了,存储后再读出来的图片居然是花了的,最初以为是没有fout。flush(),加上后还是不可以了,后来才试出来是fout。write(byte[], 0, len),不能用fout.write(byte[]);

附上代码

    byte [] b = new byte[1024];    
    fout = new FileOutputStream(path+"/"+fileName);
    int totalLength = 0;
    while(true) {
     int len = is.read(b);
     Log.d(TAG, "getsinger>>in while>>"+len);
     if(len > 0) {
      totalLength += len;
     }else{
      break;
     }
     fout.write(b, 0, len);
    }
    fout.flush();

 

所以从网上查了下问题的区别

 

public class FileCopyTest {

public static final int BUFFER_SIZE=1024*1024;

private File fileForm=new File("D://KB.txt");
private File fileTO=new File("E://KB.txt");

public FileCopyTest(){}

public void copy()throws RuntimeException,IOException
{
   FileInputStream in=new FileInputStream(fileForm);
   BufferedInputStream buffIn=new BufferedInputStream(in,BUFFER_SIZE);
  
   FileOutputStream out=new FileOutputStream(fileTO);
   BufferedOutputStream buffOut=new BufferedOutputStream(out,BUFFER_SIZE);


   byte[] buff=new byte[BUFFER_SIZE];


   int read=0;

 

// 使用此处代码完成文件复制后,文件大小为实际大小。
   while(-1!=(read=buffIn.read(buff, 0, buff.length)))
   {
    buffOut.write(buff, 0, read);
   
   }

  

// 使用此处代码完成文件复制后,目标文件大小变为1M,而实际文件大小为1k
   while((read=buffIn.read(buff))>0)
   {
    buffOut.write(buff);
   }

  
   buffIn.close();
   buffOut.flush();
   buffOut.close();
   in.close();
   out.close();
}
public static void main(String[] arges)
{
   try
   {
    FileCopyTest ft=new FileCopyTest();
    ft.copy();
   }
   catch(Exception ex)
   {
    ex.printStackTrace();
   }
  
  
}
}

上述代码很简单的一个字节流复制文件过程,红色的部分使用的是buffOut.write(buff, 0, read);输出字节流

这个方法将指定 byte 数组buff中从偏移量 0 开始的 read个字节写入此缓冲的输出流。 read为实际读入的字节流。

API上的解释

一般来说,此方法将给定数组的字节存入此流的缓冲区中,根据需要将该缓冲区刷新,并转到底层输出流。但是,如果请求的长度至少与此流的缓冲区大小相同,则此方法将刷新该缓冲区并将各个字节直接写入底层输出流。因此多余的 BufferedOutputStream 将不必复制数据

 

 

蓝色的部分使用buffOut.write(buff);方式输出字节流,

API的介绍

public void write(byte[] b) throws IOException
b.length 个字节写入此输出流。

FilterOutputStreamwrite 方法将 b0b.length 作为三个参数来调用 write 方法。

注意,此方法不调用其底层流的只带有单个参数 bwrite 方法。

通过API说明可以看到,write(byte[] b)方法调用read(byte[] b, int off, int len)方法同时将b,0,len做为参数传递给read(byte[] b, int off, int len)方法。 这是文件输出的字节数len就变成数组的长度b.length而非从输入流中读取到的实际字节数。因此多余的 BufferedOutputStream 也复制数据。

 

 

部分内容参考:http://blog.csdn.net/wud_jiyanhui/archive/2010/08/21/5827814.aspx

http://hi.baidu.com/yehaizi_2008/blog/item/da27b1eda33e19ddb31cb18f.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值