开发者

Why does this not write the correct bytes to the file?

开发者 https://www.devze.com 2023-04-01 03:49 出处:网络
Here is my test to 开发者_运维技巧write to a file: [Test] public void CanWriteManifestToFile() { byte[] data = new byte[] { 0x00, 0x01, 0x80, 0x1f };

Here is my test to 开发者_运维技巧write to a file:

    [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"));
    }

Here is the WriteManifestFile method that actually does the writing:

    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());
            }
        }
    }

My test fails. The result is the following byte array {00,01,ef,bf,bd,1f}. Now if I change the 80 to something that doesn't start with f or 8 everything works correctly. What could cause the 80 to get changed to efbfbd?


You are using string methods on non-string data; ReadToEnd and Write(string). That is invalid; the corruption is a direct result of this (i.e. running arbitrary data through a text Encoding). Use the raw Stream API instead:

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

or just:

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


StreamReader.ReadToEnd() returns a string. That means that it needs to interpret the bytes in the stream it reads from. For this interpretation it uses an encoding, UTF-8 in your case, I guess. This is wrong, because your bytes don't represent text.

You really want to read the bytes and write them to the file without any interpretation. Something like this.

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号