- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如题,当同时指定O_APPEND
和O_TRUNC
时,文件打开时不会先被截断。
那么,当指定O_APPEND
时,我如何仍然先截断文件?
@更新:
O_APPEND
和 O_TRUNC
可以完美地协同工作,这是我之前代码中的错误。
关于原子
以下代码证明 O_APPEND
将确保每个 write()
中的追加操作是原子的,方法是将偏移量设置为在原子系统调用中自动结束。
// atomic append
// TLPI exercise 5.3
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int atomic_append(int argc, char *argv[]) {
char *buf = "a";
int opt;
if(argc < 3) {
printf("command format: %s\n", "atomic_append <filename> <byte-count> [x]");
return -1;
}
char *fp = argv[1];
int bc = atoi(argv[2]);
int flag_append = 1;
if(argc >=4 && strcmp(argv[3], "x")==0) {
flag_append = 0;
}
int fd = open(fp, O_RDWR | O_CREAT | O_TRUNC | (flag_append?O_APPEND:0), 0644);
int i=0;
while(i++ < bc) {
if(!flag_append) {
lseek(fd, 0, SEEK_END);
}
write(fd, buf, 1);
}
close(fd);
return 0;
}
int main(int argc, char *argv[]) {
atomic_append(argc, argv);
return 0;
}
编译运行步骤:
a.out
./a.out a1 100000 & ./a.out a1 100000
./a.out a2 100000 x & ./a.out a2 100000 x
ll -h a*
然后你可以看到a1和a2有不同的大小。
这是 TLPI 练习 5.3 中的一个练习。
最佳答案
O_APPEND
和 O_TRUNC
可以很好地协同工作。如果他们不这样做,我会怀疑您的操作系统中存在错误(或者更可能是您的代码中)。
这是一个简单的测试程序,它在 MacOS、OpenBSD 和两个不同版本的 Linux 上都运行良好:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#define FN "truncateme"
int
main(int argc, char **argv)
{
char buf[16];
ssize_t r;
int fd;
if ((fd = open(FN, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
err(1, "open 1 ");
if (write(fd, "foo", 3) != 3)
err(1, "write 1");
close(fd);
if ((fd = open(FN, O_RDWR|O_TRUNC|O_APPEND, 0600)) == -1)
err(1, "open 2");
if (write(fd, "1", 1) != 1)
err(1, "write 2");
close(fd);
if ((fd = open(FN, O_RDONLY)) == -1)
err(1, "open 3");
if ((r = read(fd, buf, 16)) != 1)
errx(1, "read %d != 1", (int)r);
return 0;
}
Here is the POSIX description of open
请注意它是如何表示“可以使用以下各项的任意组合”并且该列表包括 O_APPEND
和 O_TRUNC
。
我真的不知道 O_TRUNC
会如何与 O_APPEND
交互,因为第一个只是告诉操作系统当时如何处理文件O_APPEND
告诉操作系统在调用 write
和 writev
函数时要做什么。
此外,为了消除其他答案给您带来的困惑。 O_APPEND
does guarantee atomicity of the write : "如果设置了文件状态标志的 O_APPEND 标志,则在每次写入之前,文件偏移量应设置为文件末尾,并且在更改文件偏移量和写入操作之间不应发生任何干预文件修改操作。"
为了消除进一步的混淆,我在关于 POSIX 下文件操作原子性的评论中看到,this part of the standard is relevant.
关于c - 同时指定 O_APPEND 和 O_TRUNC 时,它不会截断吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30022127/
func OpenFile(name string, flag int, perm FileMode) (*File, error) f, err := os.OpenFile("notes.txt"
我需要将二进制文件的内容读入缓冲区,在该缓冲区上执行操作,而不是使用输出缓冲区重写同一文件的内容。 #include #define BUFFSIZE 1024 char in[BUFFSIZE]
据我了解,open() 函数的O_TRUNC 说明符应该先删除文件中的内容,然后再开始写入。 相反,它所做的只是让我随时覆盖文件中的内容。 我的问题是文件包含 ASCII“11”,它应该做的是读取它并
如题,当同时指定O_APPEND和O_TRUNC时,文件打开时不会先被截断。 那么,当指定O_APPEND时,我如何仍然先截断文件? @更新: O_APPEND 和 O_TRUNC 可以完美地协同工作
我是一名优秀的程序员,十分优秀!