在写入文件之前检查文件是否存在,然后要求用 POSIX 在 C 中覆盖

标签 c file-io error-handling posix

好的,我有一项家庭作业是使用 POSIX API 在 C 中编写一个文件,该 API 要求读取一个文件名,写入一个文件名,然后将一个文件复制到另一个。我已经做到了,效果很好!我正在尝试进行一些错误检查,我想检查要写入的文件是否已经存在,如果存在,则询问用户是否希望覆盖。问题是它总是声明该文件存在,即使它不存在。该程序的其余部分工作正常。我在这里读了很多书,在 POSIX 上找到了很多有用的东西,但是找不到这类问题可以引用。下面是我的代码:

#include <fcntl.h>   // POSIX: give access to open
#include <unistd.h>  // POSIX: gives access to read, write, close
#include <stdio.h>   // POSIX: gives access to BUFSIZ

int main() {

int source = -1;
int target;
char sourcefile[50];
char targetfile[50];
char buff[BUFSIZ];
char ow[3];
size_t size;

printf("Please enter the name of the file you wish to read: ");
scanf( "%s", sourcefile );
printf( "\n" );
printf("Please enter the name of the file you wish to write to: ");
scanf( "%s", targetfile );
printf( "\n" );

source = open( sourcefile, O_RDONLY, 0);
//Test for existence of input file
if( source == -1 )
{
    perror( "Cannot find file" );
    return 1;
}
target = open( targetfile, O_WRONLY, 0644 );
//Test for existence of output file
if( target == 0 )
{
    perror( "File already exists" );
    printf( "Do you wish to overwrite? (yes or no): " );
    scanf( "%s", ow );

    if( strcmp( ow, "yes" ) == 0 )
    {
        target = open( targetfile, O_WRONLY | O_CREAT, 0644);   
    }else
    {
        printf( "Program Terminated!\n" );
        return 1;   
    }   
}else if( target == -1 )
{
    target = open( targetfile, O_WRONLY | O_CREAT, 0644);
}

while ((size = read(source, buff, BUFSIZ)) > 0) 
{
    write(target, buff, size);
}

close(source);
close(target);

return 0;
}

最佳答案

您可以使用 open(2)O_EXCL 来创建所谓的新文件。如果文件已经存在,这将失败;在那种情况下致命中止。否则,您可以将所需的文件内容写入其中。

如果你想成为原子的,你可以将文件内容写入一个临时文件(使用tmpfile),然后用rename(2)原子地替换创建的文件.这样,新文件要么是空的,要么是完整的副本。


另一种方法(由@R 建议)是不打扰打开目标文件,复制到临时文件,然后使用link(2) 而不是rename 尝试将新文件放入其目标位置。如果目的地已经存在,这将失败。这可能有(有争议的)好处,如果其他人同时创建目标文件并且没有像我们一样小心,那么在这种情况下你会更温和一些。 (但是,如果其他人想要不小心踩踏您的文件系统,您能做的就只有这么多了。)

关于在写入文件之前检查文件是否存在,然后要求用 POSIX 在 C 中覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14573797/

相关文章:

c# - 如何将二进制文件转换为字节数组?

python - 如何将字符串列表写入文件并添加换行符?

java - 系统找不到指定的文件

java - 调用方法时出现错误

c# - 在 .aspx 和 .ascx 页面中捕获异常

python - Tweepy 在 search_recent_tweets <> 上出现 401 错误,但在 create_tweet 时没有出现 401 错误?

python - 在Python中读取C数组

c - 当我输入字符作为输入时,CMD将被卡住并且不再响应

c++ - 使用 qsort 对 2D 数组进行排序 - 正确的类型转换

c - 函数不能返回值