Unix/Linx 文件I/O的一些小思考

来源:互联网 发布:linux chgrp 编辑:程序博客网 时间:2024/06/01 10:19

        今天复习了一下文件I/O,在看open函数的man手册时,看到了选项O_APPEND的说明,意思是每次写时都追加到文件的尾端。然后我心里就产生了几个小问题。

        第一,用O_APPEND选项打开文件时,文件的初始偏移量为多少?

        第二,在有O_APPEND选项的情况下,write之后,文件的偏移量又会是多少?

        第三,在有O_APPEND选项的情况下,write之后,能不能用lseek调整文件偏移量以读取前面的内容?

        为了解决上面三个问题,我写了下面的第一段代码。运行后得出答案。

        首先,不管open打开文件的时候有没有使用O_APPEND选项,文件的初始偏移量都为0。假设write写入之前,文件偏移量的值为A,O_APPEND选项只是在write写入之前,把文件偏移量置为文件长度B,然后再执行写入操作,而写入操作完成后,文件偏移量并不会恢复为值A,而是继续在B的基础上增加实际写入的字节数。即使有O_APPEND选项存在,在write之后,仍然可以用lseek调整文件偏移量以用于读取前面的内容。因为O_APPEND只针对写操作,而且是只在每一次写操作之前把文件偏移量置为当前文件长度,并没有锁定文件偏移量不让修改。

        然后我还写了第二段代码,用于检测自己是否真的理解了read,write,lseek,SEEK_SET,SEEK_CUR和SEEK_END对文件偏移量的影响。


第一段代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <unistd.h>#include <fcntl.h>#define MAXSIZE 100using std::cout;using std::endl;int main () {char buf[MAXSIZE] = "Hello, this is a test.";//新建一个文件a.txtint fd = open ("a.txt", O_CREAT | O_TRUNC | O_WRONLY, 0644);if (fd == -1) {perror ("open a.txt first error");return EXIT_FAILURE;}//向文件中写入数据,然后关闭文件int len = strlen (buf);int n = write (fd, buf, len);if (n != len) {perror ("write error");close (fd);return EXIT_FAILURE;}cout << "\nSuccess to write " << n << " bytes data to the file : \"" << buf << "\"" << endl;close (fd);cout << "\n*****************************************\n" << endl;//再次打开文件,以O_APPEND模式打开fd = open ("a.txt", O_APPEND | O_RDWR);if (fd == -1) {perror ("open a.txt again error");return EXIT_FAILURE;}//验证以O_APPEND模式打开时,初始偏移量是否还是0char ch = 0;cout << "File opened in O_APPEND, first read, then write, finally, back to the beginning of the file, read again.\n" << endl;cout << "Before read, the offset is : " << lseek (fd, 0, SEEK_CUR) << endl;n = read (fd, &ch, sizeof (ch));if (n < 0) {perror ("read error");close (fd);return EXIT_FAILURE;}cout << "Success to read \"" << ch << "\" from file." << endl;cout << "After read, the offset is : " << lseek (fd, 0, SEEK_CUR) << "\n" << endl;//验证以O_APPEND模式写入后,偏移量为文件尾int tmp = write (fd, &ch, n);if (tmp != n) {perror ("write error");close (fd);return EXIT_FAILURE;}cout << "Success to write " << tmp << " bytes data to file : \"" << ch << "\"" << endl;cout << "After write, the offset is : " << lseek (fd, 0, SEEK_CUR) << "\n" << endl;lseek (fd, 0, SEEK_SET);cout << "Change the file offset to value 0" << endl;cout << "Before read, the offset is : " << lseek (fd, 0, SEEK_CUR) << endl;n = read (fd, &ch, sizeof (ch));if (n < 0) {perror ("read error");close (fd);return EXIT_FAILURE;}cout << "Success to read \"" << ch << "\" from file." << endl;cout << "After read, the offset is : " << lseek (fd, 0, SEEK_CUR) << endl;close (fd);return EXIT_SUCCESS;}

第一段代码运行结果如下:



运算完这段代码后文件内容:


第二段代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <unistd.h>#include <fcntl.h>#define MAXSIZE 100using std::cout;using std::endl;int main () {char buf[MAXSIZE] = "Hello, this is a test.";char test[MAXSIZE] = "TEST";//新建一个文件a.txtint fd = open ("a.txt", O_CREAT | O_TRUNC | O_WRONLY, 0644);if (fd == -1) {perror ("open a.txt first error");return EXIT_FAILURE;}//向文件中写入数据,然后关闭文件int len = strlen (buf);int n = write (fd, buf, len);if (n != len) {perror ("write error");close (fd);return EXIT_FAILURE;}cout << "\nSuccess to write " << n << " bytes data to file : \"" << buf << "\"" << endl;close (fd);cout << "\n*****************************************\n" << endl;//再次打开文件fd = open ("a.txt", O_RDWR);if (fd == -1) {perror ("open a.txt again error");return EXIT_FAILURE;}//输出文件未修改之前的内容char ch = 0;cout << "Before modifications, the file is : \"";while ( (n = read (fd, &ch, sizeof (ch))) > 0)cout << ch;cout << "\"\n" << endl;//输出chlseek (fd, 1, SEEK_SET);n = read (fd, &ch, sizeof (ch));if (n < 0) {perror ("read error");close (fd);return EXIT_FAILURE;}cout << "Success to read \"" << ch << "\" from file." << endl;//想想看test会覆盖掉哪一些内容lseek (fd, 5, SEEK_CUR);n = strlen (test);int tmp = write (fd, test, n);if (tmp != n) {perror ("write error");close (fd);return EXIT_FAILURE;}cout << "Success to write " << tmp << " bytes data to file : \"" << test << "\"" << endl;//想想看ch会是什么n = read (fd, &ch, sizeof (ch));if (n < 0) {perror ("read error");close (fd);return EXIT_FAILURE;}cout << "Success to read \"" << ch << "\" from file." << endl;//想想看5会覆盖在哪里lseek (fd, -2, SEEK_END);n = write (fd, "5", 1);if (n != 1) {perror ("write error");close (fd);return EXIT_FAILURE;}//输出修改后的文件内容lseek (fd, 0, SEEK_SET);cout << "\nAfter modifications, the file is : \"";while ( (n = read (fd, &ch, sizeof (ch))) > 0)cout << ch;cout << "\"" << endl;close (fd);return EXIT_SUCCESS;}

第二段代码运算结果如下:




原创粉丝点击