我试图多次将字节数组写入文件。将FileMode设置为追加,如果文件不存在,则创建该文件,否则打开该文件并按照所述查找文件的末尾。问题是,当写入现有文件时,它会被覆盖,而不是将新的字节数组追加到文件中。非那样做不行。
void WriteToFile()
{
byte[] buffer = new byte[16 * 1024];
int num;
using (FileStream dest_stream = new FileStream(filename, FileMode.Append, FileAccess.Write))
{
while (num = ReadFromAnotherStream(my_other_stream, ref buffer) > 0)
dest_stream.Write(buffer, 0, num);
}
}这个函数偶尔会被调用。如果该文件已经存在,则查找文件的末尾并继续从该文件写入,否则将创建一个新文件并写入数据。
当它应该附加时,它会覆盖.它没有附加。
它应该附加到文件中,而不是覆盖它。
没有抛出错误。
使用Seek作为FileStream什么都不做。
当它覆盖时,数据是正确的,但是,它需要附加在前面的数据的末尾,而不是覆盖。
更新:,我别无选择,只能将每个调用划分为多个“临时”文件,然后在最后将它们合并到主文件中。这样的工作完美无缺,不需要寻找导致无损坏的文件。
缺点是将多个临时文件(特别是大型文件)合并到一个文件中会有额外的处理。
伪码:
string filename;
List<string> tmp_files = new List<string>();
int __i = 0;
do
{
filename = $"my_file.tmp{__i++}";
tmp_files.Add(filename);
}
while (File.Exists(filename));// Every time WriteToFile() gets called... This should be on top.
// Instead of writing directly to the file, add more of them until the input stream has been read fully.
using (FileStream out_fs = new FileStream("my_file.bin", FileMode.Create))
{
foreach (string tmp_file in tmp_files)
{
using (FileStream in_fs = new FileStream(tmp_file, FileMode.Open))
{
in_fs.CopyTo(out_fs);
}
File.Delete(tmp_file);
}
}首先,感谢参与这篇文章的每一个人。代码的一部分无法共享,这超出了我的能力范围。我知道没有魔法球可以从伪代码中读取思想,但我非常渴望从API中解决这个不道德的错误,所以我想得到尽可能多的可能性。
我仍然不知道追加的问题是什么,但是输入流与它没有任何关系,现在已经不再有问题了。
发布于 2021-11-24 19:16:14
我们无法判断您的代码有什么问题,因为您没有包括ReadFromAnotherStream的代码。但是这里有一些代码可以实现您想要的功能,它可以工作:
/// <summary>
/// Appends the contents of the file at inputFilePath to the file at pathToAppendTo
/// </summary>
void Append(string inputFilePath,string pathToAppendTo)
{
var buffer = new byte[16];
using FileStream source = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read);
using FileStream destinationStream = new FileStream(pathToAppendTo, FileMode.Append, FileAccess.Write);
while (TryRead(source, buffer, out int bytes))
{
destinationStream.Write(buffer, 0, bytes);
}
}
private bool TryRead(FileStream source, byte[] buffer, out int bytesRead)
{
bytesRead = source.Read(buffer, 0, buffer.Length);
return bytesRead > 0;
}下面是一个单元测试,以验证它是否有效:
[TestMethod]
public void TestWriteFile()
{
var inputFileName = "C:/fileYouWantToCopy";
var outputFileName = "C:/fileYouWantToAppendTo";
var originalFileBytes = GetFileLength(outputFileName);
var additionalBytes = GetFileLength(inputFileName);
Append(inputFileName,outputFileName);
Assert.AreEqual(GetFileLength(outputFileName), originalFileBytes + additionalBytes);
}
private long GetFileLength(string path) => new FileInfo(path).Length;https://stackoverflow.com/questions/70101541
复制相似问题