打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
文件操作

原创  文件操作 收藏

这两天做个小东西,使用文件指针读取、显示连续位图,但是发现内存总是一直涨,该释放的都释放了啊,百思不得其解,经过多次测试,终于发现问题是出在FILE *p;这个p没close所以内存得不到释放,按理说我用fread将位图文件读到一个buffer中,这个buffer我使用完就释放了,应该内存得到释放,至于这个文件指针p我只是每次用它来指向一个位图文件,不过是一个地址而已,但是的确因为它没有fclose所以有内存一直得不到释放,下面的文档是我在网上转载的,对文件操作讲的还行,拿来看看!


      文件操作

1、 首先想要向一个文件中写入一个字符串。

   这个时候需要一个文件结构体FILE  来操作文件流。

char* filePath = "D:\\GL\\游戏 \\TEST\\1.txt";

 

FILE* pFile = fopen( filePath, "w");

fwrite("I love you!", 1, strlen("I love you!"), pFile);

这是以写的方式打开一个文件。并且写入一个 I love you  的一个字符串。

fwrite的第一个参数是要写入字符串数组的一个指针, 第二个参数是要每次写入的字节数这里是 1 , 相当于 sizeof  char )如果是整形的话就是 sizeof  int ),第三个参数就是重复写入的次数。 第四个参数是文件流的指针。

 

这个时候我们打开1.txt 的时候发现文件里没有东西。关闭程序再打开 1.txt 发现文件里有内容了。这是因为第一次写入的内容还在缓冲里面没有写入文件当调用 fclose  pFile )的时候可以写入文件。关闭程序也会关闭 pFile 流,所以第二次就有了内容。 

我们也可主动调用 fclose pFile  

有的时候我们需要文件流保持, 需要用fflush  pFile )这个函数把缓冲里的内容刷新到文件里面。

所以调用  fflush pFile  ;也可以看到文件内容。

 

2、 下面是从文件中读入一个字符串。

    char str[100];

char* filePath = "D:\\GL\\游戏 \\TEST\\1.txt";

FILE* pFile;

 

if( !(pFile = fopen(filePath, "r")) )

{

    MessageBox("Open file fail!");

}

Str 是一个字符数组用来保存字符串。

fread(str, 3, 5, pFile);

MessageBox(str);

Fread函数的参数用法和 fwrite 差不错。

运行程序时候发现弹出对话框会 出现乱码

这个是因为字符串不是以'\0' 结尾的。

解决的方法之一是

memset ()把 str 的数组全部赋予 0.

memset(str, 0, 100);

fread 的前面加。这样的话就可以保证末尾是 0 

 

 

 

解决方法之二是

fseek(pFile, 0, SEEK_END);

long pos = ftell(pFile);

str[pos] = '\0';

rewind(pFile);

首先调用fseek 到文件的尾部, 然后调用 ftell 返回当前位置。

然后在数组响应的位置置0 ,最后返回文件头部。 

 

3、 下面讨论文本文件和二进制文件。

当我们按照文本文件方式往文件中写入数据时,一旦遇到换行字符(ASCII 10 ),则会转为回车一换行( ASCII   13  10 )读取文件时候, 一旦遇到回车一换行的组合(即连续的  ASCII   13  10 ), 则会转换为字符( ASCII 10 )。

  当我们按照二进制方式往文件中写入数据时, 则将数据在内存中的存储形式原样输入到文件中。

 

4、 向文件写入一个大的整数。

   例如向文件中写入一个 9876543

   然后打开文件显示出来。

    char ch[10];

int value = 986543;

 

FILE* pFile = fopen(filePath, "w");

itoa(value, ch, 10);

fwrite(ch, 1, 6, pFile);

fclose(pFile);

 

要以字符形式表现出来。

5、 fstream 类来实现读写

    

    ofstream out("D:\\GL\\游戏 \\TEST\\1.txt");

out.write("zhao jie!", strlen("zhao jie!"));

out.close();

这是一个写入文件。Ofstream 有三个参数, 后面的两个有默认值。

   

    ifstream in("D:\\GL\\游戏 \\TEST\\1.txt");

char str[100];

memset(str, 0, 100);

in.read(str, 100);

这是从文件读入一个文件, 和ofstream 一样有是那个参数,后面两个是有默认值的。

 

6、 下面是要讲Win32 支持的文件读写。

   首先是写文件

 

     HANDLE hFile;

hFile = CreateFile("D:\\GL\\游戏 \\TEST\\1.txt", GENERIC_WRITE, 0, NULL,

CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

DWORD numberWrite;

WriteFile(hFile, "write by win32 API!", strlen("write by win32 API!"), &numberWrite,

NULL);

CloseHandle(hFile);

写入文件, 首先是创建一个句柄并且创建一个相应的读写模式。numberWrite 是用来存储写入的字节数的。

 

读文件

     char str[100];

memset(str, 0, 100);

 

HANDLE hFile;

hFile = CreateFile("D:\\GL\\游戏 \\TEST\\1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 

 FILE_ATTRIBUTE_NORMAL, NULL);

DWORD numberRead;

ReadFile(hFile, str, 100, &numberRead, NULL);

MessageBox(str);

CloseHandle(hFile);

首先创建一个字符串数组, 有一百个字节,接着创建句柄。numberRead 是表示读出来的字节数目。

最后关闭句柄。如果不关闭会照成资源泄漏。

 

7、 CFile 类来文件读写。

写入文件。

CFile write("D:\\GL\\游戏 \\TEST\\1.txt", CFile::modeCreate | CFile::modeWrite);

write.Write("Write by using CFile!", strlen("Write by using CFile!"));

write.Close();

首先CFile 类创建一个对象。  The first parameter is a string that is the path to the desired file. The second parameter is access mod.

接着用类里面的两个函数写入字符串, 并且关闭文件。

 

读入文件

char str[100];

memset(str, 0, 100);

 

CFile read("D:\\GL\\游戏 \\TEST\\1.txt", CFile::modeRead);

read.Read(str, 100);

read.Close();

与写入相似, 固定字符串数组。

下面介绍一种动态生成字符串数组的方法。

CFile read("D:\\GL\\游戏 \\TEST\\1.txt", CFile::modeRead);

 

long fileLength = read.GetLength();

char* pfile = new char[fileLength+1];

pfile[fileLength] = 0;

read.Read(pfile, fileLength);

read.Close();

 

MessageBox(pfile);

delete []pfile;

GetLength 来得到文件的长度。后来动态的生成字符串数组。

 

8、 接下来需要用到的是CFileDialog 类用来打开 \ 保存文件。

打开文件

CFileDialog fileDialog(FALSE);

fileDialog.m_ofn.lpstrTitle = "打开文件 ";

fileDialog.m_ofn.lpstrFilter = "All File(*.*)\0*.*\0Text File(*.txt)\0*.txt\0\0";

    if(IDOK == fileDialog.DoModal())

{

    CFile saveAs(fileDialog.GetPathName(), CFile::modeCreate |   CFile::modeWrite);

saveAs.Write("Write by using CFile!", strlen("Write by using CFile!"));

saveAs.Close();

}

首先创建一个对象fileDialog 用于保存文件。这里的 FALSE 就是代表保存的意思。

lpstrTitle 表示保存对话框的 title

lpstrFilter 用于掩码, 大选择 *.txt 的时候 list 中只显示 .txt 的文件。

 

后来调用CFile 文件写入文件字符串。  fileDialog.GetPathName() 用于返回文件的全路径。

 

打开文件

CFileDialog fileDialog(TRUE);

fileDialog.m_ofn.lpstrTitle = "存储文件 ";

fileDialog.m_ofn.lpstrFilter = "All File(*.*)\0*.*\0Text File(*.txt)\0*.txt\0\0";

    if(IDOK == fileDialog.DoModal())

{

    CFile read(fileDialog.GetPathName(), CFile::modeRead);

 

long fileLength = read.GetLength();

char* pfile = new char[fileLength+1];

pfile[fileLength] = 0;

read.Read(pfile, fileLength);

read.Close();

 

MessageBox(pfile);

delete []pfile;

}

 

和保存相似打开一个文件并且读出数据用Dialog 显示。

9、 启动程序是我们经常需要独一些配置文件, 现在的程序是写入注册表的。 以前的是 win.ini 文件。 可以用 WriteProfileString 这个函数来操作 .ini 的文件。具体见 MSDN 

读写配置文件需要在文件刚开始的初始化。

CFileAPP 中的 initInstance 函数中调用:: WriteProfileString 函数来写入 win.ini 文件中。

E.g 

::WriteProfileString("GL", "zoe", "I love you!");

第一个是根键。

相对应的还有一个GetProfileString 函数用来从 win.in 文件中取得内容。

CString str;

::GetProfileString("GL", "zoe", "my", str.GetBuffer(100), 100);

AfxMessageBox(str);

首先创建一个对象用来保存从win.ini 中读取的字符串。

GetBuffer()这个是 CString 类中的一个函数用来自己操作字符串, 指向一个字符串数组。 100 是申请的长度。 

因为这是在winApp 类中, 不是继承 CWND 的类, 所以不能直接用 MessageBox;

需要调用全局的AfxMessageBox ();来显示读取的数据。

 

10、 下面是MFC 中用来操作注册表的读写。 

写入

CWinApp:: WriteProfileString("GL", "zoe", "I love you!");

这样就写入了注册表。那么我们写入的内容在哪里呢??

首先到运行中键入 regedit 打开注册表编辑器。

HKEY_CURRENT_USER->SoftWare->Local AppWizard-Gen..... 中的响应文件夹中找到 zoe 

 

CString str;

str  =  GetProfileString("GL", "zoe", "my");

AfxMessageBox(str);

从注册表中读取数据。GetProfileString  CWinApp 类的返回字符串。

 

 

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

这个CWinApp 类中 SetRegistryKey 是用来在注册表中注册一个文件夹的, 这个 application 中的注册表的数据以后就存放在这个文件夹中。

 

自己来创建注册表和编写注册表。

写入注册表。

HKEY key;

RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\GL\\zoe", &key);

RegSetValue(key, NULL, REG_SZ, "nothing", strlen("nothing"));

RegCloseKey(key);

HKEY是注册表的句柄, 用 RegCreateKey 来创建一个注册表文件夹。这个是在 HEY_LOCAL_MACHINE\SOFTWARE\GL\zoe  目录下打开或者创建。  Key 是返回的打开或者创建的句柄。

RegSetValue是一个设置注册表值的函数。 第一个参数是要设置的句柄。第二个是 zoe 下面的子 Key 要是为空的话,为默认的 key , 第三个参数为注册项的类型。 第四个为要赋值的值, 第五个是赋值的长度。

 

读取注册表。

LONG value;

RegQueryValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\GL\\zoe", NULL, &value);

char* str = new char[value+1];

str[value] = '\0';

RegQueryValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\GL\\zoe", str, &value);

MessageBox(str);

delete []str;

这个是动态生成字符串数组。 RegQueryValue 这个函数的第一个是句柄, 第二个参数是需要读取的 Key ,第三个参数是字符存储的内存地址,当为空的时候,返回第四个参数需要的容量。 下面动态生成数组。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
转载:MFC文件操作,很全面
[学习标准库]stdio.h
孙鑫VC视频教程笔记之第十二课“文件操作(含注册表操作)”
Windows编程中各种操作文件的方法
使用 InternetReadFile 来获取文件 | 学步园
C 之编码问题(Unicode,ASCII,本地默认)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服