一段代码,演示在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\r\n", szOpen);
printf("Output file: %s\r\n", szSave);
printf(" File size: 0x%I64X (%I64d bytes)\r\n", lfSave.Length, lfSave.Length);
printf(" Cache size: 0x%08X (%d bytes)\r\n", dwSize, dwSize);
printf("Press any key to fuck: \r\n");
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)\r\n", 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