muduo之FileUtil
生活随笔
收集整理的這篇文章主要介紹了
muduo之FileUtil
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ??FileUtil用來操作文件。AppendFile用來寫日志,使用的fopen函數;ReadSmallFile使用open函數用來讀取linux內核的一些信息。
FileUtil.h
// Use of this source code is governed by a BSD-style license // that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com) // // This is a public header file, it must only include public header files.#ifndef MUDUO_BASE_FILEUTIL_H #define MUDUO_BASE_FILEUTIL_H#include "muduo/base/noncopyable.h" #include "muduo/base/StringPiece.h" #include <sys/types.h> // for off_tnamespace muduo { namespace FileUtil {// read small file < 64KB class ReadSmallFile : noncopyable//小文件讀取 {public:ReadSmallFile(StringArg filename);~ReadSmallFile();// return errnotemplate<typename String> //函數模板int readToString(int maxSize, //最大的長度String* content, //讀入content緩沖區int64_t* fileSize, //文件大小int64_t* modifyTime, //修改時間int64_t* createTime); //創建時間/// Read at maxium kBufferSize into buf_// return errnoint readToBuffer(int* size);const char* buffer() const { return buf_; }static const int kBufferSize = 64*1024;//64Kprivate: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 safe class AppendFile : noncopyable {public:explicit AppendFile(StringArg filename);~AppendFile();void append(const char* logline, size_t len);void flush();off_t writtenBytes() const { return writtenBytes_; }private:size_t write(const char* logline, size_t len);FILE* fp_;char buffer_[64*1024];//64Koff_t writtenBytes_; };} // namespace FileUtil } // namespace muduo#endif // MUDUO_BASE_FILEUTIL_HFileUtil.cc
// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#include "muduo/base/FileUtil.h" #include "muduo/base/Logging.h"#include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <sys/stat.h> #include <unistd.h>using namespace muduo;FileUtil::AppendFile::AppendFile(StringArg filename): fp_(::fopen(filename.c_str(), "ae")), // 'e' for O_CLOEXEC //這里用了fopenwrittenBytes_(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);//將日志寫入文件中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_unlockedreturn ::fwrite_unlocked(logline, 1, len, fp_); }//fopen有緩沖,open是沒有緩沖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 errno template<typename String> int FileUtil::ReadSmallFile::readToString(int maxSize, //將文件讀到contentString* content,int64_t* fileSize,int64_t* modifyTime,int64_t* createTime) {static_assert(sizeof(off_t) == 8, "_FILE_OFFSET_BITS = 64");assert(content != NULL);int err = err_;if (fd_ >= 0){content->clear();if (fileSize){struct stat statbuf;//fstat函數用來 獲取文件(普通文件,目錄,管道,socket,字符,塊()的屬性//fstat 通過文件描述符獲取文件對應的屬性if (::fstat(fd_, &statbuf) == 0)//fstat用來獲取文件大小,保存到緩沖區當中{if (S_ISREG(statbuf.st_mode)){*fileSize = statbuf.st_size;//stat結構體中有st_size參數就是文件大小,串給輸入參數指針content->reserve(static_cast<int>(std::min(implicit_cast<int64_t>(maxSize), *fileSize)));}else if (S_ISDIR(statbuf.st_mode))//S_ISDIR功能是判斷一個路徑是否為目錄{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){content->append(buf_, n); //追加到字符串}else{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);if (n >= 0){if (size){*size = static_cast<int>(n);//static_cast強制類型轉換}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*);?
總結
以上是生活随笔為你收集整理的muduo之FileUtil的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: muduo之BlockingQueue
- 下一篇: muduo之LogFile