源码
//
// Created by oceanstar on 2021/8/9.
//
#ifndef OCEANSTAR_HTTP_ACL_FILE_H
#define OCEANSTAR_HTTP_ACL_FILE_H
#include <global.h>
#include "acl_vstream.h"
#define acl_off_t long long int
# define ACL_FILE_HANDLE int
namespace oceanstar{
class acl_file{
private:
ACL_FILE_HANDLE file_handle_;
explicit acl_file(ACL_FILE_HANDLE file_handle){
file_handle_ = file_handle;
}
public:
/**
* 打开文件句柄
* @param filepath {cosnt char*} 文件路径
* @param flags {int} 打开标志位, O_RDONLY | O_WRONLY | O_RDWR,
* O_CREAT | O_EXCL | O_TRUNC, O_APPEND(for UNIX)
* @param mode {int} 打开权限位, 仅对UNIX有效, 如:0700, 0755
* @return {ACL_FILE_HANDLE} 打开的文件句柄,返回 ACL_FILE_INVALID 表示打开失败
*/
static acl_file* acl_file_open(const char *filepath, int flags, int mode);
/**
* 关闭打开的文件句柄
* @return {int} 0: ok; -1: error
*/
int acl_file_close();
/**
* 定位文件位置
* @param fh {ACL_FILE_HANDLE} 文件句柄
* @param offset {acl_off_t} 偏移位置
* @param whence {int} 位置标志位:SEEK_CUR, SEEK_SET, SEEK_END
* @return {acl_off_t} 当前的文件偏移位置
*/
acl_off_t acl_lseek(acl_off_t offset, int whence);
/**
* 从文件中读数据
* @param fh {ACL_FILE_HANDLE} 文件句柄
* @param buf {void*} 存储缓冲区
* @param size {size_t} buf 缓冲区大小
* @param timeout {int} 读超时时间(秒)
* @param fp {ACL_VSTREAM*} 对应的文件流句柄, 可以为空
* @param arg {void*} 用户传递的参数, 以回调方式使用时此参数有效
* @return {int} 读到的实际数据, 如果返回 ACL_VSTREAM_EOF 表示读结束或出错
*/
int acl_file_read(void *buf, size_t size,
int timeout, ACL_VSTREAM *fp, void *arg);
/**
* 向文件中写数据
* @param fh {ACL_FILE_HANDLE} 文件句柄
* @param buf {void*} 数据存储缓冲区
* @param size {size_t} buf 缓冲区中数据长度大小
* @return {int} 成功写的数据量, 如果返回 ACL_VSTREAM_EOF 表示写出错
*/
int acl_file_write(const void *buf, size_t size);
int acl_file_lseek_begin(){
return lseek(file_handle_, 0, SEEK_SET);
}
/**
* 向文件中写一组数据
* @param fh {ACL_FILE_HANDLE} 文件句柄
* @param vec {const struct iovec*} 数据存储数组
* @param count {int} vec 数组中元素个数
* @return {int} 成功写的数据量, 如果返回 ACL_VSTREAM_EOF 表示写出错
*/
int acl_file_writev(const struct iovec *vec, int count);
/**
* 将文件缓冲区中的数据全部写入硬盘
* @return {int} 0: ok; -1: error
*/
int acl_file_fflush();
/**
* 根据文件名取得该文件的大小
* @param filename {const char*} 文件名
* @return {acl_int64} >= 0: ok; -1: error
*/
acl_int64 acl_file_size(const char *filename);
/**
* 根据文件句柄取得该文件的大小
* @return {acl_int64} >= 0: ok; -1: error
*/
acl_int64 acl_file_fsize();
};
}
#endif //OCEANSTAR_HTTP_ACL_FILE_H
//
// Created by oceanstar on 2021/8/9.
//
#include <fcntl.h>
#include <unistd.h>
#include "acl_file.h"
#include<sys/stat.h>
namespace oceanstar{
/**
* 打开文件句柄
* @param filepath {cosnt char*} 文件路径
* @param flags {int} 打开标志位, O_RDONLY | O_WRONLY | O_RDWR,
* O_CREAT | O_EXCL | O_TRUNC, O_APPEND(for UNIX)
* @param mode {int} 打开权限位, 仅对UNIX有效, 如:0700, 0755
* @return {acl_file *} 打开的文件句柄,返回 null 表示打开失败
*/
acl_file* acl_file::acl_file_open(const char *filepath, int flags, int mode){
const char *myname = "acl_file_open";
ACL_FILE_HANDLE handle = open(filepath, flags, mode);
if(handle == -1){
logger_error("%s, %s(%d): open file(%s) error(%s)",
myname, __FILE__, __LINE__,
filepath, strerror(errno));
return nullptr;
}
return new acl_file(handle);
}
int acl_file::acl_file_close(){
int ret = close(file_handle_);
delete this;
return ret;
}
acl_off_t acl_file::acl_lseek(acl_off_t offset, int whence){
return lseek64(file_handle_, offset, whence);
}
int acl_file::acl_file_read(void *buf, size_t size,
int timeout, ACL_VSTREAM *fp, void *arg){
if (fp != NULL && fp->get_read_ready()) {
fp->set_read_ready(0);
}
return (int) read(file_handle_, buf, size);
}
int acl_file::acl_file_write(const void *buf, size_t size){
return (int) write(file_handle_, buf, size);
}
int acl_file::acl_file_writev(const struct iovec *vec,
int count){
return (int) writev(file_handle_, vec, count);
}
int acl_file::acl_file_fflush(){
return fsync(file_handle_);
}
/**
* 根据文件名取得该文件的大小
* @param filename {const char*} 文件名
* @return {acl_int64} >= 0: ok; -1: error
*/
acl_int64 acl_file::acl_file_size(const char *filename){
struct stat sbuf;
if (stat(filename, &sbuf) == -1) {
return -1;
}
return sbuf.st_size;
}
/**
* 根据文件句柄取得该文件的大小
* @return {acl_int64} >= 0: ok; -1: error
*/
acl_int64 acl_file::acl_file_fsize(){
struct stat sbuf;
if (fstat(file_handle_, &sbuf) == -1) {
return -1;
}
return sbuf.st_size;
}
}
测试
#include "acl_file.h"
int main(void){
oceanstar::acl_file * fh = oceanstar::acl_file::acl_file_open("text.txt", O_CREAT | O_RDWR | O_APPEND, 0755);
if(fh == NULL){
printf("open text.txt error [%s]\n", strerror(errno));
exit(0);
}
printf("file_size = %lld\n", fh->acl_file_fsize());
int ret ;
char buf[1024];
memset(buf, 0, strlen(buf));
sprintf(buf, "hello client");
ret = fh->acl_file_write(buf, strlen(buf));
if(ret == ACL_VSTREAM_EOF){
printf("write to file error [%s]\n", strerror(errno));
fh->acl_file_close();
exit(0);
}
printf("write to file ok [%d]\n", ret);
memset(buf, 0, strlen(buf));
//记住,这里一定要重新打开或者lseek到开头,否则读不到数据【因为当前文件指针已经定位到了最末尾】
fh->acl_file_lseek_begin();
int ret1 = fh->acl_file_read(buf, sizeof(buf), 0, NULL, 0);
if (ret1 == ACL_VSTREAM_EOF) {
printf("read to file error [%s]\n", strerror(errno));
fh->acl_file_close();
exit(0);
}
buf[ret1] = 0;
printf("acl_file_read = [%d: %s]\n", ret1, buf);
fh->acl_file_close();
return 0;
}