ifstream создает файл, если он не существует

У меня возникли проблемы с написанием консольного приложения для Linux, которое читает журналы apache.

Мне нужно обработать аргументы 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

5

Решение

Вы можете установить failbit в флаге исключений для 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 исключение, если файл не может быть открыт, например, файл не найден, нет прав на чтение. Это будут открыт только для чтения.

1

Другие решения

Так как вы открываете std::ifstream надо добавить std::ios_base::in (или любое другое написание std::ios_base::openmode) в соответствии с пунктом 27.9.1.9 [ifstream.members]: флаг добавляется автоматически при вызове 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 (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).

3

Вам нужно указать ifstream :: in в качестве второго параметра как:

log.open(arg.c_str(), ifstream::in)

Вы также можете сделать:

std::ifstream log(arg.c_str(), ifstream::in);

и пропустить звонок open()

0

Редактировать с помощью чего-нибудь совместимого с 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
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector