一段代码,演示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\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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值