Задержка в ofstream :: open, возможно, из-за смешивания с _iobuf? - PullRequest
0 голосов
/ 08 января 2012

У меня есть программа на C ++, которая создает выходной файл "A" с ofstream.Этот файл затем читается неким устаревшим кодом C, который открывает файл с помощью _iobuf.Затем унаследованный код создает свой собственный выходной файл «B» с помощью _iobuf, и этот файл затем читается программой C ++ с использованием ifstream.Эта последовательность повторяется много раз, с одинаковыми именами файлов для A и B. В каждой итерации.

Иногда программа C ++ не может открыть выходной файл A для записи, и я должен попытаться несколько раз, прежде чем это удастся.Это происходит недетерминированно, и может быть один раз в тысячу итераций.Обратите внимание, что программе на C никогда не нужно ждать, чтобы открыть свой входной или выходной файл, и программе C ++ никогда не приходится ждать, чтобы открыть свой входной файл.Это неформальное наблюдение основано на сотнях тысяч итераций.

Интересно, это как-то связано со смешиванием потоков и _iobuf в одной программе?И код C ++, и код C связаны в одной программе.А унаследованный код C технически является кодом C ++, но был написан в очень C-подобном стиле.Что я могу сделать, чтобы устранить это ожидание, чтобы открыть файл ofstream?Я не хочу менять унаследованный код, если могу избежать его.

Псевдокод (не скомпилирован):

void someObject::someMethod()
{
    for (int count = 0; count < someLimit; ++count)
    {
        newerObject::firstMethod();
        olderObject::secondMethod();
        newerObject::thirdMethod();
    }
}

void newerObject::firstMethod()
{
    // do some processing first

    // then write the results of the processing to a file
    ofstream A;
    A.open("A", ofstream::out); // this sometimes must be tried multiple times
    // write data to file A
    A.close();
}

void olderObject::secondMethod()
{
    FILE* f;
    f = fopen("A", "rt"); // this always works the first time
    // read data from file A
    fclose(f);

    // do some processing

    f = fopen("B", "w");
    // write data to file B
    fclose(f);
}

void newerObject::thirdMethod()
{
    ifstream B;
    B.open("B"); // this always works the first time
    // read data from file B
    B.close();

    // do some processing
}

В настоящее время, как обходной путь, я поставил ofstream:: открыть в цикле do-while.Я хотел бы избавиться от этой неловкости.Заранее благодарим за любой совет, который вы можете дать.

1 Ответ

0 голосов
/ 08 января 2012

Во-первых, проблема почти наверняка не в том, чтобы использовать разные методы для доступа к файлам: под капотом функции ввода-вывода C и C ++ используют одни и те же средства системного ввода-вывода.Вы, кажется, используете Windows (в других системах файлы обычно могут открываться несколько раз одновременно), и я не знаю много о системе, но я подозреваю, что файловая система не была обновлена, чтобы отразить, что файл закрыт, когдаВы пытаетесь открыть это.Это может быть связано с флагом открытия "t": я не знаю, о чем идет речь.

В UNIX вы можете заставить операции ввода / вывода ждать, пока фактическое изменение на диске не будет завершено.Нечто подобное может помочь избежать этой проблемы, но имеет значительные затраты, поскольку операции становятся ужасно медленными.В UNIX один из подходов заключается в удалении записи файловой системы в момент успешного открытия файла (в конце концов, на данный момент его имя больше не используется):

if (FILE* fp = fopen("file", "r")) {
    remove("file");
    // do processing
}

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

  1. Определить, в каких ситуациях файл не может быть открыт, например, оставив файл открытым и попытавшись открыть его.Это в основном предназначено для создания установки, в которой проблема воспроизводима, чтобы позже вы могли проверить, действительно ли вы нашли решение.
  2. Как только я найду способ воспроизвести проблему, я, вероятно, получу лучшее представление о настоящем корне.причина и, возможно, поможет поиск в Google.В любом случае, именно здесь начинается исследование основной причины.
  3. Как только причина будет понята, мы надеемся, что легко найти решение.Если нет, то открытие файла несколько раз в случае его успешности вполне может быть правильным решением.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...