muduo库源码学习(base)FileUtil
来源:互联网 发布:mac能用qq旋风吗 编辑:程序博客网 时间:2024/06/05 23:44
class ReadSmallFile : boost::noncopyable{ public: ReadSmallFile(StringArg filename); ~ReadSmallFile(); // return errno template<typename String> int readToString(int maxSize,//最大的长度 String* content,//dest int64_t* fileSize,//文件大小 int64_t* modifyTime,//修改大小 int64_t* createTime); //创建时间 /// Read at maxium kBufferSize into buf_ // return errno int readToBuffer(int* size); const char* buffer() const { return buf_; } static const int kBufferSize = 64*1024; private: int fd_; int err_; char buf_[kBufferSize];};// read the file content, returns errno if error happens.template<typename String>int readFile(StringArg filename,//读取文件,是对ReadSmallFile的一个包装。 int maxSize, String* content, int64_t* fileSize = NULL, int64_t* modifyTime = NULL, int64_t* createTime = NULL){ ReadSmallFile file(filename); return file.readToString(maxSize, content, fileSize, modifyTime, createTime);}// not thread safeclass AppendFile : boost::noncopyable{ public: explicit AppendFile(StringArg filename); ~AppendFile(); void append(const char* logline, const size_t len); void flush(); size_t writtenBytes() const { return writtenBytes_; } private: size_t write(const char* logline, size_t len); FILE* fp_; char buffer_[64*1024]; size_t writtenBytes_;};
FileUtil::AppendFile::AppendFile(StringArg filename) : fp_(::fopen(filename.c_str(), "ae")), // 'e' for O_CLOEXEC//这里用了fopen writtenBytes_(0){ assert(fp_); ::setbuffer(fp_, buffer_, sizeof buffer_);//设置缓冲区 // posix_fadvise POSIX_FADV_DONTNEED ?}FileUtil::AppendFile::~AppendFile(){ ::fclose(fp_);}void FileUtil::AppendFile::append(const char* logline, const size_t len){ size_t n = write(logline, len);//调用fwrite size_t remain = len - n; while (remain > 0) { size_t x = write(logline + n, remain); if (x == 0) { int err = ferror(fp_); if (err) { fprintf(stderr, "AppendFile::append() failed %s\n", strerror_tl(err)); } break; } n += x; remain = len - n; // remain -= x } writtenBytes_ += len;}void FileUtil::AppendFile::flush()//立刻刷新{ ::fflush(fp_);}size_t FileUtil::AppendFile::write(const char* logline, size_t len){ // #undef fwrite_unlocked return ::fwrite_unlocked(logline, 1, len, fp_);}FileUtil::ReadSmallFile::ReadSmallFile(StringArg filename) : fd_(::open(filename.c_str(), O_RDONLY | O_CLOEXEC)),//构造函数打开文件 err_(0){ buf_[0] = '\0'; if (fd_ < 0) { err_ = errno; }}FileUtil::ReadSmallFile::~ReadSmallFile(){ if (fd_ >= 0)//文件描述符有效则关闭 { ::close(fd_); // FIXME: check EINTR }}// return errnotemplate<typename String>int FileUtil::ReadSmallFile::readToString(int maxSize,//将文件读到content String* content, int64_t* fileSize, int64_t* modifyTime, int64_t* createTime){ BOOST_STATIC_ASSERT(sizeof(off_t) == 8); assert(content != NULL); int err = err_; if (fd_ >= 0) { content->clear(); if (fileSize)//那为什么content就不检查呢? { struct stat statbuf;//获取文件信息 if (::fstat(fd_, &statbuf) == 0) { if (S_ISREG(statbuf.st_mode))//是文件 { *fileSize = statbuf.st_size;//文件大小 content->reserve(static_cast<int>(std::min(implicit_cast<int64_t>(maxSize), *fileSize)));//预留大小。取文件和可读的max的min } else if (S_ISDIR(statbuf.st_mode))//是目录 { err = EISDIR; } if (modifyTime)//保存修改时间 { *modifyTime = statbuf.st_mtime; } if (createTime)//创建时间 { *createTime = statbuf.st_ctime; } } else { err = errno; } } while (content->size() < implicit_cast<size_t>(maxSize))//也就是上面的比较结果,可读的最大值超过文件大小,那就尝试读到最大 {//思想就是尽量多地读 size_t toRead = std::min(implicit_cast<size_t>(maxSize) - content->size(), sizeof(buf_)); ssize_t n = ::read(fd_, buf_, toRead); if (n > 0)//读出n字节后,追加到content { content->append(buf_, n); } else//n==0表示读到文件末尾 { if (n < 0)//出错 { err = errno; } break; } } } return err;}int FileUtil::ReadSmallFile::readToBuffer(int* size){ int err = err_; if (fd_ >= 0) { ssize_t n = ::pread(fd_, buf_, sizeof(buf_)-1, 0);//读文件到buf,size是实际读出的大小。@4是文件偏移游标。 if (n >= 0) { if (size) { *size = static_cast<int>(n); } buf_[n] = '\0'; } else { err = errno; } } return err;}template int FileUtil::readFile(StringArg filename, int maxSize, string* content, int64_t*, int64_t*, int64_t*);template int FileUtil::ReadSmallFile::readToString( int maxSize, string* content, int64_t*, int64_t*, int64_t*);#ifndef MUDUO_STD_STRINGtemplate int FileUtil::readFile(StringArg filename, int maxSize, std::string* content, int64_t*, int64_t*, int64_t*);template int FileUtil::ReadSmallFile::readToString( int maxSize, std::string* content, int64_t*, int64_t*, int64_t*);#endif
阅读全文
0 0
- muduo库源码学习(base)FileUtil
- [Muduo网络库源码分析] (5) base/FileUtil.cc_h_文件操作
- muduo库源码学习(base)Atomic
- muduo库源码学习(base)AsyncLogging
- muduo库源码学习(base)Condition
- muduo库源码学习(base)CountDownLatch
- muduo库源码学习(base)Date
- muduo库源码学习(base)Exception
- muduo库源码学习(base)mutex
- muduo库源码学习(base)singleton
- muduo库源码学习(base)ThreadLocal
- muduo库源码学习(base)ThreadLocalSingleton
- muduo库源码学习(base):Logfile
- muduo库源码学习(base):LogStream
- muduo库源码学习(base):WeakCallback
- muduo库源码学习(base)BlockingQueue和BoundBlockingQueue
- muduo库源码学习(base)Thread和CurrentThread
- [Muduo网络库源码分析] (10) base/ThreadPoll_cc_h_线程池
- Linux patch命令
- Java 字符串去掉空格的几种方法
- 一个简单的傅里叶变换matlab函数(绝对可用)
- 似然与极大似然估计
- C#学习-网站基础(一)
- muduo库源码学习(base)FileUtil
- MAC卸载jenkins
- VS2015报错:计算机中丢失ucrtbased.dll
- 使用menuconfig配置内核时对.config及内核模块的影响【使用的飞凌嵌入式板】
- JZOJ 5438. 【NOIP2017提高A组集训10.31】Tree
- The import org.apache.commons cannot be resolved 的报错
- 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型
- 浏览器插件推荐
- 动态规划之矩阵链乘法