Win32 API、VC++、C# 文件操作函数的初步比较
一 C#
File.ReadAllText(FilePath) ;
一次將文本內容全部讀完,
File.ReadAllLines;
該方法返回一個字符串數組。每一行都是一個數組元素。
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 創建一個UTF-8 編碼的StreamReader對象?
StreamReader sr5 = myFile.OpenText();
// OpenText 創建一個UTF-8 編碼的StreamReader對象?
StreamReader sr6 = File.OpenText(@"C:\temp\utf-8.txt");
初始化完成之后,你可以每次讀一行,也可以每次讀一個字符 ,還可以每次讀幾個字符,甚至也可以一次將所有內容讀完。
string nextLine = sr.ReadLine(); ? ?// 讀一行
int nextChar = sr.Read(); ? ?// 讀一個字符?
// 讀100個字符?
int nChars = 100;?
char[] charArray = new char[nChars];?
int nCharsRead = sr.Read(charArray, 0, nChars); ? ? ?
? ? ?
string restOfStream = sr.ReadToEnd(); ? ?// 全部讀完?
二 VC
? ? ? 文件的讀寫定位
定位文件中的數據是很重要的,這決定了寫入的數據在文件中的位置。
CFile類的文件數據定位函數有:
LONG Seek(LONG lOff,UINT nFrom);
throw(CFileException);
如果要求的位置合法,則Seek返回從文件開始起的新字節偏移量
lOff:指針移動的字節數。
nFrom:指針移動的模式。可以是CFile::begin,CFile::current,CFile::end
void SeekToBegin( );
DWORD SeekToEnd( );//返回文件長度(字節數)。
讀取數據:
CFile的成員函數有:
UINT Read (void* lpBuf,UINT nCount);
throw(CFileException);// 返回值是傳輸到緩沖區的字節數。
三 win32 api
? ? 設置文件指針setfilepointer
? ? 在對打開的文件進行操作時需要知道當前文件指針位置,是在文件開頭還是文件末尾還是在哪里,打開文件時文件指針默認在文件開頭,如果不設置文件指針的話,下次寫入文件內容就會覆蓋掉前面的;
DWORD WINAPI SetFilePointer(
①HANDLE hFile, //文件句柄
②LONG lDistanceToMove, //32位有符號long型,表示要移動的位置(正數表示向后,負數表示向前)
③PLONG lpDistanceToMoveHigh, //
④DWORD dwMoveMethod //移動模式
);
④dwMoveMethod 移動模式
一共有三種移動模式
FILE_BEGIN 從文件開始位置定位(此時參數②不能為負)
FILE_CURRENT 從文件當前位置向前或向后移動指針(比如寫了一句話之后發現寫錯了,可以將指針移動至寫之前的位置,再次寫入)
FILE_END 從文件的末尾向前或向后定位指針
返回值:當前所處位置距文件開頭的字符數,可以借此查看當前文件有多大
判斷文件長度GetFileSize
DWORD GetFileSize(
HANDLE hFile, //文件句柄
LPDWORD LPFileSizeHigh //指向高階雙字的文件大小的指針(此參數一般為NULL)
);
返回值:返回文件的大小
從文件中讀取數據ReadFile
BOOL ReadFile(
HANDLE hFile, //文件的句柄
LPVOID lpBuffer, //用于保存讀入數據的一個緩沖區
DWORD nNumberOfBytesToRead, //要讀入的字節數
LPDWORD lpNumberOfBytesRead, //指向實際讀取字節數的指針
LPOVERLAPPED lpOverlapped //如文件打開時指定了FILE_FLAG_OVERLAPPED,那么必須,用這個參數引用一個特殊的結構。該結構定義了一次異步讀取操作。否則,應將這個參數設為NULL
);
四 基本差別
? ? C#的比較簡單易用;讀取全部內容,讀取行,讀取多少個字符;不需要數據定位;
? ? VC和Win32 API需要數據定位,設置文件指針;
? ? VC和Win32 API可按字節數讀取;但VC的要好用些;Win32 API有更多的屬性控制;
? ? VC也可以按行讀取;Win32 API應該是不能;
? ? 如果要直接用Win32 API按行讀取,需要自己逐字節判斷是否讀到回車換行符;
? ? VC和Win32 API可能數據類型還有些差別;VC指定字節數是UINT;win32 API指定字節數是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, "創建文件句柄出錯", "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個字節;單擊鼠標左鍵輸出;
讀取的文件放到源代碼文件同一目錄,否則 創建文件句柄失敗;
文件內容;
使用strcat_s代替傳統C的strcat;否則將出現C4996錯誤;
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.
?
總結
以上是生活随笔為你收集整理的Win32 API、VC++、C# 文件操作函数的初步比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用VC++2015 实现XP按钮效果
- 下一篇: 一些VC++ 系统类通用类