win32 CreateFile readFile writefile 文件读写
来源:互联网 发布:世界地图矢量数据 编辑:程序博客网 时间:2024/05/20 02:27
之前在Java、和在Linux都使用过文件的读与写。其实不管是什么平台不外乎就是获取文件句柄,通过文件句柄进行读写,然后关闭句柄。就是这么简单,那么WIN32下是怎么样获取文件句柄呢?
查看API就有一个createFile()函数,原型如下:
HANDLE CreateFile(
LPCTSTR lpFileName, // 要打开的文件名
DWORD dwDesiredAccess, // 文件的操作属性
DWORD dwShareMode, // 文件共享属性
LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性
DWORD dwCreationDisposition, //文件操作
DWORD dwFlagsAndAttributes, // 文件属性
HANDLE hTemplateFile // 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性
);
借鉴与网络资料和书籍
文件的操作属性:如果为零,表示只允许获取与一个设备有关的信息,GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);
文件的共享属性:零表示不共享; FILE_SHARE_READ 或 FILE_SHARE_WRITE 表示允许对文件进行读/写共享访问;
文件的操作有:
·CREATE_NEW:创建文件;如文件存在则会出错
·CREATE_ALWAYS:创建文件,会改写前一个文件
·OPEN_EXISTING:文件必须已经存在。由设备提出要求
·OPEN_ALWAYS:如文件不存在则创建它
·TRUNCATE_EXISTING:将现有文件缩短为零长度
文件属性有:
·FILE_ATTRIBUTE_ARCHIVE:标记归档属性
·FILE_ATTRIBUTE_COMPRESSED:将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
·FILE_ATTRIBUTE_NORMAL:默认属性
·FILE_ATTRIBUTE_HIDDEN:隐藏文件或目录
·FILE_ATTRIBUTE_READONLY:文件为只读
·FILE_ATTRIBUTE_SYSTEM:文件为系统文件
·FILE_FLAG_WRITE_THROUGH:
操作系统不得推迟对文件的写操作
·FILE_FLAG_OVERLAPPED:允许对文件进行重叠操作
·FILE_FLAG_NO_BUFFERING:禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
·FILE_FLAG_RANDOM_ACCESS:针对随机访问对文件缓冲进行优化
·FILE_FLAG_SEQUENTIAL_SCAN:针对连续访问对文件缓冲进行优化
·FILE_FLAG_DELETE_ON_CLOSE:关闭了上一次打开的句柄后,将文件删除。特别适合临时文件
可以组合的属性有:FILE_FLAG_WRITE_THROUGH,FILE_FLAG_OVERLAPPED,FILE_FLAG_NO_BUFFERING,FILE_FLAG_RANDOM_ACCESS,FILE_FLAG_SEQUENTIAL_SCAN,FILE_FLAG_DELETE_ON_CLOSE,FILE_FLAG_BACKUP_SEMANTICS,FILE_FLAG_POSIX_SEMANTICS,FILE_FLAG_OPEN_REPARSE_POINT,FILE_FLAG_OPEN_NO_RECALL
如果成功返回一个打开文件得句柄,如果调用函数之前文件存在,文件操作属性为:CREATE_ALWAYS 或 OPEN_ALWAYS,使用GetLastError函数返回的是ERROR_ALREADY_EXISTS(包括函数操作成功),如果之前函数不存在,则返回0。使用失败返回INVALID_HANDLE_VALUE,要取得更多的信息,使用GetLastError函数。
文件关闭用:
BOOL CloseHandle(HANDLE hObject // handle to object to close);
这些参数什么的真的太多了,具体不同需要还是要去认真看,这里不多介绍网上也很多这种资料。
这里要实现一个断点续传功能,也就是要在自己操控文件指针,指到断点位置,然后继续往下写或者读。
使用到函数WORD dwPtr = SetFilePointer(m_mFileHandle, Offset, NULL, FILE_BEGIN);
m_mFileHandle, 为你的文件句柄
Offset:文件指针位置。就是你上一次读取的位置。
代码如下
/*********************************************************** * Name:DataTypeDefine.h * Purpose: Define Data struct * Author: zzf * Created: 2016/03/21 * Copyright: ut ************************************************************/#ifndef H_DATA_TYPE_DEFINE_H#define H_DATA_TYPE_DEFINE_H#define DEBUG_TYPE //调试宏定义#include <string>#include <Windows.h>using namespace std;typedef signed long long TSint64;typedef unsigned long longTUint64; struct S_TTransferTaskInfo{int m_nTaskType; // 0:上传,1:下载string m_strTaskID; // 传输任务IDstring m_strPath; // 如果是上传,则是文件的全路径,如果是下载,是文件的存放路径string m_strFileName; // 文件名string m_strUrl; // Url地址,上传时指远程的路径,下载时指下载文件的全路径TUint64 m_ulTotalSize; // 上传或者下载文件总长度TUint64 m_ulCurSize; // 上传,指已经上传成功的长度,下载,指已经下载的实际长度string m_strOriginalMD5; // 原始文件MD5S_TTransferTaskInfo(){m_nTaskType = 0;m_ulTotalSize = 0;m_ulCurSize = 0; m_strTaskID = "TaskID";}};typedef enum NsResultEnum{RESULT_OK = 0,// 成功RESULT_UPLOAD_FAILED, // 上传失败RESULT_DOWNLOAD_FAILED // 下载失败};enum ETASK_WORK_TYPE{ UPLOAD_TYPE = 0, DOWNLOAD_TYPE = 1};typedef void (*TaskExecuteCallBackFun)(HANDLE phandle,S_TTransferTaskInfo mTransferTaskInfo);typedef size_t (*OnWriteDataCallBackFun)(HANDLE phandle,void* buffer, size_t size, size_t nmemb, void* lpVoid);#endif
/*********************************************************** * Name:CIniConfigfileManager.h * Purpose: int file manager * Author: zzf * Created: 2016/04/18 * Copyright: ut ************************************************************/#ifndef H_CINICONFIGFILEMANAGER_H#define H_CINICONFIGFILEMANAGER_H#include "iconfigfile.h"#include "DataTypeDefine.h"#include <iostream>#include <vector>#include <stdio.h>using namespace std;class CIniConfigfileManager : public IConfigFile{public: CIniConfigfileManager(string sFilePath); ~CIniConfigfileManager(void); //************************************************************// 函数名称: AddRecord,向配置文件追加一条记录// 参 数: S_TTransferTaskInfo,待追加的记录信息// 返回值: bool,成功返回true,失败返回false// 权 限: public //************************************************************virtual bool AddRecord(const S_TTransferTaskInfo sTaskInfo); // 函数名称: UpdateRecord ,更新配置文件中的一条记录// 参 数: S_TTransferTaskInfo,待追加的记录信息// 返回值: bool,成功返回true,失败返回false// 权 限: public //************************************************************virtual bool UpdateRecord (const S_TTransferTaskInfo sTaskInfo); // 函数名称: DeleteRecord ,删除配置文件中指定的一条记录// 参 数: szTaskID,待删除的记录ID// 返回值: bool,成功返回true,失败返回false// 权 限: public //************************************************************virtual bool DeleteRecord (const string szTaskID); // 函数名称: GetPath ,获取设置的本地路径 // 返回值: 本地路径// 权 限: public //************************************************************virtual string GetPath (); // 函数名称: GeAlltRecords ,获取配置文件中该用户名下所有的记录信息 // 参 数: szUserName 当前登陆用户名 // 返回值: 所有该用户名下的未完成任务信息存储容器 // 权 限: public //************************************************************ virtual std::vector<S_TTransferTaskInfo> GeAlltRecords(const string szUserName); // 函数名称: GetRecord ,获取配置文件中指定的某条记录 // 参 数: szTaskID 记录ID // 返回值: 记录信息 // 权 限: public //************************************************************ virtual S_TTransferTaskInfo GetRecord(const string szTaskID);protected: private: string m_sFilePath;};#endif
#include "CFilecontrolManage.h"#include <iostream>#include "CPublicTools.h"using namespace std;const unsigned long ONCE_TIME_TO_READ_NUMBER = 1024;CFilecontrolManage::CFilecontrolManage(void){}CFilecontrolManage::~CFilecontrolManage(void){}//************************************************************// 函数名称: OpenFile,打开文件// 参 数: string url 路径// 返回值: EFILE_STATE 返回状态// 权 限: public //************************************************************EFILE_STATE CFilecontrolManage::OpenFile(std::string url ,ETASK_WORK_TYPE state){ m_sFileUrl = url; if ( state == UPLOAD_TYPE ) { CreateReadFile(url); } else { CreateWriteFile(url); } if ( m_mFileHandle == NULL ) { return OPEN_FILE_FAILE; } return OPEN_FILE_SUCCESS;}//************************************************************// 函数名称: CloseFile,关闭文件// 参 数: void// 返回值: void// 权 限: public //************************************************************void CFilecontrolManage::CloseFile(){ if ( m_mFileHandle != NULL ) { CloseHandle(m_mFileHandle); } }//************************************************************// 函数名称: CreateReadFile,获取读文件句柄// 参 数: void// 返回值: void// 权 限: public //************************************************************void CFilecontrolManage::CreateReadFile(std::string url){ if ( m_mFileHandle!=NULL) { CloseHandle(m_mFileHandle); } LPCWSTR L_url = CPublicTools::getPublicToolsInstance().OnstringToLPCWSTR(url); m_mFileHandle = ::CreateFile(L_url, GENERIC_READ , FILE_SHARE_READ , //文件打开之后就不能再打开 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); #ifdef DEBUG_TYPE if (m_mFileHandle != INVALID_HANDLE_VALUE) { cout<<"获得读文件句柄成功!"<<endl; }else { int ret = GetLastError(); cout<<"获得读文件句柄失败! errID = "<<ret<<endl; }#endif }//************************************************************// 函数名称: CreateWriteFile,获取写文件句柄// 参 数: void// 返回值: void// 权 限: public //************************************************************void CFilecontrolManage::CreateWriteFile(std::string url){ LPCWSTR L_url = CPublicTools::getPublicToolsInstance().OnstringToLPCWSTR(url);; m_mFileHandle = CreateFile(L_url, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS|CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );}//************************************************************// 函数名称: Test,测试专用// 参 数: void// 返回值: void// 权 限: public //************************************************************void CFilecontrolManage::Test(std::string fileName){ m_TestFileName = fileName;}//************************************************************// 函数名称: ReadFile,读取文件// 参 数: void// 返回值: void// 权 限: public //************************************************************DWORD CFilecontrolManage::OnReadFile(LPVOID Readbuff,DWORD Offset,DWORD needToRead){ DWORD BytesRead = 0; WORD dwPtr = SetFilePointer(m_mFileHandle, Offset, NULL, FILE_BEGIN); if (dwPtr == INVALID_SET_FILE_POINTER) { //获取出错码。 DWORD dwError = GetLastError() ; //处理出错。 } BOOL readRet = ::ReadFile( m_mFileHandle, // handle to file Readbuff, // data buffer needToRead, // number of bytes to read &BytesRead, // number of bytes read NULL // overlapped buffer );#ifdef DEBUG_TYPE if (readRet) { cout << "CFilecontrolManage::OnReadFile 读文件操作失败 "<<BytesRead<<" Offset = "<<Offset<< endl; }else { //获取出错码。 DWORD dwError = GetLastError(); //处理出错。 TCHAR chErrorBuf[1024]; // wsprintf(chErrorBuf,"GetLastError()=%d\r\n",dwError); // OutputDebugString(chErrorBuf); } cout << "CFilecontrolManage::OnReadFile BytesRead = "<<BytesRead<<" Offset = "<<Offset<< endl;#endif return BytesRead;}//************************************************************// 函数名称: WriteFile,写入文件// 参 数: void// 返回值: void// 权 限: public //************************************************************DWORD CFilecontrolManage::OnWriteFile(LPVOID writeBuff,DWORD Offset,DWORD needToWrite){ string url = "F:/Test/write/"+m_TestFileName+".rar"; LPCWSTR L_url = CPublicTools::getPublicToolsInstance().OnstringToLPCWSTR(url); HANDLE mFileHandle = CreateFile(L_url, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,// FILE_FLAG_OVERLAPPED, NULL ); ///////////////////////////test WORD dwPtr = SetFilePointer(mFileHandle, Offset, NULL, FILE_BEGIN); DWORD BytesWritten = 0; BOOL writeRet = ::WriteFile( mFileHandle, // HANDLE hFile, writeBuff, //(nNumberOfBytesToWrite) LPCVOID lpBuffer, needToWrite, //DWORD nNumberOfBytesToWrite, &BytesWritten, //LPDWORD lpNumberOfBytesWritten, NULL // LPOVERLAPPED lpOverlapped ); CloseHandle(mFileHandle);#ifdef DEBUG_TYPE if (writeRet) { cout << "CFilecontrolManage::OnReadFile 写文件操作失败 "<<BytesWritten<<" Offset = "<<Offset<< endl; }else { cout << "CFilecontrolManage::OnWriteFile BytesRead = "<<BytesWritten<<" needToWrite = "<<needToWrite<<" Offset = "<<Offset<< endl; } #endif return BytesWritten;}
这里是一个执行线程,因为上传和下载都是使用不同业务,获取的文件句柄不同。比如上传肯定是获取读的句柄,下载那就是写。使用这里把CreateReadFile、CreateWriteFile分开来了。
- win32 CreateFile readFile writefile 文件读写
- <Win32 API> 文件操作CreateFile/ReadFile/WriteFile
- CreateFile ReadFile WriteFile读写文件操作
- [Win32]ReadFile/WriteFile 的文件同步读写
- CreateFile ReadFile WriteFile 详解
- CreateFile ReadFile WriteFile 详解
- CreateFile、WriteFile、ReadFile
- 使用API进行文件读写——CreateFile,ReadFile,WriteFile等
- CreateFile、ReadFile、WriteFile和fread、fwrite两种读写文件的方法
- C/C++ 文件操作之CreateFile、ReadFile和WriteFile
- C/C++ 文件操作之CreateFile、ReadFile和WriteFile
- CreateFile,ReadFile,WriteFile,DeviceIoControl,CloseHandle
- CreateFile,ReadFile,WriteFile,DeviceIoControl,CloseHandle .
- CreateFile,ReadFile,WriteFile使用记录
- 读写文件函数ReadFile和WriteFile解析
- CreateFile WriteFile ReadFile FlushFileBuffers的基本用法
- Windows API应用:CreateFile,WriteFile,ReadFile
- 使用CreateFile, ReadFile, WriteFile在Windows NT/2000/XP下读写绝对扇区的方法
- 什么是DES安全算法
- Redis+Spring缓存实例(windows环境,附实例源码及详解)
- 【数据结构】链表的原理及java实现
- Android 开发中广播Broadcast 知识点
- Loadrunner增加对于Linux服务器负载以及CPU使用情况的监控
- win32 CreateFile readFile writefile 文件读写
- 注解初体验与自定义注解实战
- struct、union
- 《疯狂Java讲义(第3版)》.(李刚)——前言
- 对于酷派手机无法打印log问题解决方法
- Timus 1820. Ural Steaks
- java从本地向另外一个地址发送请求
- IntentService
- 杭电5645