[英]ifstream creates file if it doesn't exist
我在編寫一個讀取apache日志的Linux控制台應用程序時遇到了一些麻煩。
我需要處理bash腳本參數,最后一個是日志文件的路徑。 我的問題是如果文件不存在,我想拋出異常。
但是當我嘗試以只讀模式打開文件時,它會創建文件而不是失敗!
這是代碼:
// 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
因為你打開一個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]第3段),如果新文件不存在(並且有寫入權限等),這兩個文件都會被創建。
如果您發布的代碼創建了一個新文件,那么標准C ++庫的實現是錯誤的:當只指定標志std::ios_base::in
,文件打開“就像”使用打開模式"r"
與fopen()
(27.9.1.4 [filebuf.members]第5段)。 fopen()
獲得打開模式"r"
(7.21.5.3第3段)時,它不會創建新文件。
您可以在ifstream
的例外標志中設置failbit
:
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
異常,例如找不到文件,沒有讀取權限。 它將以只讀方式打開。
編輯與Linux兼容的東西;
在寫之前嘗試用fopen打開。 如果文件DNE,則FILE
指針將為null。
FILE * file;
file = fopen ("myfile.txt","r");
if (file == NULL)
//throw if fopen didn't already.
else
//do stuff with my file
您需要將ifstream :: in指定為第二個參數:
log.open(arg.c_str(), ifstream::in)
你也可以這樣做:
std::ifstream log(arg.c_str(), ifstream::in);
並跳過調用open()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.