Linux C ftruncate 函数清空文件注意事项(要使用 lseek 重置偏移量)
2015-02-06 14:08
639 查看
之前有个要把打开的文件清空,然后重新写入的需求,但是使用 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.
之前就是因为没有看到红色那行字,导致我产生了文件开头的错误,都说了文件偏移量是不会改变的!
实验如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd;
const char *s1 = "0123456789";
const char *s2 = "abcde";
fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
/* if error */
write(fd, s1, strlen(s1));
ftruncate(fd, 0);
// lseek(fd, 0, SEEK_SET);
write(fd, s2, strlen(s2));
close(fd);
return 0;
}运行效果:
去掉 lseek(fd, 0, SEEK_SET); 的注释后,效果如下:
结论:
从以上两张图中,可以看出,不用 lseek 的文件大小为15,用 xxd 查看16进制格式看到 文件头有10个 '\0' 填充。
而重置文件偏移量后,文件大小为5,内容也正确。
因此,在用 ftruncate 函数时,再次写入一定要重新设置文件偏移量(在 ftruncate 之前或之后都行,用 lseek 或 rewind 都可以)。
------------------------------------- 我是解释分割线 --------------------------------------
首先 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.
之前就是因为没有看到红色那行字,导致我产生了文件开头的错误,都说了文件偏移量是不会改变的!
实验如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd;
const char *s1 = "0123456789";
const char *s2 = "abcde";
fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
/* if error */
write(fd, s1, strlen(s1));
ftruncate(fd, 0);
// lseek(fd, 0, SEEK_SET);
write(fd, s2, strlen(s2));
close(fd);
return 0;
}运行效果:
去掉 lseek(fd, 0, SEEK_SET); 的注释后,效果如下:
结论:
从以上两张图中,可以看出,不用 lseek 的文件大小为15,用 xxd 查看16进制格式看到 文件头有10个 '\0' 填充。
而重置文件偏移量后,文件大小为5,内容也正确。
因此,在用 ftruncate 函数时,再次写入一定要重新设置文件偏移量(在 ftruncate 之前或之后都行,用 lseek 或 rewind 都可以)。
相关文章推荐
- Linux C ftruncate 函数清空文件注意事项(要使用 lseek 重置偏移量)
- Linux C ftruncate 函数清空文件注意事项(要使用 lseek 重置偏移量)
- [Linux流操作]使用fgetpos函数获取文件当前偏移量
- Linux socket 编程中 write 函数使用的注意事项
- Linux使用带时区转换的时间函数注意事项(负负得正)
- 使用静态库时需要注意的事项(gcc下程序调用静态库编译命令:主文件必须在静态库前面!)
- inline 函数的使用以及注意事项
- 使用CRT函数和CreateThread的注意事项
- 免安装Oracle客户端使用PL/SQL连接Linux Oracle 注意事项
- services文件一使用注意事项
- new与delete函数使用方法以及注意事项
- sscanf 函数使用注意事项
- 在vxworks下使用floor等数学函数的注意事项
- Linux下使用coredump时的注意事项
- 使用C++流对象打开文件的注意事项
- services文件一使用注意事项
- WebWork之--使用fileUpload interceptor实现文件上传[基本配置+注意事项]
- OPENCV的在LINUX下的安装使用注意事项
- 字符串拷贝函数使用注意事项
- PHP IN_ARRAY 函数使用注意事项