一段代码,演示Win32下超大文件读写
一段代码,演示在win32下读写4G以上的超大文件
上限为unsigned __int64,4G的平方字节
// **************************************************************************************************** // 文件: fs32demo\main.cpp // 作者: 虎胆游侠(blog.csdn.net/prsniper; cto@renshenguo.com) // 时间: 2015-12-30 06:02:11 // 注释: // Win32下超大文件读写演示程序, Demonstration for large file operation in win32 // **************************************************************************************************** #include <windows.h> #include <stdio.h> // FS是起初想做File Splitter, 将大文件分割, 虽然只有部分数据无意义, 但对于断点续传很关键 #define FS_ARG_COUNT 5 // 用GUID作为共享内存名称避免重复 #define FS_OPEN_NAME "Global\LargeFileOpen{E4FCF358-8BF8-4b59-A046-CCF85620AC36}" #define FS_SAVE_NAME "Global\LargeFileSave{E4FCF358-8BF8-4b59-A046-CCF85620AC36}" // 默认的文件参数(本机调试使用) #define FS_FILE_OPEN "F:\Win2003Ent.rar" #define FS_FILE_SAVE "F:\Win2003Ent.rar.bak" #define FS_FILE_SIZE 8316302716 #define FS_FILE_BYTE 0x10000000 // 256 MB (268435456) // 进程退出代码 #define FS_ERROR_SUCCESS 0 #define FS_ERROR_OPEN_FILE 1 #define FS_ERROR_OPEN_MAPPING 2 #define FS_ERROR_MULTI_OPEN 3 #define FS_ERROR_SAVE_FILE 4 #define FS_ERROR_SAVE_MAPPING 5 #define FS_ERROR_MULTI_SAVE 6 #define FS_ERROR_VIEW_OPEN 7 #define FS_ERROR_VIEW_SAVE 8 #define FS_ERROR_CLOSE_FILE 9 // 类型定义 typedef unsigned __int64 QWORD; typedef struct tagLargeFile{ HANDLE File; HANDLE Mapping; LPBYTE Buffer; union { struct { DWORD Bit32; DWORD Bit64; }; QWORD Offset; QWORD Length; }; } LARGEFILE, *PLARGEFILE; // 入口函数, 用法: fs32demo[.exe][ inputfile outputfile filesize cachesize] int main(int argc, char **argv) { LARGEFILE lfOpen; LARGEFILE lfSave; char *szOpen; char *szSave; //QWORD nLength; // use lfSave.Length DWORD dwSize; union { struct { DWORD dwSizeLow; DWORD dwSizeHigh; }; QWORD nSize; // temp var }; BOOL dwRet; if(argc == FS_ARG_COUNT) { // 处理运行参数, 自动过滤引号: argv[0] == ...\fs32demo.exe szOpen = argv[1]; szSave = argv[2]; lfSave.Length = _atoi64(argv[3]); // 文件大小 dwSize = atoi(argv[4]); // 不应超过2GB, 且小于文件大小 }else { szOpen = FS_FILE_OPEN; szSave = FS_FILE_SAVE; lfSave.Length = FS_FILE_SIZE; dwSize = FS_FILE_BYTE; } // 输出参数信息 printf(" Input file: %s ", szOpen); printf("Output file: %s ", szSave); printf(" File size: 0x%I64X (%I64d bytes) ", lfSave.Length, lfSave.Length); printf(" Cache size: 0x%08X (%d bytes) ", dwSize, dwSize); printf("Press any key to fuck: "); getchar(); // 任意键继续 lfOpen.File = CreateFile(szOpen, // file to fuck with GENERIC_READ, // 只读打开 FILE_SHARE_READ, // 共享读取 NULL, // &sa(默认不能继承) OPEN_EXISTING, // CREATE_ALWAYS FILE_ATTRIBUTE_NORMAL, NULL); if(lfOpen.File == INVALID_HANDLE_VALUE) { return FS_ERROR_OPEN_FILE; } lfOpen.Mapping = CreateFileMapping(lfOpen.File, NULL, // &sa PAGE_READONLY, // 只读共享内存 0, // 高双字 0, // 低双字, 自动使用文件大小 FS_OPEN_NAME); if(lfOpen.Mapping == NULL) { CloseHandle(lfOpen.File); // system holds the corresponding file open until the last view of the file is unmapped. //lfOpen.File = NULL; return FS_ERROR_OPEN_MAPPING; } if(GetLastError() == ERROR_ALREADY_EXISTS) { // FS_ERROR_MULTI_OPEN, Proceed.. } lfSave.File = CreateFile(szSave, // file to fuck with GENERIC_READ | GENERIC_WRITE, // 读写打开 FILE_SHARE_READ, // 共享读取(不共享写入) NULL, // &sa(默认不能继承) CREATE_ALWAYS, // OPEN_EXISTING FILE_ATTRIBUTE_NORMAL, NULL); if(lfSave.File == INVALID_HANDLE_VALUE) { CloseHandle(lfOpen.Mapping); CloseHandle(lfOpen.File); return FS_ERROR_SAVE_FILE; } //lfSave.Offset = lfSave.Length; lfSave.Mapping = CreateFileMapping(lfSave.File, NULL, // &sa PAGE_READWRITE, // 读写共享内存 lfSave.Bit64, // 高双字 lfSave.Bit32, // 低双字 FS_SAVE_NAME); if(lfSave.Mapping == NULL) { CloseHandle(lfSave.File); CloseHandle(lfOpen.Mapping); CloseHandle(lfOpen.File); return FS_ERROR_SAVE_MAPPING; } if(GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(lfSave.Mapping); CloseHandle(lfSave.File); CloseHandle(lfOpen.Mapping); CloseHandle(lfOpen.File); return FS_ERROR_MULTI_SAVE; } dwRet = FS_ERROR_SUCCESS; // 默认成功 lfOpen.Offset = 0; while(lfOpen.Offset < lfSave.Length) { nSize = lfSave.Length - lfOpen.Offset; if(nSize > dwSize) { nSize = dwSize; } // 映射 lfOpen.Buffer = (LPBYTE)MapViewOfFile(lfOpen.Mapping, FILE_MAP_READ, lfOpen.Bit64, lfOpen.Bit32, dwSizeLow); if(lfOpen.Buffer == NULL) { dwRet = FS_ERROR_VIEW_OPEN; break; } lfSave.Buffer = (LPBYTE)MapViewOfFile(lfSave.Mapping, FILE_MAP_ALL_ACCESS, lfOpen.Bit64, lfOpen.Bit32, dwSizeLow); if(lfOpen.Buffer == NULL) { UnmapViewOfFile(lfSave.Buffer); dwRet = FS_ERROR_VIEW_SAVE; break; } // memcpy & unmap printf("Offset: 0x%I64X, Size: 0x%08X; (%d bytes from %I64d) ", lfOpen.Offset, dwSizeLow, dwSizeLow, lfOpen.Offset); CopyMemory(lfSave.Buffer, lfOpen.Buffer, dwSizeLow); UnmapViewOfFile(lfSave.Buffer); UnmapViewOfFile(lfOpen.Buffer); // next lfOpen.Offset += FS_FILE_BYTE; } CloseHandle(lfSave.Mapping); CloseHandle(lfSave.File); CloseHandle(lfOpen.Mapping); if(CloseHandle(lfOpen.File) == FALSE) { return FS_ERROR_CLOSE_FILE; // ... } return dwRet; }
VC工程源码下载地址:
CSDN:
http://download.csdn.net/detail/prsniper/9384068
百度云盘 http://pan.baidu.com/s/1qXkGPcS
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。