2013-04-01 2 views
0

У меня возникли проблемы с записью указателя на поток, и это довольно озадачивает, поскольку я действительно больше не вижу ничего, чего не хватает. Обратите внимание, что это является продолжением от этого вопроса: C++ vector of ofstream, how to write to one particular elementC++ указателя потока не удается записать на диск

Мой код выглядит следующим образом:

std::vector<shared_ptr<ofstream>> filelist; 

void main() 
{ 
    for(int ii=0;ii<10;ii++) 
    { 
    string filename = "/dev/shm/table_"+int2string(ii)+".csv"; 
    filelist.push_back(make_shared<ofstream>(filename.c_str())); 
    } 

    *filelist[5]<<"some string"<<endl; 
    filelist[5]->flush(); 
    exit(1); 

} 

Это делает ничего в выходной файл не писать, но оно создает 10 пустых файлов. Кто-нибудь знает, что может быть здесь неправильно?

EDIT: Я провел еще несколько испытаний. Я разрешаю код работать без выхода (1) до завершения, по всем файлам, пока все обратные вызовы не будут завершены. Оказывается, что некоторые файлы не пустые, а другие, у которых должны быть данные, пустые.

Существует много места на диске, и я знаю, что у меня есть больше дескрипторов файлов, чем это необходимо для этого. Любое объяснение того, почему некоторые файлы были написаны правильно, а другие нет?

+0

Почему 'std :: vector >' вместо простого 'std :: vector '? – LihO

+0

@LihO Вы не можете копировать поток, поэтому вы не можете напрямую выполнять вектор потоков. Использование shared_ptr вместо необработанных указателей позволяет вам вручную удалять ресурсы. Существуют и другие подходы, которые имеют более низкие штрафные санкции, но для вектора из 10 предметов это не имеет большого значения. – Pyrce

ответ

1

Я бы попробовал: (*filelist[5])<<"some string\n";.

Я бы предположил, что вы, вероятно, хотели писать файлы внутри цикла - как есть, вы пишете только один файл.

О, и на C++ вы не хотите использовать exit.

Edit: Вот быстрый (проверено) автономный демо:

#include <fstream> 
#include <string> 
#include <vector> 

std::vector<std::ofstream *> filelist; 

int main() { 
    for(int ii=0;ii<3;ii++) 
    { 
    char *names[] = {"one", "two", "three"}; 
    std::string filename = "c:\\trash_"; 
    filename += names[ii]; 
    filename += ".txt"; 
    filelist.push_back(new std::ofstream(filename.c_str())); 
    } 

    for (int i=0; i<filelist.size(); i++) { 
    (*filelist[i])<<"some string\n"; 
    filelist[i]->close(); 
    } 
} 

Однако следует отметить, что имя файла это создает для Windows, в то время как оригинал был (видимо), предназначенный для чего-то Unix-подобных. Для Unix-подобной ОС вам потребуется/требуется другая строка имени файла.

+2

Зачем это работает? – 0x499602D2

+0

Итак, я использую выход для завершения выполнения раньше, есть ли что-то, что нужно использовать вместо выхода? Я перешел к предложению выше, и, похоже, он, похоже, не изменяет поведение кода, но ничего не написано. – user788171

+0

@ user788171 Вы еще не закончили выполнение раньше. Вы уже в конце 'main()' уже. –

0

Попробуйте закрыть файл перед тем, как позвонить по телефону exit с помощью filelist[5]->close();. Вы отменили процесс с открытым файлом, что означает, что ваша запись, возможно, не попала в буфер ОС или была отброшена при завершении процесса. Вы также можете удалить вызов exit, вероятно, устраните проблему. Результаты ввода-вывода в процессе, который прерван, сложны для гвоздя, поэтому лучше избегать прерываний с активным IO или предположить, что любой активный IO не сработает после прерывания.

+0

Так что я попытался вызвать close(), и это ничего не изменило. К сожалению, это внутри функции обратного вызова, и я не уверен в том, чтобы изящно выйти из этого. – user788171

+0

@ user788171 Хм, кроме закрытия файла перед выходом, в коде, который вы опубликовали, ничего не найдено, что подсказывает, почему вы получаете это поведение. Существуют ли специальные разрешения для файлов, которые вы пишете? Являются ли они в смонтированном каталоге или в системе общего доступа, например afs? – Pyrce

Смежные вопросы