为什么这不能将正确的字节写入文件?

发布于 2024-12-02 13:25:04 字数 1004 浏览 0 评论 0原文

这是我写入文件的测试:

    [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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终难遇 2024-12-09 13:25:04

您正在对非字符串数据使用字符串方法; ReadToEndWrite(string)。那是无效的;损坏是这种情况的直接结果(即通过文本编码运行任意数据)。使用原始 Stream API 来代替:

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

或者只是:

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

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());
会发光的星星闪亮亮i 2024-12-09 13:25:04

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文