内容简介:在Java中流的一系列操作,可能会感到既熟悉又陌生。熟悉是因为很基础且出镜率很高,陌生对大多数程序员平时工作中很少写相关的代码。~~ 我是很少写~~回归正题,本章我不不是探讨流,主要来说下造成‘标题’问题的原因。
写在前面
在 Java 中流的一系列操作,可能会感到既熟悉又陌生。熟悉是因为很基础且出镜率很高,陌生对大多数 程序员 平时工作中很少写相关的代码。
~~ 我是很少写~~
回归正题,本章我不不是探讨流,主要来说下造成‘标题’问题的原因。
问题很简单,稍微看下源码或者debug下就可以找到问题所在,这是一些细节问题,既然出现了在此做下记录,给自己一个警惕。
场景引入
今天微信上突然收到前同事一段这样的问题描述
在读取文件时如果文件为空、导致进入while死循环,
并附上一段代码。
/**
* 将文件数据流写入到zip流中
*
* @param fileName
* @param inputStream
* @param outputStream
* @throws IOException
*/
public static void zipInputStream(String fileName, InputStream inputStream, ZipOutputStream outputStream)
throws IOException {
try {
BufferedInputStream bInStream = new BufferedInputStream(inputStream);
outputStream.putNextEntry(new ZipEntry(fileName));
byte[] buffer = new byte[inputStream.available()];
int r = 0;
while ((r = bInStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, r);
}
outputStream.closeEntry();
} catch (IOException e) {
throw e;
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
throw e;
}
}
}
}
咋一看这段代码也没啥问题!
我们一点点的来分析下
首先陷入while死循环的条件 bInStream.read(buffer)) != -1
while ((r = bInStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, r);
}
看下源码中的描述,
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
* <p>
* This method simply performs <code>in.read(b, off, len)</code>
* and returns the result.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
上面描述有这么一段,如果byte[]数组的len为0则不做任何操作直接返回0。
看到这问题基本就可以定位了,在看代码中byte[]的定义。
byte[] buffer = new byte[inputStream.available()];
看到这小伙们就笑了 inputStream.available()
,你读的是一个空文件可不是为0。
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* caller of a method for this input stream. The next caller might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
* <p>
* This method returns the result of {@link #in in}.available().
*
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this input stream without blocking.
* @exception IOException if an I/O error occurs.
*/
public int available() throws IOException {
return in.available();
}
描述的很清楚,返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
说到这基本就反应过来,再说就有点啰嗦了。
总结
像这种问题其实和技术和能力没多大关系、主要是细心和经验。其实定义一个程序员的牛逼与否在于他踩过的坑是否足够多。
既然说到这那就顺便温故下InputStream的几个方法吧!
方法摘要
void close() :关闭此输入流并释放与该流关联的所有系统资源。
void mark(int readlimit):在此输入流中标记当前的位置。
boolean markSupported() :测试此输入流是否支持 mark 和 reset 方法。
abstract int read() :测试此输入流是否支持 mark 和 reset 方法。
int read(byte[] b) :从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len) :将输入流中最多 len 个数据字节读入 byte 数组。
void reset() :将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。
long skip(long n) :跳过和丢弃此输入流中数据的 n 个字节。
以次简单的问题来对InputStream 温故。
如有分析的错误的地方、欢迎指正
以上所述就是小编给大家介绍的《踩坑笔记 >> InputStream.read(byte[]) 造成死循环》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 再谈spring的循环依赖是怎么造成的?
- Class.forName 造成的线程阻塞
- 物联网黑客造成的经济损失有多少?
- 是什么造成了数据库的卡顿
- 一次断电造成ingress"问题" 原 荐
- 是什么造成了数据库的卡顿
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Types and Programming Languages
Benjamin C. Pierce / The MIT Press / 2002-2-1 / USD 95.00
A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of typ......一起来看看 《Types and Programming Languages》 这本书的介绍吧!