所以我在C语言中打开和关闭文件做了一些非常基础的工作。
我注意到当我运行以下代码时,我得到了奇怪的输出:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdlib.h>
main()
{
// first get rid of existing input.txt, which is guaranteed to exist
pid_t pid = fork();
//child code
if (pid == 0) {
char* command[4] = {"rm", "-f", "input.txt", NULL};
execvp(command[0], command);
}
// parent code
else {
int status;
wait(&status);
}
// initialize file descriptor
int fd;
// open input.txt with given flags
int flags = O_RDWR | O_CREAT;
fd = open("input.txt", flags);
// debug
fprintf(stderr,"The openval is %d\n", fd);
// now close it
int closeval = close(fd);
// debug
fprintf(stderr,"The closeval is %d\n", closeval);
// try to re-open-it with different flags
flags = O_RDONLY;
fd = open("input.txt", flags);
// debug
fprintf(stderr,"The new openval is %d\n", fd);
}
输出:
The openval is 3
The closeval is 0
The new openval is -1
第一和第二行输出对我有意义。我的大问题是,为什么我不能再次打开文件?
我一开始认为可能是因为我要求使用以下标志第二次打开它:
flags = O_RDWR;
我的想法是,请求写入权限会以某种方式被前一次打开弄乱(尽管不应该是这种情况,因为我关闭它,对吗?)。所以我尝试了上面的版本,只要求阅读文件,但仍然没有运气。
打开,关闭,然后重新打开这样的文件只是不是一个选项?
编辑:这是错误的测试代码和输出
if(fd == -1) {
char* error = strerror(errno);
fprintf(stderr,"%s\n",error);
}
输出:
Permission denied
答案 0 :(得分:1)
首先,man page link。
当你这样做时
int flags = O_RDWR | O_CREAT;
fd = open("input.txt", flags);
您缺少open
的第3个参数,文件创建模式。 必需 O_CREAT
。没有它,函数将采用参数的任何“随机”值,并且可以使用某种未定义模式创建文件(或者实际上任何UB都可以在理论上发生)。
修复第一步,为程序定义行为。
此外,尽管对上述错误可能没什么帮助,但当C库函数返回错误时(通常为整数为-1,指针为NULL
),它也会设置全局errno
。使用perror
或strerror(errno)
获取人为错误消息。始终在检测到错误时记录错误,它不仅可以帮助解决错误,还可以解决代码错误问题,还可以解决文件权限等外部问题,即使在程序“准备就绪”后也可能发生。
答案 1 :(得分:1)
这是文件创建模式的问题。创建的文件的默认权限不允许您重新打开它。只需在open()中添加第三个参数即可。 所以,你的解决方案将是:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <stdlib.h> main() { // first get rid of existing input.txt, which is guaranteed to exist pid_t pid = fork(); //child code if (pid == 0) { char* command[4] = {"rm", "-f", "input.txt", NULL}; execvp(command[0], command); } // parent code else { int status; wait(&status); } // initialize file descriptor int fd; // open input.txt with given flags int flags = O_RDWR | O_CREAT; /*ADD FILE PERMISSION HERE AS A THIRD PARAMETER. */ fd = open("input.txt", flags, 0777); // debug fprintf(stderr,"The openval is %d\n", fd); // now close it int closeval = close(fd); // debug fprintf(stderr,"The closeval is %d\n", closeval); // try to re-open-it with different flags flags = O_RDONLY; fd = open("input.txt", flags); // debug fprintf(stderr,"The new openval is %d\n", fd); }