背景:
在一次使用字节流保存视频文件时,发现播放时画面出现乱码(卡碟)的现象
一开始的代码写法:
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
inputStream = response.body().byteStream();
File file = new File(*******);
if(!file.exists()){
file.createNewFile();
}
try{
fileOutputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024];
while (inputStream.read(bytes) != -1){
fileOutputStream.write(bytes);
}
inputStream.close();
fileOutputStream.close();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(inputStream != null){
inputStream.close();
}
if(fileOutputStream != null){
fileOutputStream.close();
}
}catch (IOException ex){
ex.printStackTrace();
}
}
response.close();
问题就出在while循环中fileOutputStream.write(bytes)这:
- 假设第i次,inputStream读了1024个字节写进bytes里
- 第i+1次时,inputStream只读了500个字节
- 那么,bytes数组里的前500个是i+1次的,而后524个就还是第i次读
- 而.write(bytes)把bytes里的数据都写进去了,变成多些了,造成了卡碟现象
正确写法:
//略
int len;
while ((len = inputStream.read(bytes)) != -1){
fileOutputStream.write(bytes,0,len);
}
//略
附:
一开始我还以为是不是因为outputStream没有调用flush()从而造成在while循环中写入了重复的数据,经调查发现outputStream、fileOutputStream的flush()什么都没做。相反BufferedOutputStream的flush()会把缓存写入到文件,部分源码如下:
public synchronized void flush() throws IOException {
flushBuffer();
out.flush();
}
/** Flush the internal buffer */
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
写程序,还是少一点复制粘贴,多动手,勤思考