Win32 API、VC++、C# 文件操作函数的初步比较
一 C#
File.ReadAllText(FilePath) ;
一次將文本內(nèi)容全部讀完,
File.ReadAllLines;
該方法返回一個(gè)字符串?dāng)?shù)組。每一行都是一個(gè)數(shù)組元素。
string[] strs = File.ReadAllLines(@"c:\temp\ascii.txt");?
流
FileStream fs = new FileStream(@"C:\temp\utf-8.txt", FileMode.Open, FileAccess.Read, FileShare.None);?
StreamReader sr3 = new StreamReader(fs);?
StreamReader sr4 = new StreamReader(fs, Encoding.UTF8);
FileInfo myFile = new FileInfo(@"C:\temp\utf-8.txt");?
// OpenText 創(chuàng)建一個(gè)UTF-8 編碼的StreamReader對(duì)象?
StreamReader sr5 = myFile.OpenText();
// OpenText 創(chuàng)建一個(gè)UTF-8 編碼的StreamReader對(duì)象?
StreamReader sr6 = File.OpenText(@"C:\temp\utf-8.txt");
初始化完成之后,你可以每次讀一行,也可以每次讀一個(gè)字符 ,還可以每次讀幾個(gè)字符,甚至也可以一次將所有內(nèi)容讀完。
string nextLine = sr.ReadLine(); ? ?// 讀一行
int nextChar = sr.Read(); ? ?// 讀一個(gè)字符?
// 讀100個(gè)字符?
int nChars = 100;?
char[] charArray = new char[nChars];?
int nCharsRead = sr.Read(charArray, 0, nChars); ? ? ?
? ? ?
string restOfStream = sr.ReadToEnd(); ? ?// 全部讀完?
二 VC
? ? ? 文件的讀寫定位
定位文件中的數(shù)據(jù)是很重要的,這決定了寫入的數(shù)據(jù)在文件中的位置。
CFile類的文件數(shù)據(jù)定位函數(shù)有:
LONG Seek(LONG lOff,UINT nFrom);
throw(CFileException);
如果要求的位置合法,則Seek返回從文件開始起的新字節(jié)偏移量
lOff:指針移動(dòng)的字節(jié)數(shù)。
nFrom:指針移動(dòng)的模式??梢允荂File::begin,CFile::current,CFile::end
void SeekToBegin( );
DWORD SeekToEnd( );//返回文件長度(字節(jié)數(shù))。
讀取數(shù)據(jù):
CFile的成員函數(shù)有:
UINT Read (void* lpBuf,UINT nCount);
throw(CFileException);// 返回值是傳輸?shù)骄彌_區(qū)的字節(jié)數(shù)。
三 win32 api
? ? 設(shè)置文件指針setfilepointer
? ? 在對(duì)打開的文件進(jìn)行操作時(shí)需要知道當(dāng)前文件指針位置,是在文件開頭還是文件末尾還是在哪里,打開文件時(shí)文件指針默認(rèn)在文件開頭,如果不設(shè)置文件指針的話,下次寫入文件內(nèi)容就會(huì)覆蓋掉前面的;
DWORD WINAPI SetFilePointer(
①HANDLE hFile, //文件句柄
②LONG lDistanceToMove, //32位有符號(hào)long型,表示要移動(dòng)的位置(正數(shù)表示向后,負(fù)數(shù)表示向前)
③PLONG lpDistanceToMoveHigh, //
④DWORD dwMoveMethod //移動(dòng)模式
);
④dwMoveMethod 移動(dòng)模式
一共有三種移動(dòng)模式
FILE_BEGIN 從文件開始位置定位(此時(shí)參數(shù)②不能為負(fù))
FILE_CURRENT 從文件當(dāng)前位置向前或向后移動(dòng)指針(比如寫了一句話之后發(fā)現(xiàn)寫錯(cuò)了,可以將指針移動(dòng)至寫之前的位置,再次寫入)
FILE_END 從文件的末尾向前或向后定位指針
返回值:當(dāng)前所處位置距文件開頭的字符數(shù),可以借此查看當(dāng)前文件有多大
判斷文件長度GetFileSize
DWORD GetFileSize(
HANDLE hFile, //文件句柄
LPDWORD LPFileSizeHigh //指向高階雙字的文件大小的指針(此參數(shù)一般為NULL)
);
返回值:返回文件的大小
從文件中讀取數(shù)據(jù)ReadFile
BOOL ReadFile(
HANDLE hFile, //文件的句柄
LPVOID lpBuffer, //用于保存讀入數(shù)據(jù)的一個(gè)緩沖區(qū)
DWORD nNumberOfBytesToRead, //要讀入的字節(jié)數(shù)
LPDWORD lpNumberOfBytesRead, //指向?qū)嶋H讀取字節(jié)數(shù)的指針
LPOVERLAPPED lpOverlapped //如文件打開時(shí)指定了FILE_FLAG_OVERLAPPED,那么必須,用這個(gè)參數(shù)引用一個(gè)特殊的結(jié)構(gòu)。該結(jié)構(gòu)定義了一次異步讀取操作。否則,應(yīng)將這個(gè)參數(shù)設(shè)為NULL
);
四 基本差別
? ? C#的比較簡單易用;讀取全部內(nèi)容,讀取行,讀取多少個(gè)字符;不需要數(shù)據(jù)定位;
? ? VC和Win32 API需要數(shù)據(jù)定位,設(shè)置文件指針;
? ? VC和Win32 API可按字節(jié)數(shù)讀取;但VC的要好用些;Win32 API有更多的屬性控制;
? ? VC也可以按行讀取;Win32 API應(yīng)該是不能;
? ? 如果要直接用Win32 API按行讀取,需要自己逐字節(jié)判斷是否讀到回車換行符;
? ? VC和Win32 API可能數(shù)據(jù)類型還有些差別;VC指定字節(jié)數(shù)是UINT;win32 API指定字節(jié)數(shù)是DWORD;
五 Win32 API 讀文件示例程序
/*-------------------------------------------------
bobo, 2020.01.04
-------------------------------------------------*/#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{static TCHAR szAppName[] = TEXT("readFileDemo");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.style = CS_HREDRAW | CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = szAppName;if (!RegisterClass(&wndclass)){MessageBox(NULL, TEXT("Program requires Windows NT!"),szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindow(szAppName, TEXT("readFileDemo"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL, NULL, hInstance, NULL);ShowWindow(hwnd, iCmdShow);UpdateWindow(hwnd);while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;
}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{HDC hdc;int x, y;PAINTSTRUCT ps;RECT rect;char path[50]="";char buffer[100];unsigned long lpNumber = 0;switch (message){case WM_SIZE: return 0;case WM_RBUTTONDOWN: return 0;case WM_LBUTTONDOWN:hdc = GetDC(hwnd);//strcat(path, "1.txt");strcat_s(path, 50, "1.txt");HANDLE hFile = CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);if (hFile == INVALID_HANDLE_VALUE){MessageBox(NULL, "創(chuàng)建文件句柄出錯(cuò)", "error", MB_OK);}int filesucc = ReadFile(hFile,buffer,100,&lpNumber,NULL);CloseHandle(hFile);if (filesucc == 0){MessageBox(NULL, "讀取文件失敗", "error", MB_OK);}TextOut(hdc, 100, 100, buffer, 101);return 0;case WM_PAINT:hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);
}
讀取100個(gè)字節(jié);單擊鼠標(biāo)左鍵輸出;
讀取的文件放到源代碼文件同一目錄,否則 創(chuàng)建文件句柄失敗;
文件內(nèi)容;
使用strcat_s代替?zhèn)鹘y(tǒng)C的strcat;否則將出現(xiàn)C4996錯(cuò)誤;
C4996?? ?'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
?
總結(jié)
以上是生活随笔為你收集整理的Win32 API、VC++、C# 文件操作函数的初步比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用VC++2015 实现XP按钮效果
- 下一篇: 在一个解决方案中用C#测试调用C++ D