博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux C ftruncate 函数清空文件注意事项(要使用 lseek 重置偏移量)
阅读量:4159 次
发布时间:2019-05-26

本文共 1773 字,大约阅读时间需要 5 分钟。

之前有个要把打开的文件清空,然后重新写入的需求,但是使用 ftruncate(fd, 0)后,并没有达到效果,反而文件头部有了'\0',长度比预想的大了。究其原因是没有使用 lseek 重置文件偏移量,是我太天真了,以为清空文件就会从头开始写入。

------------------------------------- 我是解释分割线 --------------------------------------

首先 man ftruncate 看下帮助手册

NAME

       truncate, ftruncate - truncate a file to a specified length

SYNOPSIS

       int truncate(const char *path, off_t length);
       int ftruncate(int fd, off_t length);

DESCRIPTION

       The truncate() and ftruncate() functions cause the regular file named by path or referenced by fd to be truncated to a size of precisely length bytes.
       If the file previously was larger than this size, the extra data is lost.  If the file previously was shorter, it is extended, and the extended part reads as null bytes ('\0').
       The file offset is not changed.
       If  the  size  changed,  then the st_ctime and st_mtime fields (respectively, time of last status change and time of last modification; see stat(2)) for the file are updated, and the set-user-ID and
       set-group-ID permission bits may be cleared.
       With ftruncate(), the file must be open for writing; with truncate(), the file must be writable.

之前就是因为没有看到红色那行字,导致我产生了文件开头的错误,都说了文件偏移量是不会改变的!

实验如下

[cpp] 
 
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <unistd.h>  
  4. #include <sys/types.h>  
  5. #include <sys/stat.h>  
  6. #include <fcntl.h>  
  7.   
  8. int main(void)  
  9. {  
  10.     int fd;  
  11.   
  12.     const char *s1 = "0123456789";  
  13.     const char *s2 = "abcde";  
  14.   
  15.     fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);  
  16.     /* if error */  
  17.   
  18.     write(fd, s1, strlen(s1));  
  19.   
  20.     ftruncate(fd, 0);  
  21.     // lseek(fd, 0, SEEK_SET);  
  22.       
  23.     write(fd, s2, strlen(s2));  
  24.   
  25.     close(fd);  
  26.   
  27.     return 0;  
  28. }  
运行效果


去掉 lseek(fd, 0, SEEK_SET); 的注释后,效果如下:

结论

从以上两张图中,可以看出,不用 lseek 的文件大小为15,用 xxd 查看16进制格式看到 文件头有10个 '\0' 填充。

而重置文件偏移量后,文件大小为5,内容也正确。

因此,在用 ftruncate 函数时,再次写入一定要重新设置文件偏移量(在 ftruncate 之前或之后都行,用 lseek 或 rewind 都可以)

你可能感兴趣的文章
127个超级实用的JavaScript 代码片段,你千万要收藏好(中)
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(下)
查看>>
Flex 布局教程:语法篇
查看>>
年薪50万+的90后程序员都经历了什么?
查看>>
2019年哪些外快收入可达到2万以上?
查看>>
【JavaScript 教程】标准库—Date 对象
查看>>
前阿里手淘前端负责人@winter:前端人如何保持竞争力?
查看>>
【JavaScript 教程】面向对象编程——实例对象与 new 命令
查看>>
我在网易做了6年前端,想给求职者4条建议
查看>>
SQL1015N The database is in an inconsistent state. SQLSTATE=55025
查看>>
RQP-DEF-0177
查看>>
MySQL字段类型的选择与MySQL的查询效率
查看>>
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>