5

我试图使用 C# 中的编码 API将文件从 utf-8 转换为阿拉伯语 1265编码,但我遇到了一个奇怪的问题,即某些字符未正确转换,例如以下语句中的 "لا" "ﻣﺣﻣد ﺻﻼ ح عادل " 它显示为 "ﻣﺣﻣد ﺻ? ح عادل"。我的一些朋友告诉我,这是因为这些字符来自阿拉伯语表示形式 B。我使用 notepad++ 创建文件并将其保存为 utf-8。

这是我使用的代码

    StreamReader sr = new StreamReader(@"C:\utf-8.txt", Encoding.UTF8);
    string str = sr.ReadLine();
    StreamWriter sw = new StreamWriter(@"C:\windows-1256.txt", false, Encoding.GetEncoding("windows-1256"));
    sw.Write(str);
    sw.Flush();
    sw.Close();

但是,我不知道如何在 C# 中使用此演示文稿正确转换文件。

4

3 回答 3

5

是的,您的字符串包含许多无法在 1256 代码页中表示的连字。您必须在写入之前分解字符串。像这样:

  str = str.Normalize(NormalizationForm.FormKD);
  st.Write(str);
于 2010-09-21T08:58:04.553 回答
3

给出更一般的答案:

  • Windows-1256 编码是过时的 8 位字符编码。它只有 256 个字符,其中只有 60 个是阿拉伯字母。

  • Unicode 具有更广泛的字符范围。特别是,它包含:

    • “普通”阿拉伯字符,U+0600 到 U+06FF。这些应该用于普通的阿拉伯语文本,包括用其他使用阿拉伯语脚本的语言编写的文本,例如波斯语。例如,“لا”是 U+0644 (ل) 后跟 U+0627 (ا)。

    • “Presentation Form”字符,U+FB50 到 U+FDFF(“Presentation Forms-A”)和 U+FE70 到 U+FEFF(“Presentation Forms-B”)。这些不适用于表示阿拉伯文本。它们主要是为了兼容,尤其是字体文件格式需要为每个字符的每种不同的连接形式和连接字符组合提供单独的代码点。“لا”连字由单个代码点 (U+FEFB) 表示,尽管它是两个字符。

  • 当编码Windows-1256 时,Windows-1256 的 .NET 编码会自动将 Presentation Forms 块中的字符转换为“普通文本” ,因为它别无选择(当然除了将其全部变成问号)。出于显而易见的原因,它只能对实际具有“等价物”的字符执行此操作。

  • Windows-1256解码时, Windows-1256 的 .NET 编码将始终从“普通文本”块生成字符。

正如我们所发现的,您的输入文件包含在 Windows-1256 中无法表示的字符。这些字符将变成问号 ( ?)。此外,那些具有普通文本等价物的 Presentation-Form 字符将改变它们的连接行为,因为这是普通阿拉伯文本所做的。

于 2010-09-21T08:48:23.790 回答
0

首先,您引用的两个字符不是来自阿拉伯语演示文稿块。它们是\x0644\x0627,它们来自标准的阿拉伯语块。但是,为了确保我尝试了字符\xFEFB,它Presentation Forms 块中 لا 的“等效”(不等效,但你知道)字符,即使这样它也能正常工作。

其次,我假设您的意思是编码Windows-1256,它用于传统的 8 位阿拉伯文本。

所以我尝试了以下方法:

var input = "لا";
var encoding = Encoding.GetEncoding("windows-1256");
var result = encoding.GetBytes(input);
Console.WriteLine(string.Join(", ", result));

我得到的输出是225, 199. 所以让我们试着把它转回来:

var bytes = new byte[] { 225, 199 };
var result2 = encoding.GetString(bytes);
Console.WriteLine(result2);

很公平,控制台没有正确显示结果——但调试器中的 Watch 窗口告诉我答案是正确的(它显示“لا”)。我也可以从控制台复制输出,它在剪贴板中是正确的。

因此,Windows-1256 编码工作得很好,不清楚你的问题是什么。

我的建议:

  • 写一小段代码来展示这个问题。

  • 用那段代码发布一个新问题。

  • 在那个问题中,准确描述你得到的结果,以及你期望得到的结果。

于 2010-09-21T07:52:12.273 回答