InputStream的read()方法是如何实现的?
How InputStream's read() method is implemented?
对于特定任务,我试图为我的扩展 InputStream 的自定义 class 重写 read()
方法。
到目前为止我的实现是:
private ArrayList<byte[]> inputBuffer = new ArrayList<>();
...
@Override
public int read(@NonNull byte[] b) throws IOException {
if (inputBuffer.size() > 0) {
b = inputBuffer.get(0);
inputBuffer.remove(0);
} else
return -1;
return b.length;
}
我正在向我的 InputStream
添加数据,如下所示:
boolean writeDataToInputStream(byte[] data) {
int arrSize = inputBuffer.size();
if (data.length > 0) {
inputBuffer.add(data);
}
return arrSize < inputBuffer.size();
}
我已阅读文档,知道默认情况下此方法的工作原理。但是我需要以某种方式将 ArrayList
元素传递给输入参数 byte[] b
.
我已经在 java 中编写代码几年了,但我从未关注过此方法的实际实现方式。如何将数据传递给传入参数和 return ArrayList 元素写入的字节数?
由于我的架构,我必须使用专门用于带输入和输出流的 BLE 的自定义套接字,我在其中使用 WiFi 套接字、BT 套接字。
请为我揭开这个谜团
当您创建自己的 InputStream
时,您必须实施的唯一方法是 read()
,因为它是 abstract
方法,这也比实施 read(byte[] b)
and/or read(byte b[], int off, int len)
。此外请注意,read(byte b[], int off, int len)
的默认实现已经为您检查了参数,因此除非您想自己重新验证参数,否则您应该只实现 read()
。
因此在您的情况下,此方法可能是:
// Current index in the last byte array read
private int index;
private List<byte[]> inputBuffer = new ArrayList<>();
...
@Override
public int read() throws IOException {
if (inputBuffer.isEmpty()) {
return -1;
}
// Get first element of the List
byte[] bytes = inputBuffer.get(0);
// Get the byte corresponding to the index and post increment the current index
byte result = bytes[index++];
if (index >= bytes.length) {
// It was the last index of the byte array so we remove it from the list
// and reset the current index
inputBuffer.remove(0);
index = 0;
}
return result;
}
但是,如果您真的想实施 read(byte b[], int off, int len)
,它可能如下所示:
@Override
public int read(byte b[], int off, int len) throws IOException {
// Check parameters
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (inputBuffer.isEmpty()) {
return -1;
}
int read = 0;
// Iterate as long as don't get the expected bytes amount and the list is not empty
do {
byte[] bytes = inputBuffer.get(0);
int lg = Math.min(bytes.length - index, len);
// Copy the bytes from "bytes" to "b"
System.arraycopy(bytes, index, b, off, lg);
// Update all counters
read += lg;
off += lg;
index += lg;
len -= lg;
if (index >= bytes.length) {
// It was the last index of the byte array so we remove it from the list
// and reset the current index
inputBuffer.remove(0);
index = 0;
}
} while (read < len && !inputBuffer.isEmpty());
return read;
}
对于特定任务,我试图为我的扩展 InputStream 的自定义 class 重写 read()
方法。
到目前为止我的实现是:
private ArrayList<byte[]> inputBuffer = new ArrayList<>();
...
@Override
public int read(@NonNull byte[] b) throws IOException {
if (inputBuffer.size() > 0) {
b = inputBuffer.get(0);
inputBuffer.remove(0);
} else
return -1;
return b.length;
}
我正在向我的 InputStream
添加数据,如下所示:
boolean writeDataToInputStream(byte[] data) {
int arrSize = inputBuffer.size();
if (data.length > 0) {
inputBuffer.add(data);
}
return arrSize < inputBuffer.size();
}
我已阅读文档,知道默认情况下此方法的工作原理。但是我需要以某种方式将 ArrayList
元素传递给输入参数 byte[] b
.
我已经在 java 中编写代码几年了,但我从未关注过此方法的实际实现方式。如何将数据传递给传入参数和 return ArrayList 元素写入的字节数?
由于我的架构,我必须使用专门用于带输入和输出流的 BLE 的自定义套接字,我在其中使用 WiFi 套接字、BT 套接字。
请为我揭开这个谜团
当您创建自己的 InputStream
时,您必须实施的唯一方法是 read()
,因为它是 abstract
方法,这也比实施 read(byte[] b)
and/or read(byte b[], int off, int len)
。此外请注意,read(byte b[], int off, int len)
的默认实现已经为您检查了参数,因此除非您想自己重新验证参数,否则您应该只实现 read()
。
因此在您的情况下,此方法可能是:
// Current index in the last byte array read
private int index;
private List<byte[]> inputBuffer = new ArrayList<>();
...
@Override
public int read() throws IOException {
if (inputBuffer.isEmpty()) {
return -1;
}
// Get first element of the List
byte[] bytes = inputBuffer.get(0);
// Get the byte corresponding to the index and post increment the current index
byte result = bytes[index++];
if (index >= bytes.length) {
// It was the last index of the byte array so we remove it from the list
// and reset the current index
inputBuffer.remove(0);
index = 0;
}
return result;
}
但是,如果您真的想实施 read(byte b[], int off, int len)
,它可能如下所示:
@Override
public int read(byte b[], int off, int len) throws IOException {
// Check parameters
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (inputBuffer.isEmpty()) {
return -1;
}
int read = 0;
// Iterate as long as don't get the expected bytes amount and the list is not empty
do {
byte[] bytes = inputBuffer.get(0);
int lg = Math.min(bytes.length - index, len);
// Copy the bytes from "bytes" to "b"
System.arraycopy(bytes, index, b, off, lg);
// Update all counters
read += lg;
off += lg;
index += lg;
len -= lg;
if (index >= bytes.length) {
// It was the last index of the byte array so we remove it from the list
// and reset the current index
inputBuffer.remove(0);
index = 0;
}
} while (read < len && !inputBuffer.isEmpty());
return read;
}