参加这个简单的测试课程:
public class InputStreamTest {
public static void main(String[] args) throws IOException {
byte[] buf = new byte[100];
Path path = Paths.get(args[0]);
System.out.println("File " + path);
try (InputStream is = new BufferedInputStream(new FileInputStream(path.toFile()))) {
// try (InputStream is = new BufferedInputStream(Files.newInputStream(path))) {
System.out.println("Available: " + is.available());
System.out.print("First 100 bytes: '");
is.read(buf);
System.out.write(buf);
System.out.println("'");
}
}
}
这会在命令行上使用文件名/路径,只需在相应的available()
上打印出InputStream
的结果,然后从 1 打印出前100个字节的结果流。
它工作正常,即使你传递了重定向的命令输出(它在内部将创建一个FIFO并将其作为文件参数传递)。例如,将其运行为:
java InputStreamTest <(echo -n "ABC")
...产生以下输出:
File /dev/fd/63:
Available: 3
First 100 bytes: 'ABC'
到目前为止看起来不错。现在,取消注释使用new-and-recommended-Java-7-ish Files.newInputStream(path)
创建InputStream
的行并注释我们使用oldschool FileInputStream
类的前一行。现在它失败了:
File /dev/fd/63
Exception in thread "main" java.io.IOException: Illegal seek
at sun.nio.ch.FileChannelImpl.position0(Native Method)
at sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:264)
at sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:116)
at java.io.BufferedInputStream.available(BufferedInputStream.java:410)
at net.tdowns.compression.InputStreamTest.main(InputStreamTest.java:20)
显然,流上的available()
方法失败了。现在你可能只是说“嘿,不要打{{1}}它几乎没用”。不幸的是,像available()
这样的核心类使用它!如果您注释掉对BufferedInputStream
的直接通话,则此仍然会失败:
available()
所以你处在一个相当困难的地方 - 如果你使用File /dev/fd/63
First 100 bytes: 'Exception in thread "main" java.io.IOException: Illegal seek
at sun.nio.ch.FileChannelImpl.position0(Native Method)
at sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:264)
at sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:116)
at java.io.BufferedInputStream.read(BufferedInputStream.java:353)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at net.tdowns.compression.InputStreamTest.main(InputStreamTest.java:22)
,Files.newInputStream(path)
调用可能会失败,你不能真正避免使用这个调用,因为其他JDK流类本身就喜欢叫它。
任何出路?
1 我说最多因为available()
方法当然可能返回少于请求的字节数,即使有更多可用字节。在实践中,它不会对文件和fifos这样做至少得到几个K,所以如果100个字节可用,通常打印出100个字节。