C#如何在文件开头添加字节?

4

如何在文件开头最快最有效地添加字节?基本上,我想打开一个文件,然后在开头添加一些字节。我考虑使用循环,但是考虑到所有要添加的字节都相同,我认为这不是必要的。


5
文件有多大?事实上,前置操作有点麻烦。如果文件很大,寻找一种追加的方法会更有效率。 - Marc Gravell
不是很大,最多只有5MB。 - dnclem
4个回答

9

一种不是原子操作的方法(即,如果程序在中途崩溃,则数据可能处于不一致状态):

  1. 打开文件。
  2. 末尾开始,按附加大小差异向后移动字节。这应该以块的形式完成(例如ReadBytes),而不是一次一个字节 - 可以参考最佳流复制方式
  3. 在文件开头填写新数据。

但是,这种方法也可能会受到文件系统预读方案的干扰,并且需要寻找/随机文件访问。因为这些问题,我只能在设备上的空间绝对有限时才真诚地推荐它。

另一种相对于文件是原子操作的方法(如果程序在任何阶段死亡,不会丢失任何数据,并且可以恢复进程):

  1. 打开旧文件。
  2. 创建一个新文件。
  3. 在新文件中填充数据。
  4. 将数据从旧文件移动到新文件(再次使用ReadBytes) - 在这种情况下,之前链接的SO问题应该“按原样工作”。。
  5. 删除旧文件并将新文件重命名为旧文件。

“缺点”是需要一个临时文件。

祝编码愉快。


4

这是我个人能想到的最简洁的方式,但不能像您想要的那样避免循环:

int numberOfBytes = 100;
byte newByte = 0x1;

using ( var newFile = new FileStream( @"C:\newfile.dat", FileMode.CreateNew, FileAccess.Write ) )
{
    for ( var i = 0; i < numberOfBytes; i++ )
    {
        newFile.WriteByte( newByte );
    }
    using ( var oldFile = new FileStream( @"C:\oldfile.dat", FileMode.Open, FileAccess.Read ) )
    {
        oldFile.CopyTo(newFile);
    }
}

// Rename and delete files, or whatever you want to do

它也可以使用一些错误处理,但是你已经有了这个想法。


分别写每个字节?说真的? - EvAlex
“简洁”并不意味着“唯一的方式”。您也可以预填充数组并使用 FileStream.Write 写入整个头块。无论如何,SO 的美妙之处在于即使是一个四年前有已接受答案的问题,您也可以选择今天添加自己的答案,并包括展示性能提升的基准结果。如果它不是冗余、过度或复杂的话,我甚至会点赞。 - Paul Walls

4
如果您真的需要添加前缀,在技术上最“安全”的方法通常是将字节写入一个新文件中,然后将旧文件写入此新文件中,最后交换文件(例如使用File.Replace并使用null作为destinationBackupFileName)。请注意,您需要足够的空间来复制旧文件!

0
我所能想到的最简单的方法是创建一个字节数组,添加您的“前置”字节,然后将要使用的文件转换为另一个字节数组并将它们合并在一起!

是的,那听起来像是一个简单的方法,但它听起来很慢且效率低下。我在想是否有更好的方法。 - dnclem
2
@david:听起来很慢?你试过了吗?总是先尝试一些容易的事情,并对它们进行基准测试,看看它们是否足够快。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接