簡體   English   中英

ifstream創建文件,如果它不存在

[英]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::ofstreamstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM