C 文件名上的Posix I/O操作是否顺序一致?

C 文件名上的Posix I/O操作是否顺序一致?,c,io,posix,read-write,C,Io,Posix,Read Write,我想知道是否有Posix标准保证,通过对同一文件名重复调用open/close可以看到对文件的修改。为了说明,请考虑这个BASH脚本: #!/bin/bash FILE=$(mktemp) echo "Some data" >> $FILE cat $FILE 是否保证在echo完成时,文件中的所有数据都可用 就Posix函数而言,示例如下: const char fn[] = "/tmp/somefile"; const char data[] = "hello world"

我想知道是否有Posix标准保证,通过对同一文件名重复调用
open
/
close
可以看到对文件的修改。为了说明,请考虑这个BASH脚本:

#!/bin/bash

FILE=$(mktemp)

echo "Some data" >> $FILE
cat $FILE
是否保证在
echo
完成时,文件中的所有数据都可用

就Posix函数而言,示例如下:

const char fn[] = "/tmp/somefile";
const char data[] = "hello world";

// Stage 1
{
   int fd = open(fn, O_CREAT);
   write(fd, data, sizeof data); // #1
   close(fd);
}

// Stage 2
{
   int fd = open(fn);
   read(fd, ...);                // #2
   close(fd);
}
是否可以保证第#1行的写操作对读取的#2可见,或者操作系统是否可以缓存写操作以使其不会及时传播?我们可以假设没有其他进程知道文件名或以其他方式破坏文件查找。

是。例如,从write()规范()中:

成功返回对常规文件的write()后: 通过该写入操作修改的文件中每个字节位置的任何成功读取()都将返回write()为该位置指定的数据,直到再次修改这些字节位置为止。 任何后续对文件中相同字节位置的成功写入()都将覆盖该文件数据。 注意,它表示“Any”read(),也就是说,您可以通过它打开()一个新的fd和read(),并且提供了相同的保证


顺便说一句,虽然这种强一致性使得对语义进行推理变得很容易,但它也使得提供符合POSIX的分布式FS以及良好的性能变得非常困难,如果不是不可能的话

从Linux手册页看:不检查close()的返回值是一个常见但严重的编程错误。前一次写入(2)操作中的错误很可能在最终关闭()时首次报告。关闭文件时不检查返回值可能会导致数据无声丢失。@卢卡马蒂尼:这会对Bash脚本产生什么影响?是否可以检查管道操作是否成功?另外,成功返回
close
是否保证一致性?我指的是示例,而不是脚本。也许还可以检查
echo“Some data”>$FILE的返回值。我在POSIX标准中没有发现任何线索,除了C标准中也存在的fflush调用。例如,Linux在这方面是否严格符合POSIX?@KerrekSB:AFAIK,对于“正常”本地文件系统,是的。网络化/分布式/集群化/无论FS做什么,通常都会以性能的名义采取快捷方式,尽管这不应该在单个客户端中真正被视为跨客户端的不一致。@KerrekSB:想象一个应用程序在相同的文件偏移量下执行
write()
,然后执行
read()
。如果
read()
不返回刚刚写入的数据,那将是一个完全崩溃的内核,不是吗?@MaximYegorushkin:如果我们谈论的是一个文件描述符,那么我完全同意。但我想问的是两个可能完全不相关的阶段。你对此有任何保证吗?@KerrekSB:这种行为是POSIX所要求的。Linux
man write(2)
说:POSIX要求在write()返回新数据后进行读取(2)。请注意,并非所有文件系统都符合POSIX标准。 After a write() to a regular file has successfully returned: Any successful read() from each byte position in the file that was modified by that write shall return the data specified by the write() for that position until such byte positions are again modified. Any subsequent successful write() to the same byte position in the file shall overwrite that file data.