为什么Files.newInputStream(path)不支持FIFO上的可用方法?

时间:2017-02-18 18:20:10

标签: java linux file-io inputstream

参加这个简单的测试课程:

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个字节。

0 个答案:

没有答案