首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我不能使用FileStream将一个新的字节数组附加到文件中?

为什么我不能使用FileStream将一个新的字节数组附加到文件中?
EN

Stack Overflow用户
提问于 2021-11-24 18:56:48
回答 1查看 333关注 0票数 2

我试图多次将字节数组写入文件。将FileMode设置为追加,如果文件不存在,则创建该文件,否则打开该文件并按照所述查找文件的末尾。问题是,当写入现有文件时,它会被覆盖,而不是将新的字节数组追加到文件中。非那样做不行。

代码语言:javascript
运行
复制
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什么都不做。

当它覆盖时,数据是正确的,但是,它需要附加在前面的数据的末尾,而不是覆盖。

更新:,我别无选择,只能将每个调用划分为多个“临时”文件,然后在最后将它们合并到主文件中。这样的工作完美无缺,不需要寻找导致无损坏的文件。

缺点是将多个临时文件(特别是大型文件)合并到一个文件中会有额外的处理。

伪码:

代码语言:javascript
运行
复制
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));
代码语言:javascript
运行
复制
// 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中解决这个不道德的错误,所以我想得到尽可能多的可能性。

我仍然不知道追加的问题是什么,但是输入流与它没有任何关系,现在已经不再有问题了。

EN

回答 1

Stack Overflow用户

发布于 2021-11-24 19:16:14

我们无法判断您的代码有什么问题,因为您没有包括ReadFromAnotherStream的代码。但是这里有一些代码可以实现您想要的功能,它可以工作:

代码语言:javascript
运行
复制
    /// <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;
    }

下面是一个单元测试,以验证它是否有效:

代码语言:javascript
运行
复制
    [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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70101541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档