繁体   English   中英

读取不存在的文件

[英]reading a file that doesn't exist

我有一个小程序,使用系统调用打印文件的内容 - 读取。

unsigned char buffer[8];
size_t offset=0;
size_t bytes_read;

int i;

int fd = open(argv[1], O_RDONLY);

do{
    bytes_read = read(fd, buffer, sizeof(buffer));
    printf("0x%06x : ", offset);

    for(i=0; i<bytes_read; ++i)
    {
        printf("%c ", buffer[i]);
    }
    printf("\n");
    offset = offset + bytes_read;
}while(bytes_read == sizeof(buffer));

现在,在运行时,我给出了一个不存在的文件名。 它打印出一些与环境变量混合的数据和最后的分段错误。

这怎么可能? 什么是程序打印?

谢谢,约翰

它打印垃圾是因为fd总是被设置为-1,这对于传递read来说并不是一件好事,因为它会反过来除了返回-1之外什么都不做。 它会让你的缓冲区不受影响,这意味着当你开始时它会保留你在那里的垃圾。

您可以将整个do循环放在以下内容中:

if (fd == -1) {
    printf ("error here");
} else {
    // do loop here
}

read返回-1因为fd无效,你将它存储在bytes_read中,它是size_t类型的无符号,所以你的循环打印(size_t)-1个字符,这是一个非常大的数字,远大于缓冲区的大小。 因此,您打印了大部分地址空间,然后在最终到达终点并访问无效地址时获得段错误。

正如其他人所提到的(没有回答你的实际问题),你应该检查打开错误的结果。 例如,

int fd = open(argv[1], O_RDONLY);
if( fd < 0 ){
    fprintf(stderr, "error opening %s: %s\n", argv[1], strerror(errno));
    exit(1);
}

需要注意的是:如果您在调用strerror之前执行另一个系统调用或调用任何可能进行系统调用的例程(例如printf),则必须保存errno,然后将保存的副本传递给strerror。

关于你的计划的另一个说明

while(bytes_read == sizeof(buffer))

这不是一个好的测试,因为读取的回报可能低于您要求的数量。 您的循环应该继续,直到读取返回<= 0。

在使用之前,您应该检查open返回的文件描述符是否有效。 根据这些文档 ,您应该获得有效文件的非否定响应。 从无效的描述符中读取可能是您的问题的根源。

成功完成后,open函数将打开文件并返回表示文件描述符的非负整数。 否则,返回-1并设置errno以指示错误。 所以请在进入循环之前检查fd以执行读取。

暂无
暂无

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

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