请问,fopen这个函数到底做了什么?

greatmj001 2009-09-25 12:40:12
fopen这个函数到底做了什么?
是将文件读入内存吗?但是,我打开了一个很大的文件,200M吧,进程显示并没有占用很大内存啊.
...全文
549 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
greatmj001 2009-09-30
  • 打赏
  • 举报
回复

VC中
在"stdio.h"中有如下定义
struct _iobuf {
char *_ptr; //文件输入的下一个位置
int _cnt; //当前缓冲区的相对位置
char *_base; //指基础位置(即是文件的其始位置)
int _flag; //文件标志
int _file; //文件的有效性验证
int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
int _bufsiz; //文件的大小
char *_tmpfname; //临时文件名
};
typedef struct _iobuf FILE;


搜了一下关于FILE结构的含义,
int _bufsiz; //文件的大小
这个解释,我怎么觉得不太对呀?
haierpro 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 greatmj001 的回复:]
试了,是这样啊!谢谢!
分配给每个文件的cache的大小是固定的吗?都是4096?
[/Quote]

不一定,在FAT文件系统中一般是一个簇的大小。也就是你在格式化磁盘时,设置的“分配单元大小”,这也是一个文件在磁盘上占用的最小空间,也就是说即使一个文件中只有一个字节的内容,它在磁盘上也要占用一个簇的空间。
greatmj001 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 gelu1040 的回复:]
文件都不知道怎么存储的还研究打开文件操作.........
[/Quote]

楼上,说话不要那么酸好不好.
谁天生什么都知道啊,不懂就向大家虚心求教,有什么问题.
gelu1040 2009-09-29
  • 打赏
  • 举报
回复
文件都不知道怎么存储的还研究打开文件操作.........
greatmj001 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 haierpro 的回复:]

文件系统中有cache(高速缓存)的,因为硬盘的速度比起CPU和RAM的速度,实在是太慢了,如果频繁的从文件中存取小量的数据,那程序的效率将会相当的低,所以文件系统需要加入cache(在RAM中分配一部分空间,FAT文件系统中应该是簇大小级别的),写入的时候,如果写入的内容的大小没有超过cache的大小,并且写入地址在cache范围之内,那么这些内容就只会写入cache,而不会写入硬盘。只有当cache被写满后,或者下次写入的地址超出当前cache的范围时,或者关闭文件时,或者通过fflush等函数强制刷新cache,才会把cache中的内存容写入硬盘的。
写完后,关闭前,调用一下fflush试试。

[/Quote]

试了,是这样啊!谢谢!
分配给每个文件的cache的大小是固定的吗?都是4096?
anhongsen521 2009-09-29
  • 打赏
  • 举报
回复
打开磁盘文件 没有此文件则创建此文件
greatmj001 2009-09-29
  • 打赏
  • 举报
回复
才发现,我19楼的回复内容怎么没发全.
17楼说的,当缓冲区满或者close的时候才会将内容真正的写到磁盘上.经过我测试,好象是这样.
_bufsiz的大小,我看了下,是4096.以下代码,如果在fclose(fp)停止运行,4096个字符后的东西就写没进文本.
if((fp = fopen("a.txt", "at+")) == NULL) 
{
cout < < "Can't open the file" < < endl;
return;
}
for(int i=0; i < 5000; i++)
{
if(i == 4095)
fputs("@", fp);
fputs("g", fp);
}

fclose(fp);
return;
jkx01whg 2009-09-29
  • 打赏
  • 举报
回复
fopen得到的是一个FILE的指针,这个指针指向要打开的目标文件
天堂路标 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wendll 的回复:]
fopen得到的是一个FILE的指针,FILE的结构你可以看一下。
fopen后并不代表将整个文件装入内存吧
[/Quote]
FILE*fopen( pathname, )
lbjfeng 2009-09-27
  • 打赏
  • 举报
回复

struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;

当我执行了打开操作以后,

- stream 0x00424aa0
+ _ptr 0x00000000 ""
_cnt 0
- _base 0x00000000 ""
CXX0030: Error: expression cannot be evaluated
_flag 1
_file 3
_charbuf 0
_bufsiz 0
- _tmpfname 0x00000000 ""
CXX0030: Error: expression cannot be evaluated

haierpro 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 greatmj001 的回复:]
引用 12 楼 haierpro 的回复:
调用fopen只会在文件系统管理器中创键一个打开文件对象,保存与此文件相关的低层信息,然后就返回了,不会把内容读入内存的。在调用fread时,才会把文件内容读入内存。


但是,有这么个现象,比如说下面这段程序,
if((fp = fopen("a.txt", "at+")) == NULL)
{
cout < < "Can't open the file" < < endl;
return;
}
fputs("mno", fp);

return;

断点设在“return;”,然后终止程序,"mno"就没有加入,如果执行完,虽然没有写FCLOSE,但是"mno"就是加入的。这说明内存里,应该有一块映射吧。

[/Quote]

文件系统中有cache(高速缓存)的,因为硬盘的速度比起CPU和RAM的速度,实在是太慢了,如果频繁的从文件中存取小量的数据,那程序的效率将会相当的低,所以文件系统需要加入cache(在RAM中分配一部分空间,FAT文件系统中应该是簇大小级别的),写入的时候,如果写入的内容的大小没有超过cache的大小,并且写入地址在cache范围之内,那么这些内容就只会写入cache,而不会写入硬盘。只有当cache被写满后,或者下次写入的地址超出当前cache的范围时,或者关闭文件时,或者通过fflush等函数强制刷新cache,才会把cache中的内存容写入硬盘的。
写完后,关闭前,调用一下fflush试试。



kongbai308416350 2009-09-25
  • 打赏
  • 举报
回复
例子很 生动.......
greatmj001 2009-09-25
  • 打赏
  • 举报
回复
期待高手解惑!
sdd0124 2009-09-25
  • 打赏
  • 举报
回复
顶上,每天收获一点,谢谢楼主。
greatmj001 2009-09-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 aizibion 的回复:]
你打开成功了吗?
[/Quote]

肯定了,专门打开的呀.也不做其他操作
wendll 2009-09-25
  • 打赏
  • 举报
回复
fopen得到的是一个FILE的指针,FILE的结构你可以看一下。
fopen后并不代表将整个文件装入内存吧
aizibion 2009-09-25
  • 打赏
  • 举报
回复
你打开成功了吗?
gelu1040 2009-09-25
  • 打赏
  • 举报
回复
fopen 的时候,CPU只将文件系统中的这个文件信息读出,比如文件名称,文件路径.
注意红色字体部分,此时并没有访问文件内部的数据.只要是文件,不管他是10000000000GB还是0bit,打开后读出是数据量都是一样的大小(所需文件信息的大小).
另外,当fwrite之后,数据确实已经写入了存储器物理设备,但是并没有修改文件的信息,而文件的信息里面包含了文件的存储区域的表,这表没修改.写入的地方不归这个文件管,所以宏观上并没写入.所以需要fclose

还有,文件被删除之后,还可以还原,也是这个原因.删除的是文件的信息,并没有删除文件的数据.所以可以还原出来,只要重新指定这个文件可以管理的存储范围就可以了.
当然深度删除是把文件信息重置,文件数据部分写入无用的值,那么这个文件就无法还原出来了.


看看文件系统方面的资料就直接理解了
greatmj001 2009-09-25
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 w0911h 的回复:]
文件写入不是马上刷新的,当缓冲区满或者close的时候才会将内容真正的写到磁盘上,return之前系统会调用一些默认的清理函数,这些函数会执行close操作
[/Quote]
if((fp = fopen("a.txt", "at+")) == NULL)
{
cout << "Can't open the file" << endl;
return;
}
for(int i=0; i < 5000; i++)
{
if(i == 4095)
fputs("@", fp);
fputs("g", fp);
}

fclose(fp);
return;
2009-09-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 mstlq 的回复:]
“打开”不意味着“全部装入内存”……

打个比方吧……
我有一部蓝光压制的高清无码爱情动作片,rmvb的,总共3g大……
我用kmp播放器打开它,我享受影片的的时候,任务管理器告诉我,我内存使用500多m……
[/Quote]
多次佩服 mstlq 的生动形象与无可比拟的亲和力~~
加载更多回复(7)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧