1

我在标准输入上有一个非常大的已知字节数,并希望在读取感兴趣的部分之前丢弃大量(也已知)字节(换句话说,我想 fseek 向前一个大整数,但 fseek 不是'没有为管道定义)。实现这一点的最简单方法似乎是对 fgetc 的大量调用,第一种替代方法是使用单个调用 fread 并分配一个大的临时指针来存储结果。第一个非常慢,第二个无缘无故地使用了可能无限量的内存。进行多次较小的读取可以解决无限的内存使用问题,但会引入一个空闲参数(块大小),对于每台机器和操作系统组合,它可能具有不同的最快值。

是否有任何替代方案能够以简洁、高效的方式实现这一目标?假定为 POSIX。

4

1 回答 1

2

没有办法“跳过”管道上的数据——你必须阅读它。

如果它是一个非常大的块,您将需要使用一个中等大小的缓冲区(作为开销和内存使用之间的折衷),如下所示:

 size_t dataToRead = some_large_number;

 while(dataToRead)
 {
    char buffer[4096];
    size_t toread = min(sizeof(buffer), dataToRead);
    size_t nread = fread(buffer, 1, toread, stdin);
    dataToRead -= nread;
 }

大小 4096 是一个相当随意的选择——但它足够大,不会导致对输入的大量读取,并且足够小,不会使用大量的堆栈空间。您不太可能从更改此大小中获得/损失太多。

于 2013-09-21T20:54:23.207 回答