Почему это не записывает правильные байты в файл? - PullRequest
2 голосов
/ 01 сентября 2011

Вот мой тест для записи в файл:

    [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 на что-то, что не начинается с f или 8, все работает правильно.Что может привести к изменению 80 на efbfbd?

Ответы [ 2 ]

4 голосов
/ 01 сентября 2011

Вы используете string методы для нестроковых данных; ReadToEnd и Write(string). Это неверно; повреждение является прямым результатом этого (то есть пропуск произвольных данных через текст Encoding). Вместо этого используйте сырой Stream API:

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

или просто:

File.WriteAllBytes(filePath, ms.ToArray());
3 голосов
/ 01 сентября 2011

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...