【问题标题】:ifstream keeps read even though the file does not exists anymore即使文件不再存在,ifstream 也会继续读取
【发布时间】:2020-10-30 16:47:08
【问题描述】:

我在使用 std::ifstream 读取文件时遇到问题。我有一个名为“nice_folder.zip”(71.6MB)的 zip 文件和重现该问题的以下代码:

#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <unistd.h>

int main() {

  size_t read = 0;
  size_t f_size = std::filesystem::file_size("nice_folder.zip");
  std::shared_ptr<char[]> buffer{new char[4096]};
  std::ifstream file{"nice_folder.zip"};
  while (read < f_size) {
    size_t to_read = (f_size - read) > 4096 ? 4096 : (f_size - read);
    file.read(buffer.get(), to_read);
    sleep(2);
    std::cout << "read: " << std::to_string(to_read) << "\n";
  }
}

问题如下:经过一些读取周期后,我从文件夹中删除了文件,但它仍然继续读取它。这怎么可能 ?如果用户在使用 ifstream 读取文件时删除文件,我该如何捕捉错误?我猜 ifstream 在开始读取之前会将文件的内容放入内存,但我不确定。

【问题讨论】:

  • 删除文件时发生的行为是特定于操作系统的。一些操作系统会在删除后保持文件存在,而它仍然在应用程序中打开。此外,c++ 可能已经缓冲了文件的至少一部分
  • 也不清楚为什么你认为你观察到的行为是一个“问题”。您想在读取文件时对文件被删除做出反应吗?
  • 我强烈建议在每次 IO 事务后检查流状态是否有错误。不检查你怎么知道你真的在读什么?
  • @drescherjm 据我所知,当您在 Linux 上打开文件时,您会检索文件描述符并将其插入到每个进程打开的文件表中,我不明白操作系统为什么要检索文件此时的内容还是缓冲到内存中这么大的内容。
  • 关于linux的答案是正确的。

标签: c++ ifstream


【解决方案1】:

如果您正在执行此操作,例如linux,那么操作系统不会真正删除该文件,直到您关闭它的所有文件句柄。所以看起来文件被删除了,但它仍然存储在磁盘上的某个地方。参见例如What happens internally when deleting an opened file in linux.

因此,如果您尝试检测此文件删除以防止错误读取,请不要担心,该文件实际上不会被删除。

如果您关闭流,然后尝试为该文件再次打开它,您将收到错误消息。但这也意味着您将无法从中读取...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 2019-03-01
    相关资源
    最近更新 更多