InputStream的read方法读取字节不完全的解决方案

  • 2019-02-14
  • 浏览 (2324)

InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的。很多情况我们会发现,这方法不是很靠谱。比如,有一台设备(硬件设备)通过蓝牙发送字节数据给一个APP(APP接收、处理数据并在界面中显示出来)。在APP接收数据的时候,你会发现,事实上,硬件在发送数据的时候并不是整个JSON(假定写成类JSON格式的)一起发送,而是分段的发送(在window10上经常每次接收到是16371字节)。要是我们单次接收、单次处理就会出问题,因为每次接收到的数据可能都是缺失的。因此,我们才需要修改代码,将获取到的字节拼接起来,形成完整的我们需要的字节数据。

好在common-io给我们提供了这样的方法,它的实现方法是每次判断是否到文件末尾或已经读到指定长度,如果没有则继续读。

common-io的maven依赖:
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

使用:

byte[] buffer = new byte[1024];
int len = 0;
while ((len = IOUtils.read(inputStream, buffer)) != -1) {

}

源代码:
/**
 * Reads bytes from an input stream.
 * This implementation guarantees that it will read as many bytes
 * as possible before giving up; this may not always be the case for
 * subclasses of {@link InputStream}.
 *
 * @param input where to read input from
 * @param buffer destination
 * @return actual length read; may be less than requested if EOF was reached
 * @throws IOException if a read error occurs
 * @since 2.2
 */
public static int read(final InputStream input, final byte[] buffer) throws IOException {
    return read(input, buffer, 0, buffer.length);
}

/**
 * Reads bytes from an input stream.
 * This implementation guarantees that it will read as many bytes
 * as possible before giving up; this may not always be the case for
 * subclasses of {@link InputStream}.
 *
 * @param input where to read input from
 * @param buffer destination
 * @param offset initial offset into buffer
 * @param length length to read, must be &gt;= 0
 * @return actual length read; may be less than requested if EOF was reached
 * @throws IOException if a read error occurs
 * @since 2.2
 */
public static int read(final InputStream input, final byte[] buffer, final int offset, final int length)
        throws IOException {
    if (length < 0) {
        throw new IllegalArgumentException("Length must not be negative: " + length);
    }
    int remaining = length;
    while (remaining > 0) {
        final int location = length - remaining;
        final int count = input.read(buffer, offset + location, remaining);
        if (EOF == count) { // EOF
            break;
        }
        remaining -= count;
    }
    return length - remaining;
}

0  赞