简体   繁体   English

Java I / O流过滤器的示例

[英]Examples of Java I/O Stream Filters

I am looking for example code that demonstrates how to create a filter that understands binary data. 我正在寻找示例代码,这些代码演示了如何创建可以理解二进制数据的过滤器。 Links to examples are greatly appreciated. 链接到示例非常感谢。

If you mean examples of FilterInputStream/FilterOutputStream, then you need look no further than the JDK. 如果您是说FilterInputStream / FilterOutputStream的示例,那么您只需要看一下JDK。 I'll talk about the input stream variant for the sake of argument, but the same applies to output streams. 为了论证,我将讨论输入流的变体,但对输出流也是如此。

Take a look at InflaterInputStream, for example. 例如,看看InflaterInputStream。 Look at the arry read() method, and notice how at some point if calls fill(), which in turn reads from the underlying input stream. 查看arry read()方法,并注意调用fill()的方式,该方法又从底层输入流中读取。 Then, around that method, it calls into the Inflater to actually turn the buffer of "raw" bytes that it pulled from the underlying stream into the actual bytes that are written to the caller's array. 然后,围绕该方法,它调用Inflater,实际上将其从基础流中拉出的“原始”字节的缓冲区转换为写入调用方数组的实际字节。

One thing to consider is that FilterInputStream is a little bit of a waste of space. 要考虑的一件事是FilterInputStream有点浪费空间。 So long as you can define your InputStream to take another underlying InputStream, and in all the read method(s) you read from that underlying stream (bearing in mind that in theory you only need to define the byte read() method), then specifically making your class extend FilterInputStream doesn't really buy you very much. 只要您可以定义InputStream来接受另一个基础InputStream,并且在所有从该基础流中读取的read方法中(请记住,理论上您只需要定义字节read()方法),然后专门使您的类扩展FilterInputStream并不会真正给您带来多少好处。 For example, here's part of the code for an input stream that limits the number of bytes from the underlying stream that it allows the caller to read (in effect, we can "chop up" a stream into several sub-streams, which is useful when reading from archive files, for example): 例如,这是输入流的一部分代码,它限制了允许调用者读取的基础流中的字节数(实际上,我们可以将流“分成”几个子流,这很有用)例如,从存档文件读取时:

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()..
}

In this case in my application, it really buys me nothing to declare this class as a FilterInputStream-- in effect, it's a choice between wanting to call in.read() or super.read() to get the underlying data...! 在这种情况下,在我的应用程序中,我真的没有买什么东西就可以将此类声明为FilterInputStream-实际上,可以在想要调用in.read()或super.read()之间进行选择以获取基础数据... !

For a good example, I'd suggest taking a look at the source code for java.io.DataInputStream . 举个好例子,我建议看一下java.io.DataInputStream的源代码。 This class shows you one way to decode primitive types and character strings from "binary" data, from which more complex structures can be produced. 此类向您展示一种从“二进制”数据中解码原始类型和字符串的方法,从中可以产生更复杂的结构。

Of course, other applications might choose to use other encodings. 当然,其他应用程序可能会选择使用其他编码。 For example, the ASN.1 "distinguished encoding rules" are used for Public Key Infrastructure applications. 例如, ASN.1“专有编码规则”用于公钥基础结构应用程序。 Lucene provides good documentation for its file format, which is designed for compactness. Lucene提供了很好的文档格式,这是为了紧凑起见。

If you have the Sun JDK, look in its top directory for "src.zip". 如果您有Sun JDK,请在其顶层目录中查找“ src.zip”。 Most IDEs will show you the source code for the core Java classes if you tell them where to find this file. 如果您告诉核心Java类在哪里可以找到该文件,则大多数IDE会向您显示它们的源代码。

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

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