0

我对我正在编写的一个小工具上的编码有一些普遍的困惑。

首先,我很抱歉以下代码有点被屠杀,但在我迄今为止编写的代码中,它是最接近实际工作的。

如果我使用以下代码:

/*create file*/
FileStream fileS = new FileStream(filename + ".ppm", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 8, FileOptions.None);
/*create a binary writer*/
BinaryWriter bWriter = new BinaryWriter(fileS, Encoding.ASCII);

/*write ppm header*/
string buffer = "P6 ";
bWriter.Write(buffer.ToCharArray(), 0, buffer.Length);
buffer = width.ToString() + " ";
bWriter.Write(buffer.ToCharArray(), 0, buffer.Length);
buffer = height.ToString() + " ";
bWriter.Write(buffer.ToCharArray(), 0, buffer.Length);
buffer = "255 ";
bWriter.Write(buffer.ToCharArray(), 0, buffer.Length);

/*write data out*/
byte[] messageByte = Encoding.UTF8.GetBytes(ppmDataBox.Text);
bWriter.Write(messageByte, 0, messageByte.Length);

/*close writer and bWriter*/
bWriter.Close();
fileS.Close();

然后我得到的是一个以 UTF-8 格式保存的文件,如果我打开该文件并将其重新保存为 ASCII,我会得到我期望的 PPM。

但是,如果我换行:

 byte[] messageByte = Encoding.UTF8.GetBytes(ppmDataBox.Text);

 byte[] messageByte = Encoding.ASCII.GetBytes(ppmDataBox.Text);

然后我确实得到了一个以 ASCII 格式保存的文件,但文件错误,颜色错误,基本上文件中的数据与文本框中的数据不匹配。

我假设文本框是 UTF-8,我粘贴到其中的数据实际上是 ASCII 格式/字符,我首先需要将该 ASCII 转换为其相应的 UTF-8 ...(又名 UTF-8 版本那些字符)。但是,如果我完全诚实,这是我第一次进入编码世界,我完全一无所知。所以如果我在说垃圾,请告诉我。

这是我粘贴到文本框中的数据示例:

ÿÿ ÿÿ ÿÿ ÿÿ aa aa aa ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿ

它本来是黄色的,到处都是黑色的小方块,但它变成了绿色,当文件以 ASCII 格式创建时,数据最终看起来像这样:

?? ?? ?? ?? aa aa aa ?? ?? ?? ??
4

1 回答 1

1

ASCII是 7 位编码(字符值 0 到 127)。ÿ 字符的值大于 127,具体值取决于使用的编码或代码页。(在代码页 1252中,它的值为 255)。当 ASCII 编码试图处理一个值大于 127 的字符时,它只是写一个问号。

看起来您需要将高 ASCII 字符(字符值 128 到 255)映射到单个字节。这排除了使用UTF8UTF32UniCode编码,因为它们的 GetBytes() 方法将为大于 127 的单个字符值返回多个字节。

要将高位 ASCII 字符映射到单个字节,请尝试使用 1252 或437 之类的代码页。如果这些没有提供所需的映射,这里列出了许多其他代码页。

这是使用代码页 1252 的示例:

using System;
using System.IO;
using System.Text;

namespace ConsoleApplication6
{
  public class Program
  {
    public static void Main(String[] args)
    {
      (new Program()).Run();
    }

    public void Run()
    {
      this.SaveData(@"c:\temp\test.ppm", "ÿÿ ÿÿ ÿÿ ÿÿ aa aa aa ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿÿ ÿ", 100, 200, Encoding.GetEncoding(1252));
    }

    private void SaveData(String filename, String data, Int32 width, Int32 height, Encoding encoding)
    {
      const Int32 bufferSize = 2048;

      Directory.CreateDirectory(Path.GetDirectoryName(filename));      

      if (Path.GetExtension(filename).ToLower() != ".ppm")
        filename += ".ppm";

      using (var fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize))
      {
        using (var bw = new BinaryWriter(fs, encoding))
        {
          var buffer = encoding.GetBytes(this.GetHeader(width, height));
          bw.Write(buffer);

          buffer = encoding.GetBytes(data);
          bw.Write(buffer);
        }
      }
    }

    private String GetHeader(Int32 width, Int32 height)
    {
      return String.Format("P6 {0} {1} 255 ", width, height);
    }
  }
}
于 2011-11-14T02:19:14.740 回答