bash-3.1$ cat test.txt This is a test file for test04.c. |
#include <stdio.h> int main(void) { char *fname = "test.txt"; FILE *fp; fp = fopen(fname, "r+"); fseek(fp, 0, SEEK_END); fprintf(fp, "hello, world!\n"); return 0; } |
bash-3.1$ cat test.txt This is a test file for test04.c. hello, world! |
原帖由 sihan 于 2008-1-31 15:45 发表
一直觉得C不能直接对磁盘文件操作, 而是把文件全部读到内存理, 操作完成后,
在全部写回磁盘。 可是下面这个程序确实可以工作, 不知道哪位高手知道
其内部的实现思路大概是怎么的?
个人觉得应该是: ...
原帖由 sihan 于 2008-1-31 15:45 发表
一直觉得C不能直接对磁盘文件操作, 而是把文件全部读到内存理, 操作完成后,
在全部写回磁盘。 可是下面这个程序确实可以工作, 不知道哪位高手知道
其内部的实现思路大概是怎么的?
个人觉得应该是: ...
原帖由 halve 于 2008-1-31 16:05 发表
sihan 说的大致没有错
一般情况下,我们并不能直接对磁盘进行读写操作
事实上,操作系统会维护一个内存区域,这个区域由很多小块内存组成
每一内存小块对应磁盘的一个小单元,比如一个扇区
然后我们对磁盘的 ...
原帖由 sihan 于 2008-1-31 16:18 发表
我刚问的问题的关键是: fopen("r+"), fseek(), fwrite() 这样的操作确实
可以不自己读文件到内存, 改, 然后写磁盘。
按理说:
fopen() ->open()
fseek() -> lseek()
fwrite() -> write()
照 ...
原帖由 halve 于 2008-1-31 16:29 发表
open() 得到这个文件磁盘布局的索引信息,即每个位置的数据存在磁盘哪个扇区上
lseek() 得到文件指定位置处数据对应的扇区位置
write() 修改扇区内容
这个过程中,所有的操作都是作用于磁盘的内存镜像
有可能你要修改的扇区并没有对应的内存镜像
这个时候系统会负责将这个扇区读入内存(总的镜像数目有限制,若没有多余空闲区域,系统会释放一个已经不再使用的镜像)
原帖由 sihan 于 2008-1-31 16:36 发表
那现在假定: “读文件到内存, 改, 然后写磁盘” 成立。 接下来的问题是:
我要在一个4G的文件中间插入“hello, world!"这句。我进行的操作是:
fopen(file, "r+");
fseek(file_middle);
fwrite( ...
原帖由 GodPig 于 2008-1-31 20:50 发表
还有一种是用内存映射的方法进行操作的,这普通的操作与内存映射再进行操作有什么样的区别吗???
看大家的解释,也是将某一块映射到内存,然后再进行读写之类的操作
原帖由 SuperZ 于 2008-1-31 21:13 发表
在所有语言中,文件操作最终都会转化成系统调用(文件系统的系统调用)。
所以,文件读写策略和c语言没有任何关系;是操作系统,文件系统和设备驱动程序关心的事情。
O_SYNC 打开 文件 实现 I/O 的 同步 . 任何 通过 文件描述符 对 文件 的 write 都会 使 调用 的 进程 中断 , 直到 数据 被 真正 写入 硬件 中 . |
原帖由 sihan 于 2008-2-1 14:15 发表
O_SYNC
打开 文件 实现 I/O 的 同步 . 任何 通过 文件描述符 对 文件 的 write 都会 使 调用 的 进程 中断 , 直到 数据 被 真正 写入 硬件 中 .
但还是会使用内核buffer的。
这和我问的问题没 ...
原帖由 sihan 于 2008-2-1 14:15 发表
O_SYNC
打开 文件 实现 I/O 的 同步 . 任何 通过 文件描述符 对 文件 的 write 都会 使 调用 的 进程 中断 , 直到 数据 被 真正 写入 硬件 中 .
但还是会使用内核buffer的。
这和我问的问题没 ...
原帖由 flw2 于 2008-2-1 17:27 发表
我看了好久也发只有SuperZ说的完全符合你的题目意思
其实D语言也能操作文件,只要你使用linux的系统调用
2楼老版主是想告诉你你的说法明显是错的
3楼说了和没说一样
4也说了和语言没关系
5楼说的没 ...
原帖由 sihan 于 2008-2-1 18:12 发表
我在12楼已经明确表明 halve 说的符合我的意思。
zx_wing 让我更肯定这种理解,
本来想在那层节贴的, 但牵扯到大家可以互相学习,
就没节。
你说了一堆, 除了激发大家的火药味之外, 感觉没一点用 ...
原帖由 Edengundam 于 2008-2-3 16:52 发表
你可以调查下Windows系统上提供的: FILE_FLAG_WRITE_THROUGH, FILE_FLAG_NO_BUFFERING.
提供这种操作, 可以阻止OS进行磁盘buffer管理, 为一些特殊应用程序, 譬如: DBMS实现管理buffer提供支持.
Win ...
原帖由 zx_wing 于 2008-2-3 17:21 发表
兄台误解LZ意思了。FILE_FLAG_WRITE_THROUGH、FILE_FLAG_NO_BUFFERING其实类似于linux下的O_SYNC和DIRECT_IO参数。
前者是写操作直接flush到磁盘不缓存,后者是不使用文件系统的buffer。这和LZ的意思无关。
所谓直接操作文件,意思是指数据是如何写入磁盘的,中间会不会经过内存?而不是时候使用操作系统提供的一些buffer机制。
如果可以直接操作文件,不经过内存,就变成CPU把自己cache(或连CPU自己的cache都不经过)中的内容不经过内存的途径而直接写入磁盘中。现在计算机体系中没有这种实现。
...
原帖由 Edengundam 于 2008-2-3 17:27 发表
LZ问题在于根本不理解c lib的缓存, OS的缓存, 进程退出时候, c lib语义(APUE有介绍). 如果可以, 当然不经过内核管理的buffer, 这已经是直接操作了. 而且还有裸设备, 说到这些, 磁盘上还有buffer呢. 非要扯什 ...
原帖由 zx_wing 于 2008-2-3 17:37 发表
不是我非要扯什么硬件的cache来显得我高深,小弟虽然不才,也没必要靠这些东西彰显自己。
从LZ的问题和他的回复,我认为大部分朋友误解了LZ的意思,包括flw2兄弟。
LZ是给了个例子,没有分配内存,就把一个 ...
原帖由 Edengundam 于 2008-2-3 17:43 发表
字符串就在内存啊...所以我认为他不知道究竟怎么写的, 事实上这个过程很可能没有写磁盘的过程. 所有的信息都只是更新到内核的buffer上了. 根本不涉及到底层东西. 因为没有flush(NULL), 内核不一定立即写磁盘 ...
原帖由 zx_wing 于 2008-2-3 17:49 发表
关键就在“字符串就在内存啊...”这点,我估计LZ没把这个想到,想岔了
也可能是我们对LZ问题有不同的理解,所以回复侧重面不同,怎么理解就看LZ。
不好意思,刚才激动了,惭愧惭愧
原帖由 sihan 于 2008-1-31 15:45 发表
一直觉得C不能直接对磁盘文件操作, 而是把文件全部读到内存理, 操作完成后,
在全部写回磁盘。 可是下面这个程序确实可以工作, 不知道哪位高手知道
其内部的实现思路大概是怎么的?
原帖由 sihan 于 2008-1-31 16:02 发表
那各位的意思是, 直接对磁盘进行操作了?
那如果我想给文件中间插入一段文字, fseek到文件中间, 然后fwrite进入。 这个过程怎么实现的呢?
岂不是要把我的fseek点以后的内容往后移我要fw ...
原帖由 Liu_xp2003 于 2008-2-3 23:32 发表
就发现34楼的一针见血,点中要害!大部分回帖跟顶楼的问题都不相干...
看了代码,感觉代码的作者对Linux的device输出运用的很有形.顺便提醒一下楼主,这种方式输出可以在文件末尾追加内容,但是不能在文件中间做插 ...
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |