C#资源字符串含不同长度无效前缀的原因及解决方法
问题解答
前缀长度不同的原因
当你将文件的Build Action设置为Resource时,Visual Studio会自动将其编译到全局资源文件(.g.resources)或与特定类型关联的.resources文件中。这些字节前缀是.NET资源系统的类型标记头,作用是告诉资源系统如何反序列化对应的资源:
- 不同类型的资源(纯文本文件、RESX中的字符串条目、带格式的资源等)会被添加不同结构的头信息
- 比如纯文本资源的头可能包含换行符、整数类型的长度标识(如
\r\0\0\0);RESX中的特殊字符串资源会包含类型标识字节(如�\u0016)
这些头的长度和内容完全由资源的原始类型、存储方式决定,因此没有固定长度。
正确修剪前缀的方法
不要直接使用ResourceReader.GetResourceData读取原始字节流,推荐使用.NET官方提供的资源读取类自动处理前缀:
方法1:使用ResourceManager读取全局资源
如果资源编译到全局的.g.resources文件中,用ResourceManager可以直接获取处理后的字符串:
var asm = GetType().Assembly; // 全局资源名称格式:程序集名称.g var resourceManager = new ResourceManager($"{asm.GetName().Name}.g", asm); // 直接获取资源内容,自动处理前缀 string text = resourceManager.GetString("textfile1.txt");
方法2:使用ResourceSet读取指定.resources文件
如果资源关联到特定类型的.resources文件,用ResourceSet读取:
var asm = GetType().Assembly; var resourceName = $"{someType.FullName}.resources"; using (var stream = asm.GetManifestResourceStream(resourceName)) using (var resourceSet = new ResourceSet(stream)) { // GetObject会自动反序列化资源,返回正确的字符串 string text = resourceSet.GetObject("textfile1.txt") as string; }
不推荐的手动处理方式(仅作参考)
如果必须手动解析字节流,可以根据resType参数判断资源类型,用对应的序列化方式反序列化:
reader.GetResourceData("textfile1.txt", out string resType, out byte[] bytes); // 判断是否为字符串类型资源 if (resType.Contains("System.String")) { using (var ms = new MemoryStream(bytes)) { // 注意:BinaryFormatter在.NET Core/.NET 5+中已过时,不推荐使用 var formatter = new BinaryFormatter(); string text = formatter.Deserialize(ms) as string; } }
内容的提问来源于stack exchange,提问作者Andrey Bushman
相关产品推荐
相关产品推荐

