繁体   English   中英

这个lseek,fseek,read,fread之间的区别是什么?

[英]Whats the difference between this lseek, fseek, read, fread?

我在调用这些函数:

unsigned blah[5];
lseek(0, 100, SEEK_CUR);
read(0, blah, sizeof(blah));

FILE *fr;
fr = fopen(arg[1], "r");
unsigned blah[5];
fseek(fr, 100, SEEK_CUR);
fread(blah, 1, sizeof(blah), fr);

我运行第一个代码运行此命令:

cat TEXTFILE | ./a.out

我运行第二个代码运行此命令:

./a.out TEXTFILE

但是,我得到了不同的结果。 虽然第一个搜索正确,所以它读取正确的文本,第二个不是。 我想使用第二种格式,那么我做错了什么?

添加一个open(filename,O_RDONLY); 打电话给第一个例子,对我来说都很好。 我怀疑你的问题是因为调用lseek(0, 100, SEEK_CUR); ,这是要求标准输入的寻求。 你不能总是寻求标准 - 如果你有:

 cat file | ./my_program 

然后标准输入是一个fifo,你不能寻求。 如果我在我的系统上执行此操作,则返回-1 ,查找失败,错误为“非法搜索”。 这可能是您遇到的问题,您可能没有注意到,因为您没有在示例中检查搜索调用的返回值。

请注意,如果您有:

 ./my_program < file

然后标准输入是一个文件,你可以寻求。 在我的系统上,搜索返回100 ,输出正确。


这是一个程序,您可以用来说明返回值:

int main(void){ 

  int fd = 0;
  char blah[5];
  printf("Seek moved to this position: %d\n",lseek(fd, 100, SEEK_CUR));
  perror("Seek said");
  printf("Then read read %d bytes\n",read(fd, blah, sizeof(blah)));
  printf("The bytes read were '%c%c%c%c%c'\n",blah[0],blah[1],blah[2],blah[3],blah[4]); 
}                       

这是两个执行:

 $ ./a.out < text
 Seek moved to this position: 100
 Seek said: Success
 Then read read 5 bytes
 The bytes read were '+++.-'

(那些是该文件中位置100的正确字节)

$ cat text | ./a.out 
Seek moved to this position: -1
Seek said: Illegal seek
Then read read 5 bytes
The bytes read were '# def'

(那些字节是文件的前5个字节)


我还注意到标准输入版本是你说的正常工作。 如果您在使用FILE *版本时遇到问题,我怀疑fopen()调用失败,因此请确保检查fopen()的返回值。 当然,你总是可以这样做:

FILE *fr = stdin;  

因此,您正在阅读标准版。 然而,由于您不能总是寻求标准版,我建议您在计划寻找时始终打开文件。

请注意,您无法在所有可以打开文件的设备上寻找(尽管在大多数系统上都没有问题),因此您应该始终检查seek()的结果以确保它成功。

SEEK_CUR从当前位置开始。 这就是为什么当你在文件的开头时,你的第一次搜索工作。 要始终从头开始寻求,您需要使用SEEK_SET而不是SEEK_CUR。

0   SEEK_SET    The beginning of the file
1   SEEK_CUR    The current position
2   SEEK_END    The end of the file

我不是100%肯定差异,但它似乎与管道vs stdio /文件有关。 为了说明这一点,我做了这两个不同的测试程序:

exam.c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
        char blah[5] = {0,};

        /* we're using stdin instead of pipeline  :( */
        lseek(0, 100, SEEK_CUR);
        read(0, blah, sizeof(blah));

        printf("%c%c%c%c%c\n", blah[0], blah[1], blah[2], blah[3], blah[4]);

        return 0;
}

test.c的

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

void testA(const char *s)
{
        int f = -1;
        char blah[5] = {0,};

        f = open(s, O_RDONLY);

        if (-1 < f)
        {
                lseek(f, 100, SEEK_CUR);
                read(f, blah, sizeof(blah));
        }

        printf("%c%c%c%c%c\n", blah[0], blah[1], blah[2], blah[3], blah[4]);
}

void testB(const char *s)
{
        FILE *fp = NULL;
        char blah[5] = {0,};

        fp = fopen(s, "r");

        if (fp)
        {
                fseek(fp, 100, SEEK_CUR);
                fread(blah, 1, sizeof(blah), fp);
        }

        printf("%c%c%c%c%c\n", blah[0], blah[1], blah[2], blah[3], blah[4]);
}

int main(int argc, char **argv)
{
        testA(argv[1]);
        testB(argv[1]);

        return 0;
}

然后我创建了一些测试数据。

data.txt中

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

当我执行cat ./data.txt | ./exam cat ./data.txt | ./exam ,输出是

01234

当我执行./test ./data.txt ,我得到了

bcdef
bcdef

仅供参考,结果保持不变,即使我们更换SEEK_CURSEEK_SET

但是,。/ ./exam <./data.txt导致

bcdef

这是合法的。

我知道这不是一个可接受的答案,如果不知道为什么'0'会显示数据文件的内容,但我希望它有所帮助。

暂无
暂无

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

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