使用输入/输出流在android中复制文件:好的方法和不好的方法 [英] copying files in android with input/output stream: the good and the bad way
问题描述
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
byte[] bytes = new byte[buffer_size];
try {
int count,prog=0;
while ((count = is.read(bytes)) != -1) {
os.write(bytes, 0, count); //write buffer
prog = prog + count;
publishProgress(((long) prog) * 100 / size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
您可能会猜想例程是在AsyncTask内部调用的,因此是publishProgresss
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
有人知道为什么while虽然有效,但是for无效吗?我想念什么?
问题在于您的for循环在第一次运行后检查条件.基本上,该错误是在上一个循环已对它进行良好的读取时发生的,但在下一个循环中,is.read
调用将返回-1.之后,您尝试调用os.write(bytes,0,-1); -1是无效索引.解决方案是:
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
if(count != -1) {
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
但是它与while循环相比更具可读性,因此我会坚持下去.当您知道要循环的次数时,应使用for循环;对于每个循环,您应循环使用一个循环.
i have made this two routines to copy files using inputstream and outpustream. they are quite the same however the second one rise ArrayIndexOutOfBoundsException while the first one works flawlessly and i don't know why:
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
byte[] bytes = new byte[buffer_size];
try {
int count,prog=0;
while ((count = is.read(bytes)) != -1) {
os.write(bytes, 0, count); //write buffer
prog = prog + count;
publishProgress(((long) prog) * 100 / size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
as you may guess the routine is called inside an AsyncTask, therefore the publishProgresss
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
Does anyone know why the while works but the for no ? what am i missing?
The problem lies in your for loop checking the condition after the first run through. Basically the error occurs when it has read fine the last loop but on the next loop the is.read
call returns -1. Afterwards you try to call os.write(bytes,0,-1); -1 is an invalid index. The solution would be:
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
if(count != -1) {
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
But it is much more readable as the while loop so I would stick with that. For loops should be used either when you know the quantity of times to loop or as a for each where you loop through each individual item of a collection.
这篇关于使用输入/输出流在android中复制文件:好的方法和不好的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!