【问题标题】:Why does this not write the correct bytes to the file?为什么这不会将正确的字节写入文件?
【发布时间】:2011-11-08 16:37:49
【问题描述】:

这是我写入文件的测试:

    [Test]
    public void CanWriteManifestToFile()
    {
        byte[] data = new byte[] { 0x00, 0x01, 0x80, 0x1f };
        MemoryStream ms = new MemoryStream(data);
        var mg = new ManifestGeneratorV1();
        mg.WriteManifestFile(ms, "TestManifest.mnf");

        Assert.IsTrue(File.Exists("TestManifest.mnf"));
        Assert.AreEqual(data, GetDataFromFile("TestManifest.mnf"));
    }

这里是实际进行写入的 WriteManifestFile 方法:

    public void WriteManifestFile(MemoryStream ms, string filePath)
    {
        using (StreamWriter sw = new StreamWriter(filePath, false))
        {
            ms.Seek(0, 0);
            using (StreamReader sr = new StreamReader(ms))
            {
                sw.Write(sr.ReadToEnd());
            }
        }
    }

我的测试失败了。结果是以下字节数组{00,01,ef,bf,bd,1f}。现在,如果我将 80 更改为不以 f8 开头的东西,一切正常。什么可能导致 80 更改为 efbfbd

【问题讨论】:

  • 你忘了说你正在改变什么使它正常工作。
  • 这些字节是 utf8 BOM。如果您真的想用 BOM 编写 utf8(有问题),请使用 new UTF8Encoding(false)。

标签: c# streamwriter


【解决方案1】:

您正在对非字符串数据使用 string 方法; ReadToEndWrite(string)。那是无效的;损坏是由此产生的直接结果(即通过文本Encoding 运行任意数据)。改用原始的Stream API:

using(var file = File.Create(filePath))
{
    ms.Position = 0;
    ms.CopyTo(file);
}

或者只是:

File.WriteAllBytes(filePath, ms.ToArray());

【讨论】:

    【解决方案2】:

    StreamReader.ReadToEnd() 返回一个字符串。这意味着它需要解释它读取的流中的字节。对于这种解释,我猜它在您的情况下使用编码 UTF-8。这是错误的,因为您的字节不代表文本。

    您真的想读取字节并将它们写入文件而无需任何解释。像这样。

    var bytes = new byte[ms.Length];
    ms.Read(bytes, 0, bytes.Length);
    using(var fileStream = new FileStream(...))
    {
        fileStream.Write(bytes, 0, bytes.Length);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多