【问题标题】:Problem of displaying Russian texts in a tool. (UTF8)在工具中显示俄语文本的问题。 (UTF8)
【发布时间】:2020-09-16 19:36:28
【问题描述】:

从昨天开始,我在我的一个工具中显示俄语文本时遇到了问题。

我正在使用以下代码,它显示了项目的名称:

public static string LocalizedName(LocalizedNames localizedNames, string currentLanguage = null, string alternativeName = "NO_ITEM_NAME")
    {
        if (localizedNames == null)
            return alternativeName;

        if (string.IsNullOrEmpty(currentLanguage))
            currentLanguage = LanguageController.CurrentCultureInfo.TextInfo.CultureName.ToUpper();

        switch (FrequentlyValues.GameLanguages.FirstOrDefault(x => string.Equals(x.Value, currentLanguage, StringComparison.CurrentCultureIgnoreCase)).Key)
        {
            case GameLanguage.UnitedStates:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.EnUs ?? alternativeName));
            case GameLanguage.Germany:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.DeDe ?? alternativeName));
            case GameLanguage.Russia:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.RuRu ?? alternativeName));
            case GameLanguage.Poland:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.PlPl ?? alternativeName));
            case GameLanguage.Brazil:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.PtBr ?? alternativeName));
            case GameLanguage.France:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.FrFr ?? alternativeName));
            case GameLanguage.Spain:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.EsEs ?? alternativeName));
            case GameLanguage.Chinese:
                return Encoding.UTF8.GetString(Encoding.Default.GetBytes(localizedNames.ZhCn ?? alternativeName));
            default:
                return alternativeName;
        }
    }

这里是该工具的链接,用于测试它:https://github.com/Triky313/AlbionOnline-StatisticsAnalysis

对我来说,所有语言都正确显示(德国),但俄罗斯的其他人只能看到错误文本。

编辑: 这里是项目列表文件的一部分:

` "LocalizedNames": {
"EN-US": "Hideout Construction Kit",
"DE-DE": "Unterschlupf-Baukasten",
"FR-FR": "Kit de construction de repaire",
"RU-RU": "Ðабор Ð´Ð»Ñ Ð¿Ð¾Ñтройки убежища",
"PL-PL": "Zestaw do budowy Kryjówki",
"ES-ES": "Kit de construcción de Escondites",
"PT-BR": "Kit de Construção de Esconderijo",
"ZH-CN": "è—身地堡建筑工具包",
"KO-KR": "ì€ì‹ ì²˜ 건설키트" }, `

文件将从这个网址下载:

https://raw.githubusercontent.com/broderickhyman/ao-bin-dumps/master/formatted/items.json

有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 由于在某些元素中俄语文本显示没有问题,因此似乎是控件中的问题没有正确显示文本。
  • 你应该得到这个包的来源,看看里面,Имя栏是如何实现的。
  • Encoding.UTF8.GetString(Encoding.Default.GetBytes(…)) 没有任何意义,因为这意味着您有一个 UTF-16 Unicode 字符串(因为 .NET 将其字符串存储在 UTF-16 中),应将其转换为计算机的 ANSI 编码(这就是 Encoding.Default 是)字节,然后应将其解码为 UTF-8。这是行不通的,或者更确切地说,它只适用于 UTF-8 的公共子集和你的 ANSI 编码,它们是由英文字母和数字组成的低 128 个代码点。所以难怪俄语字符会产生乱码输出——中文也是如此。
  • LocalizedNames 已经以错误方式填充这些问题的根源。您需要从最初获取这些字符串的源头为每种语言提供正确的编码。所以请展示一下,你在哪里实际分离了你放入 LocalizedNames 的字符串。
  • 编辑帖子并添加源文件。

标签: c# .net wpf utf-8 localization


【解决方案1】:

您的代码所做的是将 .NET 编码为 UTF-16 的字符串,将这些字符串转换为您计算机的 ANSI 编码 (= Encoding.Default) 字节,然后将其解码为 UTF-8。此往返只会为 UTF-8 的公共子集和您的 ANSI 编码产生有效结果,它们是由英文字母和数字组成的低 128 个代码点。俄语、中文、韩语等除此之外的所有内容都会变成乱码。

您的源是存储为 UTF-8 的 JSON 文件。

但是在您的代码中,您使用WebClient.DownloadStringTaskAsync,它使用WebClient.Encoding 来决定如何将下载的流转换为字符串。该文档写道,它默认为Encoding.Default,这通常很糟糕,因为这取决于您的计算机的配置方式。在德语语言环境Encoding.Default 的计算机上是Windows-1252/ISO-8859-15,在英语语言环境下是ISO-8859-1,在俄语计算机上可能是KOI8R,等等。这意味着使用 Encoding.Default 的代码是不可移植的,甚至是 documentation warns not to use it。

解决这组WebClient.Encoding 到Encoding.UTF8。或者更好:使用 HttpClient 代替,因为 WebClient 已被弃用近 10 年。

之后删除所有 Encoding.UTF8.GetString(Encoding.Default.GetBytes(...)) 实例,因为不再需要这些实例。

【讨论】:

    【解决方案2】:

    问题出在其他地方。该文件以 UTF8 格式保存,而不是默认保存。

    File.WriteAllText($"{AppDomain.CurrentDomain.BaseDirectory}{Settings.Default.ItemListFileName}", itemsString, Encoding.Default);
    

    在 Encoding.UTF8 之前。

    感谢您的帮助。 :)

    【讨论】:

    • 请看我的回答,为什么永远不应该使用Encoding.Default,为什么连微软自己的文档都警告不要使用它。
    • @ckuri:完全被忽视了,抱歉。感谢您的好解决方案,我会调整和改变日子。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多