Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解文件截断_C_Linux_File_Unix_Truncate - Fatal编程技术网

C 理解文件截断

C 理解文件截断,c,linux,file,unix,truncate,C,Linux,File,Unix,Truncate,引用第13.6节(第505页): 我们需要截断该文件,因为 守护进程的进程ID可能比我们的大,并且 字符串长度。例如,如果守护进程的前一个实例 是进程ID 12345,新实例是进程ID 9999 将进程ID写入文件,我们将在 文件截断文件会阻止来自上一个守护进程的数据 看起来好像它适用于当前守护进程 就这一职能发表了以下评论: already_running(void) { int fd; char buf[16]; fd = open(LOCKFILE, O_RDWR|

引用第13.6节(第505页):

我们需要截断该文件,因为 守护进程的进程ID可能比我们的大,并且 字符串长度。例如,如果守护进程的前一个实例 是进程ID 12345,新实例是进程ID 9999 将进程ID写入文件,我们将在 文件截断文件会阻止来自上一个守护进程的数据 看起来好像它适用于当前守护进程

就这一职能发表了以下评论:

already_running(void)
{
    int fd;
    char buf[16];
    fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
    if (fd < 0) {
        syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
        exit(1);
    }
    if (lockfile(fd) < 0) {
        if (errno == EACCES || errno == EAGAIN) {
            close(fd);
            return(1);
        }
        syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno));
        exit(1);
    }
    ftruncate(fd, 0);
    sprintf(buf, "%ld", (long)getpid()); 
    write(fd, buf, strlen(buf)+1);
    return 0;
}
已在运行(无效)
{
int-fd;
char-buf[16];
fd=打开(锁定文件,O|U RDWR | O|U创建,锁定模式);
如果(fd<0){
syslog(LOG_ERR,“无法打开%s:%s”,锁文件,strerror(errno));
出口(1);
}
if(锁文件(fd)<0){
if(errno==EACCES | | errno==EAGAIN){
关闭(fd);
申报表(1);
}
syslog(LOG_ERR,“无法锁定%s:%s”,锁文件,strerror(errno));
出口(1);
}
ftruncate(fd,0);
sprintf(buf,“%ld”,(long)getpid();
写入(fd、buf、strlen(buf)+1);
返回0;
}
我不明白这种行为是如何可能的,以及文件截断是如何防止这种行为发生的。有人能解释一下吗


谢谢你的回答

在上面的示例中,文件最初为5字节长。当您打开它进行写入,并在不截断的情况下向其写入字符串“9999”时,它只会覆盖前4个字节,并保留第5个字节。因此,该文件将读取“99995”。截断将文件长度设置为0,有效地删除以前的内容。

Hellmar已经为您的问题提供了答案——但为了缩短代码(谁不喜欢code golf?),您可以简化开放调用:

already_running(void)
{
    int fd;
    char buf[16];
    fd = open(LOCKFILE, O_RDWR|O_CREAT|O_TRUNC, LOCKMODE);
    ...
向标志中添加O_TRUNC将导致文件被截断

如果文件已存在且为常规文件且处于打开模式 允许写入(即是O_RDWR或O_WRONLY),它将被截断为 长度为0


调用
ftruncate
只会在覆盖文件之前将文件长度重置为0,这样就不会有任何以前的内容出现在文件的新版本中(如果以前的内容大于新内容,可能会发生这种情况)。是,但是,只有当您要覆盖现有文件,并且新内容可能比旧内容短时,才需要这样做。否则它是多余的(但无害的)。