首先是从网络上获取输入流
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
个字节写入此输出流。
FilterOutputStream
的 write
方法将 b
、0
和 b.length
作为三个参数来调用 write
方法。
注意,此方法不调用其底层流的只带有单个参数 b
的 write
方法。
通过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