我在编写读取apache日志的Linux控制台应用程序时遇到了一些麻烦。
我需要处理bash脚本参数,最后一个是日志文件的path。 我的问题是,如果文件不存在,我想抛出一个exception。
但是,当我试图以只读模式打开文件,而不是失败它创build文件!
代码如下:
// logreader.h #include <string> #include <sstream> #include <iostream> #include <fstream> #include <stdexcept> class LogReader { public: LogReader(int, const char **); virtual ~LogReader(); // ... private: std::ifstream log_; }; // logreader.cpp #include <logreader.h> LogReader::LogReader(int argc, const char ** argv): log_() { log_.exceptions(std::ifstream::failbit | std::ifstream::badbit); for (int i = 1; i < argc; ++i) { std::string arg(argv[i]); if (i == argc - 1) { try { log_.open(arg.c_str(), std::ifstream::in); } catch (std::ifstream::failure) { throw std::runtime_error("The file " + arg + " wasn't opened"); } } } } LogReader::~LogReader() { } // main.cpp #include <logreader.h> int main(int argc, const char ** argv) { LogReader(argc, argv); return 0; }
脚本调用:
jmcomets $ ./test -g -l jmcomets $ ls -l -rw-rw-r-- 1 jmcomets jmcomets 0 Nov 14 22:41 -l
您可以在ifstream
的异常标志中设置ifstream
:
std::ifstream log; log.exceptions ( std::ifstream::failbit ); try { log.open ("test.txt"); } catch (std::ifstream::failure e) { std::cout << "Exception opening/reading file\n"; }
资源
我已经测试过,如果文件无法打开, ifstream
会抛出一个failure
异常,例如找不到文件,没有读取权限。 它将打开只读。
由于你正在打开一个std::ifstream
所以需要根据27.9.1.9 [ifstream.members]段落4添加std::ios_base::in
(或std::ios_base::openmode
任何其他拼写):标志是通过调用open()
自动添加的。 请注意, std::ofstream
或std::fstream
会自动添加std::ios_base::out
(27.9.1.13 [ofstream.members] paragrpah 3)或std::ios_base::in | std::ios_base::out
std::ios_base::in | std::ios_base::out
(27.9.1.17 [fstream.members] paragraph 3),如果它不存在(并且有写入权限等),则会导致创建新文件。
如果您发布的代码创建了一个新文件,则标准C ++库的实现是错误的:只有std::ios_base::in
标志被指定时,该文件使用开放模式"r"
打开“as if” fopen()
(27.9.1.4 [filebuf.members]第5段)。 fopen()
在得到一个开放模式"r"
(7.21.5.3段落3)时不会创建一个新文件。
你需要指定ifstream :: in作为第二个参数:
log.open(arg.c_str(), ifstream::in)
你也可以这样做:
std::ifstream log(arg.c_str(), ifstream::in);
并跳过呼叫open()
编辑与Linux兼容的东西;
在写之前试着用fopen打开。 如果文件DNE的FILE
指针将为空。
FILE * file; file = fopen ("myfile.txt","r"); if (file == NULL) //throw if fopen didn't already. else //do stuff with my file