我遇到了一个问题而无法解决问题。
我有这段代码:
public List<NavigationModul> LoadNavigation()
{
byte[] navBytes = NavigationResources.Navigation;
var encoding = GetEncoding(navBytes);
string json = encoding.GetString(navBytes);
List<NavigationModul> navigation = JsonConvert.DeserializeObject<List<NavigationModul>>(json);
return navigation;
}
public static Encoding GetEncoding(byte [] textBytes)
{
if (textBytes[0] == 0x2b && textBytes[1] == 0x2f && textBytes[2] == 0x76) return Encoding.UTF7;
if (textBytes[0] == 0xef && textBytes[1] == 0xbb && textBytes[2] == 0xbf) return Encoding.UTF8;
if (textBytes[0] == 0xff && textBytes[1] == 0xfe) return Encoding.Unicode; //UTF-16LE
if (textBytes[0] == 0xfe && textBytes[1] == 0xff) return Encoding.BigEndianUnicode; //UTF-16BE
if (textBytes[0] == 0 && textBytes[1] == 0 && textBytes[2] == 0xfe && textBytes[3] == 0xff) return Encoding.UTF32;
return Encoding.ASCII;
}
目标是从ResourceFile加载嵌入式Json文件(NavigationResources.Navigation)。导航文件是嵌入式文件。我们只是在使用ResourceManager来避免使用Magic字符串。
在加载嵌入文件的字节并检查其编码后,我现在从文件中读取String并将其传递给JsonConverter.DeserializeObject函数。
但不幸的是,由于无效的Json,这失败了。长话短说:加载的json字符串仍然包含编码标识字节。我无法弄清楚如何摆脱它。
我还尝试在加载字符串之前将utf8 bytearray转换为默认编码,但这只会使编码字节成为可见字符。
我和同行交谈过,他们告诉我他们在阅读嵌入式批处理文件时遇到了同样的问题,导致批处理文件损坏。他们也不知道如何解决问题,但想出了批处理文件本身的解决方法(在批处理文件中添加一个空行以使其工作)
有关如何解决此问题的任何建议吗?
答案 0 :(得分:1)
感谢Alex K.我有一个解决方案:
在调用Encoding.GetString之前屏蔽了标识字节。
这是我现在用来执行任务的功能:
public static string GetStringFromEncodedBytes(byte[] bytes) {
Encoding encoding = Encoding.Default;
int skipBytes = 0;
if (bytes[0] == 0x2b && bytes[1] == 0x2f && bytes[2] == 0x76) {
encoding = Encoding.UTF7;
skipBytes = 3;
}
if (bytes[0] == 0xef && bytes[1] == 0xbb && bytes[2] == 0xbf)
{
encoding = Encoding.UTF8;
skipBytes = 3;
}
if (bytes[0] == 0xff && bytes[1] == 0xfe)
{
encoding = Encoding.Unicode;
skipBytes = 2;
}
if (bytes[0] == 0xfe && bytes[1] == 0xff)
{
encoding = Encoding.BigEndianUnicode;
skipBytes = 2;
}
if (bytes[0] == 0 && bytes[1] == 0 && bytes[2] == 0xfe && bytes[3] == 0xff)
{
encoding = Encoding.UTF32;
skipBytes = 4;
}
return encoding.GetString(bytes.Skip(skipBytes).ToArray());
}
答案 1 :(得分:0)
这是一种更简单的方法,在解码后删除BOM :
// Your data is always in UTF-8 apparently, so just rely on that.
string text = Encoding.UTF8.GetString(data);
if (text.StartsWith("\ufeff"))
{
text = text.Substring(1);
}
当然,这有复制字符串的缺点。
或者如果你做想要跳过字节:
// Again, we're assuming UTF-8
int start = data.Length >= 3 && data[0] == 0xef &&
data[1] == 0xbb && data[2] == 0xbf)
? 3 : 0;
string text = Encoding.UTF8.GetString(data, start, data.Length - start);
这样您就不需要使用Skip
和ToArray
,也可以避免进行任何无关的复制。