刚刚接触win32 编程的时候,就被他的数据类型吓住的,和平时c++常用的变量不一样。
特别是win32 API羞涩难懂,只好硬着头皮去看。由于工作中,主要是处理文件,磁盘,逻辑磁盘
这些设备,主要开发是在windows下 只好用win32 的CreateFile WriteFile ReadFile 等函数去操作。
时间长了发现主要操作就是打开设备,读、写、跳转。好多代码都是重复的,最近把一些常用的操作,
进行了封装。写了几个类。JIO JFile JDisk JLogicalDisk.
JIO是一个借口,定义了几个常用的 功能,包含了基本的设备打开,读写操作。
interface JIO
{
public:
HANDLE hDevice;
public:
u64 filesize;
virtual u64 GetSize()= 0;
virtual void DoSomething(const char* buffer,size_t buffersize){}
virtual ~JIO()
{
CloseHandle(hDevice);
}
JIO()
{
filesize = 0;
}
virtual bool OpenA( const char* filename,bool newfile = false )//处理AsciI
{
DWORD type = 0;
if(newfile)
{
type = CREATE_ALWAYS;
}else
{
type = OPEN_EXISTING;
}
hDevice=CreateFileA(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE ,NULL,type,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE)return false;
GetSize();
return true;
}
bool SeekPos( u64 offset )
{
LARGE_INTEGER a1,a2;
a1.QuadPart = offset;
a2.QuadPart = 0;
BOOL ret = SetFilePointerEx(hDevice,a1,&a2,SEEK_SET);
return ret?true:false;
}
bool SeekPos(u64 offset,u64& realoffset)
{
LARGE_INTEGER a1,a2;
a1.QuadPart = offset;
a2.QuadPart = 0;
BOOL ret = SetFilePointerEx(hDevice,a1,&a2,SEEK_SET);
realoffset = a2.QuadPart;
return ret?true:false;
}
bool WriteData( char* data,size_t size,size_t& realsize )
{
DWORD rr = 0;
BOOL ret = WriteFile(hDevice,data,(DWORD)size,&rr,NULL);
realsize = rr;
return ret?true:false;
}
bool ReadData( char* data,size_t size,size_t& realsize )
{
DWORD rr ;
BOOL ret = ReadFile(hDevice,data,(DWORD)size,&rr,NULL);
realsize = rr;
//DWORD error = GetLastError();
return ret?true:false;
}
bool TellPosition( u64& pos )
{
LARGE_INTEGER a1,a2;
a1.QuadPart = 0;
a2.QuadPart = 0;
BOOL ret = SetFilePointerEx(hDevice,a1,&a2,SEEK_CUR);
pos = a2.QuadPart;
return ret?true:false;
}
virtual bool OpenW(const wchar_t* filename,bool newfile = false)//处理unicode
{
DWORD type = 0;
if(newfile)
{
type = CREATE_ALWAYS;
}else
{
type = OPEN_EXISTING;
}
hDevice=CreateFileW(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE ,NULL,type,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE)return false;
GetSize();
return true;
}
bool ReadRange(s64 beginset=0,s64 size=-1)
{
size==-1?filesize:size;
if(!SeekPos(beginset))return false;
u64 loop = size/BUFFERSIZE;
char* buffer = new char[BUFFERSIZE];
memset(buffer,0,BUFFERSIZE);
size_t rr;
for(u64 i=0;i<loop;i++)
{
if(!ReadData(buffer,BUFFERSIZE,rr))return false;
DoSomething(buffer,BUFFERSIZE);
}
size_t remain = size% BUFFERSIZE;
if(remain)
{
if(!ReadData(buffer,remain,rr))return false;
DoSomething(buffer,remain);
}
return true;
}
};
Getsize() 函数是一个虚函数,因为文件,磁盘,硬盘的获取大小的方式不一样,所以写了几个JIO的子类!
JFile类
class JFile:public JIO
{
public:
bool OpenA(const char* name,bool newfile = false)
{
return JIO::OpenA(name,newfile);
}
bool OpenW(const wchar_t* name,bool newfile = false)
{
return JIO::OpenW(name,newfile);
}
u64 GetSize()
{
LARGE_INTEGER rr;
rr.QuadPart = 0;
GetFileSizeEx(hDevice,&rr);
filesize = rr.QuadPart;
return filesize;
}
};
JLogicalDisk类
class JLogicalDisk:public JIO
{
public:
bool OpenA( const char* name)
{
return JIO::OpenA(name,false);
}
bool OpenW(const wchar_t* name)
{
return JIO::OpenW(name,false);
}
u64 GetSize()
{
GET_LENGTH_INFORMATION lpOutBuffer;
DWORD lpBytesReturned=0;
if(DeviceIoControl(
hDevice, // handle to device
IOCTL_DISK_GET_LENGTH_INFO , // dwIoControlCode
0, // lpInBuffer
0, // size of input buffer
&lpOutBuffer, // output buffer
sizeof(NTFS_VOLUME_DATA_BUFFER), // size of output buffer
&lpBytesReturned, // number of bytes returned
NULL // OVERLAPPED structure
))
{
filesize = (u64)lpOutBuffer.Length.QuadPart;
}
return filesize;
}
};
JDisk类
class JDisk:public JIO
{
public:
bool OpenA(const char* name)
{
return JIO::OpenA(name,false);
}
bool OpenW(const wchar_t* name)
{
return JIO::OpenW(name,false);
}
u64 GetSize()
{
DISK_GEOMETRY_EX info;
DWORD lpBytesReturned=0;
if(DeviceIoControl(
hDevice, // handle to volume
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID) &info, // output buffer
sizeof(DISK_GEOMETRY_EX), // size of output buffer
&lpBytesReturned, // number of bytes returned
NULL // OVERLAPPED structure
)){
filesize = info.DiskSize.QuadPart;
}
return filesize;
}
};
这几个类 主要是自己平时用,封装的也许不是太好,但是使用中没有出现问题,跟着我立下了不少汗马功劳。经过了考验。
使用方法:
char ch[1024];
size_t rr;
JFile file;
file.OpenA("data",flag);//flag 为真表示创建一个新的文件,为false打开一个存在的文件。
file.ReadData(ch,1024,rr);//读
file.WriteData(ch,1024,rr);//写
JDisk 等的用法和这个一样。
希望自己的代码对小伙伴们有帮助,如果有错误麻烦提醒下 谢谢