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;}
第二段代码运算结果如下:
- Unix/Linx 文件I/O的一些小思考
- unix----文件I/O
- UNIX文件 I / O
- UNIX文件I/O函数
- UNIX 文件I/O总结
- 关于UNIX的文件I/O补充实例
- 由unix文件I/O引出的原子操作
- Unix文件 I/O(不带缓冲区的)上
- unix c编程:不带缓冲的文件 I/O
- UNIX的高级I/O
- Unix 标准I/O总结和与文件I/O的比较
- Linux I/O 重定向的一些小技巧
- Linux I/O重定向的一些小技巧
- 转贴:Linux I/O重定向的一些小技巧
- 技巧:Linux I/O重定向的一些小技巧
- 技巧:Linux I/O重定向的一些小技巧
- Linux I/O重定向的一些小技巧
- 技巧:Linux I/O重定向的一些小技巧
- .net
- 大连SEO为你解答:网站内页不收录如何解决?
- An Easy Problem
- 《我的第一本c++书》学习笔记:STL之shared_ptr(上)
- HDU 1269——迷宫城堡
- Unix/Linx 文件I/O的一些小思考
- PHP 传值时,要对+ 号进行处理
- HDU1210---Eddy's 洗牌问题 HDU(89)
- sqlplus常用命令
- 两天没更新了
- poj 1062"错误“代码
- [Oracle] SQL*Loader 详细使用教程(3)- 控制文件
- Stanford Algorithms: Design and Analysis, Part 1[week 6]
- nodejs的总结