我的意思是用 fdopen
FILE *fdopen(int fd, const char *mode);
在 人页,它规定 "流的模式("r"、"r+"、"w"、"w+"、"a"、"a+"中的一个值)必须与文件描述符的模式兼容。"因此,我必须首先了解 fd
(我想这是一个 int
)来选择合适的 const char *mode
为流。
我知道我应该用 fcntl
int fcntl(int fd, int cmd);
来 "操作文件描述符"(在下文中,我引用了来自于 本官).它可以对以下内容进行操作。
文件描述符标志
以下命令用于操作与文件描述符相关的标志。 ...
文件状态标志
每个打开的文件描述都有一定的关联状态标志,由open(2)初始化......。
(我就不知道这两者之间的区别了.鉴于 fcntl
完全是指文件描述符,我想第二个标题应该是 "文件描述符状态标志",这样我们就有了 "标志 "和 "状态标志"......让我很困惑。我没有看到任何这方面的规范)。) 我在这里顺便提一下,我正在整理一个关于这个问题的具体问题。
从描述来看,我想我应该选择后者.在这种情况下,当 cmd=F_GETFL
,返回值是 "文件访问模式和文件状态标志"。"文件状态标志及其语义描述于 开放(2)".
现在我看了引用的资料后,无法理解。
所有可能的模式是什么?int
s)的fd
因此,所有的组合mode(fd) <-> mode(stream)是 "兼容 "的。
我想应该可以把两个列表放在一起,然后用箭头连接。
相关的。
文件描述符的规范 (我这样问)
如何理解O_RDONLY=0? (我问过这个问题)
https:/www.gnu.orgsoftwarelibcmanualhtml_nodeAccess-Modes.html
https:/www.gnu.orgsoftwarelibcmanualhtml_nodeFile-Status-Flags.html#File-Status-Flags
经过学习回答和评论,在这里和在 如何理解O_RDONLY = 0?我把下面的代码放在一起,从那里,我得到了以下关于文件描述符状态的信息"言语"(我不愿意用""这个词。旗帜",见下文注,摘自 此话)和文件打开 模式s.
*** Flag O_RDONLY = 0 = 0 = x0000
*** Flag O_WRONLY = 1 = 1 = x0001
*** Flag O_RDWR = 2 = 10 = x0002
*** Flag O_CREAT = 64 = 1000000 = x0040
*** Flag O_TRUNC = 512 = 1000000000 = x0200
*** Flag O_APPEND = 1024 = 10000000000 = x0400
*** Flag O_WRONLY | O_CREAT | O_TRUNC = 577 = 1001000001 = x0241
*** Flag O_WRONLY | O_CREAT | O_APPEND = 1089 = 10001000001 = x0441
*** Flag O_RDWR | O_CREAT | O_TRUNC = 578 = 1001000010 = x0242
*** Flag O_RDWR | O_CREAT | O_APPEND = 1090 = 10001000010 = x0442
*** Mode r F_GETFL -> 32768 = 1000000000000000 = x8000
*** Mode w F_GETFL -> 32769 = 1000000000000001 = x8001
*** Mode a F_GETFL -> 33793 = 1000010000000001 = x8401
*** Mode r+ F_GETFL -> 32770 = 1000000000000010 = x8002
*** Mode w+ F_GETFL -> 32770 = 1000000000000010 = x8002
*** Mode a+ F_GETFL -> 33794 = 1000010000000010 = x8402
三栏中的数字分别是十进制、二进制和十六进制.寻找 "奇怪的" x8000
我发现在 fcntl-linux.h
# ifdef __USE_GNU
...
# define AT_RECURSIVE 0x8000 /* Apply to the entire subtree. */
...
# endif
所以,除了那个 旗帜,存在于所有 模式的,该协会将是
r <-> O_RDONLY
w <-> O_WRONLY
a <-> O_WRONLY | O_APPEND
r+ <-> O_RDWR
w+ <-> O_RDWR
a+ <-> O_RDWR | O_APPEND
现在,这给我提供了几个耐人寻味的发现。
名单并不符合... 托尼-坦努斯给出的表格.
该 词 对于 r+
与 w+
.这对编码员来说是一个挑战,即使用哪种模式与 fdopen
当言 O_RDWR
(既 r+
和 w+
将是确定的).根据 这个我以为 w+
还 O_CREAT
(如上表所示)。w
来拥有它。
为了编写完全可移植的代码,似乎每当使用 fdopen
必须像我写的那样写代码来自动找到连接。模式 <-> 词.(其实我做的部分工作是人工识别,还需要进一步编码)。
EDIT根据评论,对第1点和第2点的解释是,该表显示的匹配度是:"我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说,我是说。fopen
模式和 open
标志,即在创建过程中,但我通过使用 fcntl
旗帜是否持久 之后 创作,而不是那些用于 在...期间 创作。此处, O_CREAT
和 O_TRUNC
属于 文件创建标志 因此不具有持久性.另一方面。O_APPEND
属于 文件状态标志 并且是持久性的。"这两组标志的区别在于 档案创建标志 会影响开放操作本身的语义,而 档案状态标志 影响后续IO操作的语义。" [档号]
注:The open(2) 的手册页 首先介绍了文件访问模式,然后补充说:"此外,零个或多个文件创建标志和文件状态标志可以在标志中进行位智操作......" 但它(正确的)并没有提到文件访问模式可以进行位操作。对我来说,"flag "这个词绝对是个误区,也是误导。
to_binary
可以使用二进制形式)。)int main() {
const char fname[100] = "test.txt";
const char modes[][4] = { "r", "w", "a", "r+", "w+", "a+" };
const size_t nmodes = sizeof(modes) / sizeof(modes[0]);
const int flags[] = { O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
O_WRONLY | O_CREAT | O_TRUNC,
O_WRONLY | O_CREAT | O_APPEND,
O_RDWR | O_CREAT | O_TRUNC,
O_RDWR | O_CREAT | O_APPEND
};
const char flags_str[][100] = { "O_RDONLY", "O_WRONLY", "O_RDWR", "O_CREAT", "O_TRUNC", "O_APPEND",
"O_WRONLY | O_CREAT | O_TRUNC",
"O_WRONLY | O_CREAT | O_APPEND",
"O_RDWR | O_CREAT | O_TRUNC",
"O_RDWR | O_CREAT | O_APPEND"
};
const size_t nflags = sizeof(flags) / sizeof(flags[0]);
for (size_t iflag = 0 ; iflag < nflags ; iflag++) {
const int flag = flags[iflag];
const char * flag_str = flags_str[iflag];
char nbin[33];
to_binary(flag, nbin);
printf( "*** Flag %30s = %5d = %12s = x%04x\n", flag_str, flag, nbin, flag);
}
for (size_t imode = 0 ; imode < nmodes ; imode++) {
const char * mode = modes[imode];
FILE * fp1 = fopen(fname, mode);
int fd1 = fileno(fp1);
int retval = fcntl(fd1, F_GETFL);
char nbin[33];
to_binary(retval, nbin);
printf( "*** Mode %2s F_GETFL -> %5d = %12s = x%04x", mode, retval, nbin, retval);
fclose(fp1);
}
return 0;
}