使用AIO读写文件
编译时需连接以下动态库
LIBS += /usr/lib/x86_64-linux-gnu/librt.so
LIBS += -lpthread
#ifndef CAIO_H
#define CAIO_H
#include <string>
#include <aio.h>
#include <stdio.h>
#include <unistd.h>
#include <aio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
enum eAIOState
{
eBusyState,
eReadyState
};
typedef void (*FucCallBackAIO)(sigval_t);
class CAIO
{
public:
CAIO();
~CAIO();
bool Open(string strName, int nMode);
bool Close();
int Write(const char* buf, int nSize, bool bAppend, eAIOState& eIOState);
int Read(char* buf );
void SetCallbackFuc(FucCallBackAIO fAIO);
int GetFileSize(const char *szFileName);
void Seek(int offset, int __whence);
int Write(const char* buf, int nSize);;
int GetFD();
private:
struct aiocb m_aiocb;
int m_fdFile;
string m_strFilename;
int m_nFileSize;
};
#endif // CAIO_H
#include <fcntl.h>
#include <sys/stat.h>
#include "caio.h"
using namespace std;
CAIO::CAIO()
{
m_fdFile =-1;
m_nFileSize=0;
}
CAIO::~CAIO()
{
}
int CAIO::GetFileSize(const char *szFileName)
{
int nSize=0;
struct stat buffer;
int status;
status = stat(szFileName, &buffer);
if(status>=0)
{
nSize=buffer.st_size;
}
return nSize;
}
bool CAIO::Open(string strName, int nMode)
{
m_fdFile = open(strName.c_str(), nMode);
if(m_fdFile < 0)
{
printf("Open %s failed\n", strName.c_str());
return false;
}
bzero((void*) &m_aiocb, sizeof(struct aiocb));
m_aiocb.aio_fildes = m_fdFile;
m_aiocb.aio_offset =0;
m_nFileSize= GetFileSize(strName.c_str());
m_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;
// 指定回调函数
m_aiocb.aio_sigevent._sigev_un._sigev_thread._attribute = NULL;
// 指定AIO请求
return true;
}
void CAIO::SetCallbackFuc(FucCallBackAIO fAIO)
{
m_aiocb.aio_sigevent._sigev_un._sigev_thread._function =fAIO;
m_aiocb.aio_sigevent.sigev_value.sival_ptr = &m_aiocb;
}
int CAIO::Write(const char* buf, int nSize, bool bAppend, eAIOState& eIOState)
{
m_aiocb.aio_nbytes = nSize;
m_aiocb.aio_buf=(void*)buf;
m_aiocb.aio_offset=0;
m_aiocb.aio_offset+=m_nFileSize;
if(!bAppend)
m_aiocb.aio_offset = 0;
// 发送异步读请求
int ret;
if(eReadyState == eIOState)
{
ret = aio_write(&m_aiocb);
if (ret < 0)
sleep(1);
m_nFileSize +=nSize;
eIOState = eBusyState;
}
return ret;
}
void CAIO::Seek(int offset, int __whence)
{
lseek(m_fdFile, offset, SEEK_SET);
}
int CAIO::Write(const char* buf, int nSize)
{
write(m_fdFile,buf,nSize);
}
int CAIO::GetFD()
{
return m_fdFile;
}
bool CAIO::Close()
{
if (close(m_fdFile) < 0)
{
return false;
}
return true;
}
#include <fcntl.h>
#include <aio.h>
#include "caio.h"
#include <iostream>
using namespace std;
void msleep( unsigned int ms )
{
int microsecs;
struct timeval tv;
microsecs = ms * 1000;
tv.tv_sec = microsecs / 1000000;
tv.tv_usec = microsecs % 1000000;
select( 0, NULL, NULL, NULL, &tv );
}
eAIOState g_eIOState;
void aio_completion_handler( sigval_t sigval )
{
int ret;
struct aiocb *tAiocb;
// 获取aiocb结构体指针
tAiocb = (struct aiocb *)sigval.sival_ptr;
// 获取异步读请求的返回值
if ((ret = aio_return(tAiocb)) > 0)
{
// 获取并输出读取的数据
printf("value:%s\n", (char*) (tAiocb->aio_buf));
g_eIOState = eReadyState;
}
}
#define BUFFER_SIZE 100
// AIO回调函数
int main()
{
CAIO aio;
bool bOpen= aio.Open("/media/sda1/Videos/20151221/1/155332.mp4",O_WRONLY);
aio.SetCallbackFuc(aio_completion_handler);
if(false == bOpen)
return 1;
string strData="yes tes";
g_eIOState = eReadyState;
for(int i=0 ; i < 10; )
{
if(eReadyState==g_eIOState )
{
aio.Write(strData.c_str(), strData.length(), true, g_eIOState);
i++;
}
msleep(100);
}
aio.Seek(4, 0);
strData="fffff";
msleep(1000);
aio.Write(strData.c_str(), strData.length());
aio.Close();
return 0;
}