简体   繁体   English

如何从流中读取x个字节?

[英]How do I read x bytes from a stream?

I want to read exactly n bytes from a Socket at a time. 我想一次从Socket读取n个字节。 How can I achieve that? 我怎样才能做到这一点?

DataInputStream.readFully()

当然它可以阻止任意长时间......

You can create a helper method to completely fill a buffer. 您可以创建一个辅助方法来完全填充缓冲区。 Something like this: 像这样的东西:

public int fillBufferCompletely(InputStream is, byte[] bytes) throws IOException {
    int size = bytes.length;
    int offset = 0;
    while (offset < size) {
        int read = is.read(bytes, offset, size - offset);
        if (read == -1) {
            if ( offset == 0 ) {
                return -1;
            } else {
                return offset;
            }
        } else {
            offset += read;
        }
    }

    return size;
}

Then you just need to pass in a buffer of size x . 然后你只需要传入一个大小为x的缓冲区。

Edit 编辑

Michael posted a link to a function which does essentially the same thing. 迈克尔发布了一个功能的链接,该功能基本上是相同的。 The only difference with mine is that it does have the ability to return less than the buffer length, but only on the condition of an end-of-stream. 与我的唯一区别是它确实能够返回小于缓冲区长度,但仅限于流末尾的条件。 DataInputStream.readFully would throw a runtime exception in this scenario. DataInputStream.readFully会在此方案中引发运行时异常。

So I'll leave my answer up in case an example of that behaviour is useful. 所以我会留下我的答案以防万一这种行为的例子很有用。

DataInputStream.readFully() throws an exception on EOF, as Mark Peters points out. MarkInputStream.readFully()在EOF上引发异常,正如Mark Peters指出的那样。 But there are two other methods who don't: Commons IO's IOUtils.read() and Guavas ByteStreams.read() . 但还有另外两种方法:Commons IO的IOUtils.read()和Guavas ByteStreams.read () These both try to read up to N bytes, stopping only at EOF, and return how many they actually read. 这两个都尝试读取最多N个字节,仅在EOF停止,并返回它们实际读取的数量。

This is impossible. 这是不可能的。 The underlying platforms cannot guarantee this, so neither can Java. 底层平台无法保证这一点,因此Java也无法保证。 You can attempt to read n bytes, but you always have to be prepared that you get less than what was requested. 您可以尝试读取n个字节,但是您必须准备好比请求的更少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM