简体   繁体   English

读取不存在的文件

[英]reading a file that doesn't exist

I have got a small program that prints the contents of files using the system call - read. 我有一个小程序,使用系统调用打印文件的内容 - 读取。

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));

Now while running I give a file name that doesn't exist. 现在,在运行时,我给出了一个不存在的文件名。 It prints some kind of data mixed with environment variables and a segmentation fault at the end. 它打印出一些与环境变量混合的数据和最后的分段错误。

How is this possible? 这怎么可能? What is the program printing? 什么是程序打印?

Thanks, John 谢谢,约翰

It's printing rubbish because fd will invariably be set to -1 which is not a good thing to pass to read since it will, in turn do nothing other than return -1 as well. 它打印垃圾是因为fd总是被设置为-1,这对于传递read来说并不是一件好事,因为它会反过来除了返回-1之外什么都不做。 It will leave your buffer untouched meaning that it's holding whatever rubbish you had in there when you started. 它会让你的缓冲区不受影响,这意味着当你开始时它会保留你在那里的垃圾。

You could probably put the entire do loop inside something like: 您可以将整个do循环放在以下内容中:

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

read is returning -1 because fd is invalid, you store that in bytes_read which is of type size_t which is unsigned, so your loop prints (size_t)-1 chars, which is a very large number, much larger than the size of buffer. read返回-1因为fd无效,你将它存储在bytes_read中,它是size_t类型的无符号,所以你的循环打印(size_t)-1个字符,这是一个非常大的数字,远大于缓冲区的大小。 So, you're printing a big chunk of your address space and then getting a segfault when you eventually reach the end and access an invalid address. 因此,您打印了大部分地址空间,然后在最终到达终点并访问无效地址时获得段错误。

As others have mentioned (without answering your actual question), you should be checking the results of open for an error. 正如其他人所提到的(没有回答你的实际问题),你应该检查打开错误的结果。 eg, 例如,

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

A caveat: if you do another system call, or call any routine that might do a system call (eg, printf) before calling strerror, you must save errno and then pass the saved copy to strerror. 需要注意的是:如果您在调用strerror之前执行另一个系统调用或调用任何可能进行系统调用的例程(例如printf),则必须保存errno,然后将保存的副本传递给strerror。

Another note about your program: 关于你的计划的另一个说明

while(bytes_read == sizeof(buffer))

This is not a good test, because read can return less than the amount you ask for. 这不是一个好的测试,因为读取的回报可能低于您要求的数量。 Your loop should continue until read returns <= 0. 您的循环应该继续,直到读取返回<= 0。

You should probably check that the file descriptor returned by open is valid before using it. 在使用之前,您应该检查open返回的文件描述符是否有效。 As per these docs , you should get a non-negative response for a valid file. 根据这些文档 ,您应该获得有效文件的非否定响应。 Reading from an invalid descriptor is likely the source of your problem. 从无效的描述符中读取可能是您的问题的根源。

Upon successful completion, open function shall open the file and return a non-negative integer representing the file descriptor. 成功完成后,open函数将打开文件并返回表示文件描述符的非负整数。 Otherwise, -1 shall be returned and errno set to indicate the error. 否则,返回-1并设置errno以指示错误。 So please check fd before entering the loop to perform the read. 所以请在进入循环之前检查fd以执行读取。

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

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