這兩天做個(gè)小東西,使用文件指針讀取、顯示連續(xù)位圖,但是發(fā)現(xiàn)內(nèi)存總是一直漲,該釋放的都釋放了啊,百思不得其解,經(jīng)過(guò)多次測(cè)試,終于發(fā)現(xiàn)問(wèn)題是出在FILE *p;這個(gè)p沒(méi)close所以內(nèi)存得不到釋放,按理說(shuō)我用fread將位圖文件讀到一個(gè)buffer中,這個(gè)buffer我使用完就釋放了,應(yīng)該內(nèi)存得到釋放,至于這個(gè)文件指針p我只是每次用它來(lái)指向一個(gè)位圖文件,不過(guò)是一個(gè)地址而已,但是的確因?yàn)樗鼪](méi)有fclose所以有內(nèi)存一直得不到釋放,下面的文檔是我在網(wǎng)上轉(zhuǎn)載的,對(duì)文件操作講的還行,拿來(lái)看看!
文件操作
1、 首先想要向一個(gè)文件中寫(xiě)入一個(gè)字符串。
這個(gè)時(shí)候需要一個(gè)文件結(jié)構(gòu)體FILE 來(lái)操作文件流。
char* filePath = "D:\\GL\\游戲 \\TEST\\1.txt";
FILE* pFile = fopen( filePath, "w");
fwrite("I love you!", 1, strlen("I love you!"), pFile);
這是以寫(xiě)的方式打開(kāi)一個(gè)文件。并且寫(xiě)入一個(gè) I love you 的一個(gè)字符串。
fwrite的第一個(gè)參數(shù)是要寫(xiě)入字符串?dāng)?shù)組的一個(gè)指針, 第二個(gè)參數(shù)是要每次寫(xiě)入的字節(jié)數(shù)這里是 1 , 相當(dāng)于 sizeof ( char )如果是整形的話就是 sizeof ( int ),第三個(gè)參數(shù)就是重復(fù)寫(xiě)入的次數(shù)。 第四個(gè)參數(shù)是文件流的指針。
這個(gè)時(shí)候我們打開(kāi)1.txt 的時(shí)候發(fā)現(xiàn)文件里沒(méi)有東西。關(guān)閉程序再打開(kāi) 1.txt 發(fā)現(xiàn)文件里有內(nèi)容了。這是因?yàn)榈谝淮螌?xiě)入的內(nèi)容還在緩沖里面沒(méi)有寫(xiě)入文件當(dāng)調(diào)用 fclose ( pFile )的時(shí)候可以寫(xiě)入文件。關(guān)閉程序也會(huì)關(guān)閉 pFile 流,所以第二次就有了內(nèi)容。
我們也可主動(dòng)調(diào)用 fclose( pFile ) 。
有的時(shí)候我們需要文件流保持, 需要用fflush ( pFile )這個(gè)函數(shù)把緩沖里的內(nèi)容刷新到文件里面。
所以調(diào)用 fflush( pFile ) ;也可以看到文件內(nèi)容。
2、 下面是從文件中讀入一個(gè)字符串。
char str[100];
char* filePath = "D:\\GL\\游戲 \\TEST\\1.txt";
FILE* pFile;
if( !(pFile = fopen(filePath, "r")) )
{
MessageBox("Open file fail!");
}
Str 是一個(gè)字符數(shù)組用來(lái)保存字符串。
fread(str, 3, 5, pFile);
MessageBox(str);
Fread函數(shù)的參數(shù)用法和 fwrite 差不錯(cuò)。
運(yùn)行程序時(shí)候發(fā)現(xiàn)彈出對(duì)話框會(huì) 出現(xiàn)亂碼
這個(gè)是因?yàn)樽址皇且?span style="line-height: 24px; font-family: 'Times New Roman'; ">'\0' 結(jié)尾的。
解決的方法之一是
用memset ()把 str 的數(shù)組全部賦予 0.
memset(str, 0, 100);
在fread 的前面加。這樣的話就可以保證末尾是 0 了
解決方法之二是
fseek(pFile, 0, SEEK_END);
long pos = ftell(pFile);
str[pos] = '\0';
rewind(pFile);
首先調(diào)用fseek 到文件的尾部, 然后調(diào)用 ftell 返回當(dāng)前位置。
然后在數(shù)組響應(yīng)的位置置0 ,最后返回文件頭部。
3、 下面討論文本文件和二進(jìn)制文件。
當(dāng)我們按照文本文件方式往文件中寫(xiě)入數(shù)據(jù)時(shí),一旦遇到換行字符(ASCII 10 ),則會(huì)轉(zhuǎn)為回車一換行( ASCII 為 13 、 10 )讀取文件時(shí)候, 一旦遇到回車一換行的組合(即連續(xù)的 ASCII 為 13 、 10 ), 則會(huì)轉(zhuǎn)換為字符( ASCII 10 )。
當(dāng)我們按照二進(jìn)制方式往文件中寫(xiě)入數(shù)據(jù)時(shí), 則將數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式原樣輸入到文件中。
4、 向文件寫(xiě)入一個(gè)大的整數(shù)。
例如向文件中寫(xiě)入一個(gè) 9876543
然后打開(kāi)文件顯示出來(lái)。
char ch[10];
int value = 986543;
FILE* pFile = fopen(filePath, "w");
itoa(value, ch, 10);
fwrite(ch, 1, 6, pFile);
fclose(pFile);
要以字符形式表現(xiàn)出來(lái)。
5、 用fstream 類來(lái)實(shí)現(xiàn)讀寫(xiě)
ofstream out("D:\\GL\\游戲 \\TEST\\1.txt");
out.write("zhao jie!", strlen("zhao jie!"));
out.close();
這是一個(gè)寫(xiě)入文件。Ofstream 有三個(gè)參數(shù), 后面的兩個(gè)有默認(rèn)值。
ifstream in("D:\\GL\\游戲 \\TEST\\1.txt");
char str[100];
memset(str, 0, 100);
in.read(str, 100);
這是從文件讀入一個(gè)文件, 和ofstream 一樣有是那個(gè)參數(shù),后面兩個(gè)是有默認(rèn)值的。
6、 下面是要講Win32 支持的文件讀寫(xiě)。
首先是寫(xiě)文件
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);
寫(xiě)入文件, 首先是創(chuàng)建一個(gè)句柄并且創(chuàng)建一個(gè)相應(yīng)的讀寫(xiě)模式。numberWrite 是用來(lái)存儲(chǔ)寫(xiě)入的字節(jié)數(shù)的。
讀文件
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);
首先創(chuàng)建一個(gè)字符串?dāng)?shù)組, 有一百個(gè)字節(jié),接著創(chuàng)建句柄。numberRead 是表示讀出來(lái)的字節(jié)數(shù)目。
最后關(guān)閉句柄。如果不關(guān)閉會(huì)照成資源泄漏。
7、 用CFile 類來(lái)文件讀寫(xiě)。
寫(xiě)入文件。
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 類創(chuàng)建一個(gè)對(duì)象。 The first parameter is a string that is the path to the desired file. The second parameter is access mod.
接著用類里面的兩個(gè)函數(shù)寫(xiě)入字符串, 并且關(guān)閉文件。
讀入文件
char str[100];
memset(str, 0, 100);
CFile read("D:\\GL\\游戲 \\TEST\\1.txt", CFile::modeRead);
read.Read(str, 100);
read.Close();
與寫(xiě)入相似, 固定字符串?dāng)?shù)組。
下面介紹一種動(dòng)態(tài)生成字符串?dāng)?shù)組的方法。
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 來(lái)得到文件的長(zhǎng)度。后來(lái)動(dòng)態(tài)的生成字符串?dāng)?shù)組。
8、 接下來(lái)需要用到的是CFileDialog 類用來(lái)打開(kāi) \ 保存文件。
打開(kāi)文件
CFileDialog fileDialog(FALSE);
fileDialog.m_ofn.lpstrTitle = "打開(kāi)文件 ";
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();
}
首先創(chuàng)建一個(gè)對(duì)象fileDialog 用于保存文件。這里的 FALSE 就是代表保存的意思。
lpstrTitle 表示保存對(duì)話框的 title
lpstrFilter 用于掩碼, 大選擇 *.txt 的時(shí)候 list 中只顯示 .txt 的文件。
后來(lái)調(diào)用CFile 文件寫(xiě)入文件字符串。 fileDialog.GetPathName() 用于返回文件的全路徑。
打開(kāi)文件
CFileDialog fileDialog(TRUE);
fileDialog.m_ofn.lpstrTitle = "存儲(chǔ)文件 ";
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;
}
和保存相似打開(kāi)一個(gè)文件并且讀出數(shù)據(jù)用Dialog 顯示。
9、 啟動(dòng)程序是我們經(jīng)常需要獨(dú)一些配置文件, 現(xiàn)在的程序是寫(xiě)入注冊(cè)表的。 以前的是 win.ini 文件。 可以用 WriteProfileString 這個(gè)函數(shù)來(lái)操作 .ini 的文件。具體見(jiàn) MSDN 。
讀寫(xiě)配置文件需要在文件剛開(kāi)始的初始化。
在CFileAPP 中的 initInstance 函數(shù)中調(diào)用:: WriteProfileString 函數(shù)來(lái)寫(xiě)入 win.ini 文件中。
E.g
::WriteProfileString("GL", "zoe", "I love you!");
第一個(gè)是根鍵。
相對(duì)應(yīng)的還有一個(gè)GetProfileString 函數(shù)用來(lái)從 win.in 文件中取得內(nèi)容。
CString str;
::GetProfileString("GL", "zoe", "my", str.GetBuffer(100), 100);
AfxMessageBox(str);
首先創(chuàng)建一個(gè)對(duì)象用來(lái)保存從win.ini 中讀取的字符串。
GetBuffer()這個(gè)是 CString 類中的一個(gè)函數(shù)用來(lái)自己操作字符串, 指向一個(gè)字符串?dāng)?shù)組。 100 是申請(qǐng)的長(zhǎng)度。
因?yàn)檫@是在winApp 類中, 不是繼承 CWND 的類, 所以不能直接用 MessageBox;
需要調(diào)用全局的AfxMessageBox ();來(lái)顯示讀取的數(shù)據(jù)。
10、 下面是MFC 中用來(lái)操作注冊(cè)表的讀寫(xiě)。
寫(xiě)入
CWinApp:: WriteProfileString("GL", "zoe", "I love you!");
這樣就寫(xiě)入了注冊(cè)表。那么我們寫(xiě)入的內(nèi)容在哪里呢??
首先到運(yùn)行中鍵入 regedit 打開(kāi)注冊(cè)表編輯器。
在HKEY_CURRENT_USER->SoftWare->Local AppWizard-Gen..... 中的響應(yīng)文件夾中找到 zoe 。
CString str;
str = GetProfileString("GL", "zoe", "my");
AfxMessageBox(str);
從注冊(cè)表中讀取數(shù)據(jù)。GetProfileString 是 CWinApp 類的返回字符串。
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
這個(gè)CWinApp 類中 SetRegistryKey 是用來(lái)在注冊(cè)表中注冊(cè)一個(gè)文件夾的, 這個(gè) application 中的注冊(cè)表的數(shù)據(jù)以后就存放在這個(gè)文件夾中。
自己來(lái)創(chuàng)建注冊(cè)表和編寫(xiě)注冊(cè)表。
寫(xiě)入注冊(cè)表。
HKEY key;
RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\GL\\zoe", &key);
RegSetValue(key, NULL, REG_SZ, "nothing", strlen("nothing"));
RegCloseKey(key);
HKEY是注冊(cè)表的句柄, 用 RegCreateKey 來(lái)創(chuàng)建一個(gè)注冊(cè)表文件夾。這個(gè)是在 HEY_LOCAL_MACHINE\SOFTWARE\GL\zoe 目錄下打開(kāi)或者創(chuàng)建。 Key 是返回的打開(kāi)或者創(chuàng)建的句柄。
RegSetValue是一個(gè)設(shè)置注冊(cè)表值的函數(shù)。 第一個(gè)參數(shù)是要設(shè)置的句柄。第二個(gè)是 zoe 下面的子 Key 要是為空的話,為默認(rèn)的 key , 第三個(gè)參數(shù)為注冊(cè)項(xiàng)的類型。 第四個(gè)為要賦值的值, 第五個(gè)是賦值的長(zhǎng)度。
讀取注冊(cè)表。
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;
這個(gè)是動(dòng)態(tài)生成字符串?dāng)?shù)組。 RegQueryValue 這個(gè)函數(shù)的第一個(gè)是句柄, 第二個(gè)參數(shù)是需要讀取的 Key ,第三個(gè)參數(shù)是字符存儲(chǔ)的內(nèi)存地址,當(dāng)為空的時(shí)候,返回第四個(gè)參數(shù)需要的容量。 下面動(dòng)態(tài)生成數(shù)組。
聯(lián)系客服