【发布时间】:2010-10-20 09:52:00
【问题描述】:
我正在寻找演示如何创建能够理解 二进制 数据的过滤器的示例代码。非常感谢您提供示例链接。
【问题讨论】:
标签: java sockets network-programming filter stream
我正在寻找演示如何创建能够理解 二进制 数据的过滤器的示例代码。非常感谢您提供示例链接。
【问题讨论】:
标签: java sockets network-programming filter stream
如果您指的是 FilterInputStream/FilterOutputStream 的示例,那么您只需看看 JDK。为了争论,我将讨论输入流变体,但同样适用于输出流。
以 InflaterInputStream 为例。查看数组的 read() 方法,并注意在某些时候 if 调用了 fill(),它又从底层输入流中读取。然后,围绕该方法,它调用 Inflater 以实际将其从底层流中提取的“原始”字节缓冲区转换为写入调用方数组的实际字节。
需要考虑的一点是,FilterInputStream 有点浪费空间。只要您可以定义您的 InputStream 以获取另一个基础 InputStream,并且在您从该基础流中读取的所有读取方法中(请记住,理论上您只需要定义字节 read() 方法),然后特别是让你的类扩展 FilterInputStream 并不能真正为你买太多。例如,下面是输入流的部分代码,它限制了它允许调用者读取的底层流中的字节数(实际上,我们可以将一个流“切分”成几个子流,这很有用例如,从存档文件中读取时):
class LimitedInputStream extends InputStream {
private InputStream in;
private long bytesLeft;
LimitedInputStream(InputStream in, long maxBytes) {
this.in = in;
this.bytesLeft = maxBytes;
}
@Override
public int read() throws IOException {
if (bytesLeft <= 0)
return -1;
int b = in.read();
bytesLeft--;
return b;
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if (bytesLeft <= 0)
return -1;
len = (int) Math.min((long) len, bytesLeft);
int n = in.read(b, off, len);
if (n > 0)
bytesLeft -= n;
return n;
}
// ... missed off boring implementations of skip(), available()..
}
在这种情况下,在我的应用程序中,将此类声明为 FilterInputStream 确实对我没有任何好处——实际上,这是在想要调用 in.read() 或 super.read() 来获取底层数据之间的选择...!
【讨论】:
举个很好的例子,我建议看一下java.io.DataInputStream 的源代码。此类向您展示了一种从“二进制”数据中解码原始类型和字符串的方法,从中可以生成更复杂的结构。
当然,其他应用程序可能会选择使用其他编码。例如,ASN.1 "distinguished encoding rules" 用于公钥基础设施应用程序。 Lucene provides good documentation 的文件格式,专为紧凑而设计。
如果您有 Sun JDK,请在其顶层目录中查找“src.zip”。如果您告诉他们在哪里可以找到这个文件,大多数 IDE 会向您显示核心 Java 类的源代码。
【讨论】: