#c #c 11 #visual-c #c 14
#c #c 11 #visual-c #c 14
Вопрос:
Рассмотрим следующий код,
auto fin = ifstream("address", ios::binary);
if(fin.is_open())
fin.close()
for(auto i = 0; i < N; i){
fin.open()
// ....
// read (next) b bytes...
// ....
fin.close()
// Some delay
}
Приведенный выше код не может быть реализован на C , который я знаю, но я хотел бы знать, возможно ли это сделать?
Вот мои требования:
- При повторном открытии файла не было бы необходимости снова передавать параметры (путь и режим).
- При повторном открытии потока он продолжается с точки в потоке, в которой он был закрыт.
Разъяснение
- Файлы, с которыми я работаю, имеют большой размер, и в определенный момент времени другие потоки из сторонних библиотек могут решить (повторно) переместить их. Открытый поток предотвратит такие действия.
- Непрерывное чтение большого файла замедлит работу системы.
Комментарии:
1. Потоки работают не так. Зачем закрывать его, если вы хотите, чтобы он был открыт и позиционирован?
2. @BoPersson Файлы, с которыми я работаю, имеют большой размер, и в какой-то момент другие потоки из сторонних библиотек могут решить удалить их. Открытый поток предотвратит это действие, и эти потоки могут завершиться сбоем.
3. Здесь вы настраиваетесь на кошмар параллелизма. Рекомендую переосмыслить.
4. Удалил мой ответ, поскольку я недостаточно помню C , чтобы продолжить отвечать. Вы всегда можете создать функцию, которая принимает аргументы конструктора и возвращает новую функцию, которая принимает поток, и создает новую там, где остановилась старая. Вероятно, самый простой способ сделать то, чего вы пытаетесь достичь.
5. @Carcigenicate Я ценю время, которое вы посвятили ответу. Спасибо. Я взял идею из того, что вы упомянули.
Ответ №1:
Необходимость
Действительно, файл не может быть удален другим процессом, пока поток сохраняет его открытым.
Я полагаю, вы уже задавали себе эти вопросы, но для восстановления я должен предложить вам подумать об этом:
- Разве файл не может быть считан в (виртуальную) память и удален, когда он больше не нужен?
- Разве обработка файла не может быть конвейерной асинхронной, чтобы сразу прочитать его и обработать без ненужных задержек?
- Что делать, если файл больше не может быть открыт, потому что он был удален другим процессом ? Что делать, если местоположение не может быть найдено, потому что файл был изменен (например, сокращен)?
- Если бы у вас было идеальное решение вашей проблемы, каков был бы эффект, если бы другой процесс попытался удалить файл, когда он открыт (только на короткое время, но, тем не менее, открыт и блокирует удаление)?
Решение
К сожалению, вы не можете добиться желаемого поведения со стандартными потоками. Вы могли бы эмулировать его, отслеживая имя файла и позицию (и, в более общем смысле, состояние):
auto mypos = ifs.tellg(); // saves position.
// Should flag be saved as well ? and what about gcount ?
ifs.close();
...
if (! ifs.is_open()) {
ifs.open(myfilename, myflags); // open again !
if (! ifs) {
// ouch ! file disapeared ==> process error
}
ifs.seekg(mypos); // restore position
if (! ifs) {
// ouch ! position no longer reachable ==> process error
}
}
Конечно, вы не хотели бы повторять этот код когда-либо и когда-либо. И было бы не так приятно, если бы внезапно появилось много глобальных переменных для отслеживания состояния потока. Но вы могли бы очень легко инкапсулировать его в класс-оболочку, который позаботится о сохранении и восстановлении состояния потока с использованием существующих стандартных операций.
Комментарии:
1. Даже если файл открыт, он может быть обрезан до нулевого размера другими процессами, и его запись в каталоге может быть удалена. Какова предполагаемая операционная система?
2. @HeikoBloch да, и мы не будем решать здесь все проблемы OP. Я думаю, что OP нацелен на Windows из-за тега «visual C »
3. Спасибо. Вопросы, которые вы задали, я имел в виду. К сожалению, все риски, о которых вы упомянули, существуют, и у меня не было лучшего решения, чем то, которое вы дали. Кажется, другого или лучшего решения нет. Еще раз спасибо.