【问题标题】:Permanently delete file in Qt在 Qt 中永久删除文件
【发布时间】:2014-04-04 11:34:13
【问题描述】:

我不得不更改我没有编写的 Qt 程序。我在代码中找到了该位置并且知道我想要它,但我不知道要更改什么,所以寻求帮助。 代码如下:

QFile file(path);
qint64 size = filesize(path);
qint64 blockSize = 10240;
bool ok = file.open(QIODevice::ReadWrite);

if (ok)
{
    QTime t;
    t.start();
    file.seek(0);
    for (int i = 0; i < ceil(double(size) / double(blockSize)); i++)
    {
        qint64 block = size - i * blockSize;
        if (block > blockSize)
        {
            block = blockSize;
        }

        QByteArray data;
        data.resize(block);
        data.fill('0');
        file.write(data, block);
    }
    file.close();
    file.remove();
}

这里用零替换文件的内容,因为删除后无法恢复。谷歌搜索我得出了两个结论,要么文件中没有真正的写入,要么将新数据写入其他磁盘扇区,而旧的仍然存在。如何使文件的内容真正被零替换而无法恢复? 任何帮助将不胜感激!

【问题讨论】:

  • 绝对不能保证旧块不在磁盘上/在某些备份中。
  • 这是一个常见问题 - 搜索安全擦除文件。 Example 1 Example 2 这是一个难题,最好留给已经做到这一点的工具,而不是尝试开发自己的工具(Qt 没有提供这样做的功能,它将非常依赖于操作系统)。
  • 如果您不希望任何人在您不需要文件时读取文件的内容,那么您可能在仍然需要文件时也想要同样的内容。因此,防止任何人读取现有和已删除文件的最简单方法 - 对其进行加密。我知道这不是您所要求的,并且很难安全地加密文件,但这会有所帮助。通常,在您物理融化磁盘之前,您无法确定文件是否无法恢复。

标签: c++ qt qtcore qfile shred


【解决方案1】:

我个人只会使用shred 或通过QProcess 提供的类似工具。在这种情况下,这可能是最好的效果/努力比。

我认为你不应该自己发明这个,因为这不是 Qt 特有的东西,也不是常见的东西。

【讨论】:

  • shred 几乎完成了上面代码的含义......在 Windows 上,shred 的端口是不够的。 SDelete 是唯一合理的解决方案(或精确的重新实现)。
  • 不,正如其他人指出的那样,它取决于平台。你不能只在 Qt 中实现它。此外, shred 比上面的代码做得更多和不同。这是source code。另外,我不记得提到过“碎纸港”。
  • 除了直接 I/O 之外,shred 不再做任何有趣的事情。如今,多重覆盖货物崇拜已经相当陈旧和无聊。如果您将现代硬盘上的内容覆盖一次,数据就会消失,没有人可以恢复它。
  • 我不明白你的意思。让我们想象一下你想说的是真的,周围仍然有很多“旧”硬盘,但我不确定你说的是真的。也许,您跳过了阅读 OP 问题中的另一个链接线程。尽管公司几十年来一直专注于这项任务,但您似乎对这件事的看法非常简单。
  • 本次讨论的“旧”硬盘驱动器可以存储 一次。如果可能的话,那就太酷了,但事实并非如此。
【解决方案2】:

代码相当复杂。不值得“修复”。

下面是一个合理合理的实现,应该可以工作,只要这种方法可以在您的系统上运行。如果您说它“不起作用”-您如何检查?在什么平台上?什么Qt版本?

请注意,在 Windows 上,此工具对压缩、加密和稀疏文件无用。在内部,写入此类文件首先复制集群,然后在复制的集群中进行修改,将原始数据留在后面。 SDelete 工具可以适当地处理这些问题。

bool shred(const QString & fileName) {
  QFile file(fileName); 
  QFileInfo fi(file);
  qint64 fileSize = fi.size();
  if (! file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)) return false;

  QByteArray block(65536, '\0');
  while (fileSize > 0) {
    if (fileSize < block.size()) block.truncate(fileSize);
    qint64 written = file.write(block);
    if (written != block.size()) return false;
    fileSize -= written;
  }
  Q_ASSERT(fileSize == 0);
  fsync(file.handle());
  return file.remove();
}

【讨论】:

  • 为什么打开文件 ReadWrite 而不是 WriteOnly?另外,对于 Windows,我认为您应该在 remove() 之前 close()。
  • A WriteOnly open 可以想象截断文件,我们不希望这样。我不认为ReadWrite 打开不应该受到伤害。 close() 由 remove() 自动完成,这是 QFile 的行为,与平台无关。
  • 我在 Windows 7 上使用基于 Qt 4.8.3(32 位)的 Qt Creator 2.6.0。尝试采纳您的建议,但编译器生成错误“错误:‘fsync’是未在此范围内声明”,如何解决?
【解决方案3】:
QDir destination;
destination.remove("path to file");

【讨论】:

  • 嗯,这应该有两次指定的相同字符串文字吗?
  • 请在您的回答中添加一些描述。
  • 可以在没有路径“QDir destination;”的情况下声明QDir
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
相关资源
最近更新 更多