在不打开文件的情况下删除文件的最后4个字节

本文关键字:文件 最后 4个 字节 删除 情况下 | 更新日期: 2023-09-27 18:25:05

这是一个在面试中问我的问题,但仍然找不到解决方法-

假设我有一个.txt文件,并且我想在不打开该文件的情况下从该文件的内容中删除最后4个字符。第一个问题是——它真的可行吗?如果是,该怎么做?

在不打开文件的情况下删除文件的最后4个字节

我猜您无法读取文件的内容。因此,如果你可以用只读访问"打开"它,你可以做:

using (var fileStream = File.Open("initDoc.txt", FileMode.Open, FileAccess.Write))
{
    fileStream.SetLength(fileStream.Length - 4);
}  

当然,你需要额外的检查,以确保根据编码减去正确的字节数,而不是减去超过长度等。

如果不能使用FileMode.Open,可以使用使用SafeFileHandle的FileStream构造函数的重载。要获取文件的SafeFileHandle,您需要使用C#互操作。在下面的这个例子中,我已经包装了interop代码,以便在一个名为"UnmanagedFileLoader"的类中获得一个文件句柄:

var unmanagedFileLoader = new UnmanagedFileLoader("initDoc.txt");
using (var fileStream = new FileStream(unmanagedFileLoader.Handle, FileAccess.Write))
{
    fileStream.SetLength(fileStream.Length - 4);
}

UnmanagedFileLoader内部使用非托管CreateFile函数打开具有写权限的现有文件:

handleValue = CreateFile(Path, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

有关如何获取SafeFileHandle的更多信息,您可以查看此链接:

http://msdn.microsoft.com/en-us/library/microsoft.win32.safehandles.safefilehandle%28v=vs.110%29.aspx

如果您想跳过FileStream方式,第三种方法是使用StreamReader和StreamWriter,然后使用StreamReader读取不包含最后4个字节的文件,然后使用StreamWriter写入。但我仍然建议使用上面的FileStream示例。

编辑:我认为"打开文件"意味着"获得文件的句柄"。

当然有可能:

  • 打开包含文件的驱动器的句柄
  • 获取文件系统类型
  • 扫描包含所有文件信息的结构的内容:MFT(对于NTFS)、FAT记录。。等等
  • 查找与您的文件相对应的条目
  • 通过将存储"文件大小"信息的值减去4来更新条目(写入):)

如果您关心的是读取一个长文件的所有数据:那是没有必要的。如果我们假设你真的是指字节,那么简单地说:

using (var file = File.Open(path, FileMode.Open, FileAccess.Write)) {
    file.SetLength(file.Length - 4);
}

这不会读取文件的内容

如果你的意思是字符,那么你需要非常仔细地考虑编码——4个字符不一定是4个字节。