使用System.IO.BinaryWriter编写文件

时间:2009-07-17 19:37:03

标签: c#

我正在尝试使用C#的System.IO.BinaryWriter class编写音频文件。

执行此操作时,它可以正常工作:

File.WriteAllBytes(@"C:\TestFile\File1", br.ReadBytes((int)br.BaseStream.Length));

但是,当我执行以下操作时,它不起作用:

Encoding e = Encoding.ASCII;
char[] reslts = e.GetChars(br.ReadBytes((int)br.BaseStream.Length));
br.BaseStream.Position = 0;
File.WriteAllBytes((@"C:\TestFile\File2",e.GetBytes(reslts));

我检查了字节数组,在这两种情况下,数组都包含相同的值(我将它们的值复制到一个单独的excel文件中并检查是否有任何差异,没有)。

在这两种情况下,基本流位置都设置为0.

代码本身有效,文件创建成功。打开文件时出现问题,第一个文件正常工作,Windows Media Player无法识别第二个文件。

有没有人对我可能做错了什么有任何想法?

4 个答案:

答案 0 :(得分:1)

Encoding e = Encoding.ASCII;

看起来很可疑。我不知道使用ASCII编码的任何音频格式。

答案 1 :(得分:1)

永远不要读取任意二进制数据,就像它的文本一样。它总是出错,因为它们不是一回事。

此外,不要依赖流的长度 - 它可能会改变,或者它可能不支持取其流。

你想要这样的东西:

public static byte[] CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[16*1024];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, read);
    }
}

然后只需打开FileStream到您想要写入数据的位置,然后调用

CopyStream(inputStream, outputFile);

您尚未显示您从哪里获得输入,但基本上您并不真正需要BinaryReader。这并不像你正在使用BinaryReader来实现它的正常目的,那就是读取单个原始值,长度为前缀的字符串等。你只想逐字复制数据 - 而Stream就可以了

答案 2 :(得分:1)

对于大多数编码,包括Encoding.ASCII,将字节转换为字符并再次返回将不会返回相同的数据。例如,IIRC Encoding.ASCII将128-255范围内的所有字节映射到'?'字符。然后,当您转换回字节时,它们将全部转换回相同的值。

例外是Latin1又名ISO-8859-1编码,它将所有具有十六进制值的字节映射到具有相同十六进制值的Unicode字符的0-255范围内。以下应该给出你想要的结果:

Encoding e = Encoding.GetEncoding(28591);
// or either of the following is equivalent
// Encoding.GetEncoding("Latin1");
// Encoding.GetEncoding("ISO-8859-1");

char[] reslts = e.GetChars(br.ReadBytes((int)br.BaseStream.Length));
br.BaseStream.Position = 0;
File.WriteAllBytes((@"C:\TestFile\File2",e.GetBytes(reslts));

然而,除非你有充分的理由这样做,否则我不会以这种方式将字节转换为字符。

答案 3 :(得分:0)

编码用于将字符串编码为字节,然后返回字符串。

你正在向后使用它,解码一些不是字符串的东西。