Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.io.InputStream及其子类型中数据的健壮跳过_Java_Stream_Inputstream_Java Io_Skip - Fatal编程技术网

java.io.InputStream及其子类型中数据的健壮跳过

java.io.InputStream及其子类型中数据的健壮跳过,java,stream,inputstream,java-io,skip,Java,Stream,Inputstream,Java Io,Skip,我正在处理一个二进制流,需要高效地跳过一系列我不感兴趣的数据,跳转到一些将要处理的数据 InputStream.skip(long)在保证方面没有多大作用: 跳过并丢弃此输入流中的n字节数据。由于各种原因,skip方法可能会跳过一些较小的字节数,可能是0。这可能由多种情况中的任何一种导致;在跳过n个字节之前到达文件末尾只是一种可能性。返回跳过的实际字节数 我需要知道发生了两件事中的一件: 溪流结束了 字节被跳过 很简单。然而,本描述中提供的宽大性意味着,例如,BufferedInputStrea

我正在处理一个二进制流,需要高效地跳过一系列我不感兴趣的数据,跳转到一些将要处理的数据

InputStream.skip(long)
在保证方面没有多大作用:

跳过并丢弃此输入流中的n字节数据。由于各种原因,skip方法可能会跳过一些较小的字节数,可能是0。这可能由多种情况中的任何一种导致;在跳过n个字节之前到达文件末尾只是一种可能性。返回跳过的实际字节数

我需要知道发生了两件事中的一件:

  • 溪流结束了
  • 字节被跳过
  • 很简单。然而,本描述中提供的宽大性意味着,例如,
    BufferedInputStream
    可以跳过几个字节并返回。当然,它告诉我,它只是跳过了这几个,但不清楚为什么


    因此,我的问题是:您是否可以使用
    InputStream.skip(long)
    ,以便您知道流何时结束或跳过何时成功完成?

    这似乎适用于跳过
    n
    字节:

    long skippedTotal = 0;
    while (skippedTotal != n) {
        long skipped = _stream.skip(n - skippedTotal);
        assert(skipped >= 0);
        skippedTotal += skipped;
        if (skipped == 0)
            break;
    }
    boolean skippedEnough = skippedTotal == n;
    

    但是,不清楚它是否适用于可以传递到我的库的
    InputStream
    的所有实现。我想知道是否应该实现我自己的缓冲跳过方法。

    我认为我们无法获得真正健壮的实现,因为
    skip()
    方法契约非常奇怪。一方面,
    EOF
    的行为没有得到很好的定义。如果我想跳过8个字节,并且
    是.skip(8)
    返回
    0
    ,那么决定是否重试并不容易,如果某些实现选择在
    EOF
    处返回
    0
    ,则存在无限循环的危险。而且
    available()
    也不可信

    因此,我提议如下:

    /**
     * Skips n bytes. Best effort.
     */
    public static void myskip(InputStream is, long n) throws IOException {
        while(n > 0) {
            long n1 = is.skip(n);
            if( n1 > 0 ) {
                n -= n1;
            } else if( n1 == 0 ) { // should we retry? lets read one byte
                if( is.read() == -1)  // EOF
                    break;
                else 
                    n--;
            } else // negative? this should never happen but...
            throw new IOException("skip() returned a negative value. This should never happen");
        }
    }
    

    我们不应该返回一个值来通知“真正跳过”的字节数吗?还是一个布尔值来通知已达到EOF?我们不能以稳健的方式做到这一点。例如,如果我们调用对象的
    skip(8)
    ,即使我们处于
    EOF
    ,或者文件只有2个字节。但是,从某种意义上说,该方法是健壮的,它做了我们想要做的事情:跳过
    n
    字节(如果可能的话),让我继续处理它(如果我下一次读取返回
    -1
    ,我将知道
    EOF
    已达到)。

    我对此问题晚了6年

    原则上,跳过(int n)之间没有区别 和readFully(int n)。在这种情况下,你不感兴趣 在字节中

    对于实时流,即tcp套接字或 附加到,skip(n)可以阻止(等待)它 «跳过»0字节,具体取决于用户等待的首选项

    返回EOF或-1表示任务结束 流,并应将其返回给最终用户 因为在这一点之后不会有其他事情发生

    为了有效地跳过文件中的字节,我需要 探索随机io、通道。但这种优化是不可能的
    在任何输入流中都是通用的。

    我不认为任何
    InputStream
    实现都会偏离约定,即返回实际跳过的字节数。@EJP,我同意。我关心的是,是否由于某种IO伪影(缓冲等)或流结束而跳过了较少的字节。如果流尚未结束,
    skip
    仍可能返回零。在什么情况下,您知道跳过不起作用是因为没有更多的字节,而不是它在网络上等待字节?我看到的问题是,我们无法确定在
    skipped==0
    时不应该重试。此外,布尔值
    skippedOutgh
    不可信。看我的回答。你的回答具体地详述了我所关心的事情。我发布的代码在实践中似乎有效,但我不确定它是否适用于
    InputStream
    的所有实现。您的扩展看起来很有趣,我将很快在中试用。目前,我的API尝试报告跳过是否成功,因此如果无法保证,我可能需要修改客户端代码。非常感谢。您可以修复
    FileInputStream.skip()
    问题:使用
    while
    循环
    n-1
    字节;然后,在循环之后,调用.read()中的
    一次。如果它返回
    -1
    ,则跳过将达到EOF,否则跳过成功。另外,不要忘记在顶部检查
    n==0
    。@KannanGoundan一个有趣的建议。当然,一个缺点是它至少需要从流中读取两次数据(一个
    跳过
    加上一个
    读取
    ),这在某些情况下可能会影响性能。这看起来或多或少与Guava的
    ByTestStreams.skipFully
    方法相同,因此它可能是正确的。