2

我正在制作一个简单的套接字应用程序,它使用 TCP 与我的服务器连接。我有时需要读取 2 个字节的值,所以这一切都是这样的:

public byte[] read(int bytes)
{
    byte b[] = new byte[bytes];
    try {
        in.read(b); //in is InputStream from properly connected Socket.getInputStream()
    return b;
    } catch (IOException e) {
        return null;
    }
}

此函数应接收给定的字节数并将其以数组形式返回。问题是,有时它会在剩余可用之前读取一个字节并返回奇怪的数据。

byte a[]=read(2); //Program is blocked here untill some bytes arrive...
System.out.prntln(a[0]); //always correct
System.out.prntln(a[1]); //unprintable character (probably 0 or -1)

我的快速解决方法是添加 while 循环检查是否有足够的数据可供读取:

public byte[] read(int bytes)
{
    byte b[] = new byte[bytes];
    try {
        while (in.available()<bytes); //It does the thing
        in.read(b);
    return b;
    } catch (IOException e) {
        return null;
    }
}

但是那个循环正在使用 100% 的处理器功率(实际上是一个内核),这非常烦人。有什么方法可以重写该函数(参数和返回值必须完全相同)以使其正常工作?

提前谢谢:)

4

2 回答 2

7

是的。你的快速修复是个坏主意。事实上,任何使用的代码available都可能被破坏。

以下是我的做法:

public byte[] read(int bytes) throws IOException {
    byte b[] = new byte[bytes];
    int pos = 0;
    while (pos < b.length) {
       int nosRead = in.read(b, pos, b.length - pos);
       if (nosRead == -1) {
          return null;  // Not the best idea ... see below.
       } else {
          pos += nosRead;
       }
    }
    return b;
}

无需使用available(). 没有必要睡觉。您只需利用read仅在读取至少一个字节或您符合“流结束”时才会返回的事实。


null请注意,如果您的read方法失败,我也不认为返回 a 是正确的。最好抛出异常......或让IOException来自in.read()调用的传播。

这也适用于我的重写......我不想在这方面改变你的代码的行为。

于 2013-06-23T02:52:34.990 回答
2

扔掉它并使用 DataInputStream.readFully()。

于 2013-06-23T03:41:34.760 回答