.NET WASM 全球化 ICU 数据加载实战指南:icudt 分片文件、自定义构建与 Blazor 配置
.NET WASM 全球化 ICU 数据加载实战指南icudt 分片文件、自定义构建与 Blazor 配置【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime导读在 WebAssemblyWASM应用场景下.NET 运行时无法像桌面端那样依赖操作系统自带的 ICUInternational Components for Unicode数据而是需要把区域设置culture数据文件随应用一起打包加载。本文以 dotnet/runtime 仓库的 WASM Globalization Icu 设计文档 为主线系统讲解icudt*.dat四种数据分片的区别、WasmIcuDataFileName/BlazorIcuDataFileName/BlazorWebAssemblyLoadAllGlobalizationData等 MSBuild 属性的用法、如何利用dotnet/icu仓库裁剪出自定义 ICU 数据文件并结合仓库中的构建目标文件与自动化测试源码验证行为细节。读完本文你将能够在 WASM Console、WASM Browser 与 Blazor WebAssembly 项目中精准控制全球化数据的体积与加载策略。背景WASM 场景下 ICU 数据的特殊性在传统桌面与服务器场景中.NET 的全球化功能依赖操作系统提供的 ICU 数据Linux 上通常以libicu包提供约 28 MBWindows 与 macOS 作为系统组件内置。但在 WASM 应用中运行时运行在浏览器等沙箱环境里既没有操作系统级的 ICU 数据可用也不可能打包体积过大的完整数据因此必须采用随应用携带数据文件的策略。与之配套的还有 Globalization Invariant Mode全球化不变模式当InvariantGlobalization开启时应用完全不加载任何 ICU 数据改用简化行为如仅支持 ASCII 大小写转换、字符串比较退化为 ordinal 序数比较、日期时间使用固定格式等适用于对全球化正确性要求不高、但极度在意包体大小的场景。当不变模式关闭默认时WASM 应用就需要加载 ICU 数据文件这正是本文讨论的icudt*.dat文件体系。四种 ICU 数据分片按需裁剪区域数据仓库文档明确了四类基础数据文件它们是对完整 ICU 数据的区域子集裁剪sharding文件包含的区域locale适用场景icudt.dat全部数据需要完整全球化能力的应用icudt_EFIGS.daten-*、fr-FR、es-ES、it-IT、de-DE主要面向英语及法、意、德、西等欧洲语言应用icudt_CJK.daten、ja、ko、zh面向中日韩CJK用户icudt_no_CJK.daticudt.dat的全部区域但排除ja、ko、zh需要全量区域但不含 CJK 的应用这种分片设计让开发者可以在数据完整性与包体大小之间做权衡例如一个只面向英语用户的工具类应用加载icudt_EFIGS.dat即可而面向中文、日文、韩文用户的应用则应选择icudt_CJK.dat。在仓库的自动化测试中各分片包含的区域范围被直接验证。见 IcuTestsBase.cs例如 EFIGS 分片测试覆盖en-US、fr-FR、es-ES并断言pl-PL、ko-KR、cs-CZ等不在分片内的区域会回退到en-US的星期日名称SundayCJK 分片测试覆盖zh-CN、ja-JP并断言fr-FR、hr-HR、it-IT回退no_CJK分片则验证en-AU、fr-FR、sk-SK正常、而ja-JP、ko-KR、zh-CN回退。这从测试层面印证了上述分片表的行为。Wasm Console 与 Wasm Browser用 WasmIcuDataFileName 指定数据文件对于 WASM 控制台应用与 WASM 浏览器应用可以通过在.csproj中添加 MSBuild 属性来指定要加载的数据文件WasmIcuDataFileNameicudt_no_CJK.dat/WasmIcuDataFileName使用要点如下只能设置一个值WasmIcuDataFileName不接受多个文件每次构建只加载一个数据文件。支持自定义文件该属性可以指向开发者自行构建的 ICU 数据文件构建方法见下文自定义 ICU一节文件名不限于四种内置分片。未指定时的自动匹配如果不设置WasmIcuDataFileName构建系统会根据应用当前 culture 自动选择对应分片并加载。例如应用文化为en-US时加载icudt_EFIGS.dat为zh-CN时加载icudt_CJK.dat。相关 MSBuild 属性的完整语义在仓库的 WASM 构建目标文件 WasmApp.Common.targets 中对 ICU 相关属性有明确注释两个属性配合使用WasmIncludeFullIcuData—— 加载完整 ICU 数据icudt.dat默认值为false仅当InvariantGlobalizationfalse时生效。WasmIcuDataFileName—— 指定要加载的 ICU 全球化数据文件名/路径仅当InvariantGlobalizationfalse且WasmIncludeFullIcuDatafalse时生效。因此三者的优先级关系为InvariantGlobalizationtrue不加载任何数据WasmIncludeFullIcuDatatrue加载全量icudt.datWasmIcuDataFileName加载指定分片或自定义文件 均未设置按应用 culture 自动匹配分片。这一点也与测试 IcuTests.cs 中的验证逻辑一致测试通过组合InvariantGlobalization与BlazorWebAssemblyLoadAllGlobalizationData两个开关断言不变模式下所有区域缺失、非不变模式下按分片或全量数据返回正确的本地化星期日名称。自定义 ICU 数据文件从 dotnet/icu 仓库裁剪当四种内置分片都无法满足需求时开发者可以自行构建自定义 ICU 数据文件。构建入口与过滤器最便捷的方式是在 Codespaces 中打开dotnet/icu仓库可参考仓库的 Codespaces 使用说明。该仓库的icu-filters目录下存放着过滤器文件构建系统会据此对 ICU 数据进行 locale slicing区域切片。构建前建议先阅读 ICU 官方用户手册中关于Locale Slicing构建工具的章节了解过滤器语法。eng/icu.mk文件用于选择要构建哪些过滤器。裁剪过滤器的重要建议来自仓库设计文档务必遵守只通过增删localeFilter/includelist中的区域来编辑过滤器避免误删其他关键数据如脚本、日历、数字格式等非区域维度的数据。强烈建议不要把en-US从localeFilter/includelist中移除因为它被用作回退fallback区域。移除它会引发两类后果当设置了PredefinedCulturesOnlytrue/PredefinedCulturesOnly时抛出Encountered infinite recursion while looking for resource in System.Private.Corelib.异常无限递归查找资源当未启用 PredefinedCulturesOnly 时运行时将从 ICU 的root.txt文件解析数据导致本地化结果退化例如CultureInfo.DateTimeFormat.GetDayName(DateTime.Today.DayOfWeek)只返回缩写形式Mon而不是完整的Monday。若删除了特定功能数据运行时可能抛出以[CultureData.IcuGetLocaleInfo(LocaleStringData)] Failed开头的异常含义是你删除了提取区域基本信息所必需的数据。为浏览器构建Browser / wasm前置条件运行.devcontainer/postCreateCommand.sh若使用 Codespaces容器创建时会自动执行。构建命令./build.sh /p:TargetOSBrowser /p:TargetArchitecturewasm输出位置artifacts/bin/icu-browser-wasm。为移动端构建Mobiles / Android前置条件先准备 Android NDK文档给出的步骤如下export ANDROID_NDK_ROOT$PWD/artifacts/ndk/ mkdir $ANDROID_NDK_ROOT wget https://dl.google.com/android/repository/android-ndk-r25b-linux.zip unzip android-ndk-r25b-linux.zip -d $ANDROID_NDK_ROOT rm android-ndk-r25b-linux.zip mv $ANDROID_NDK_ROOT/*/* $ANDROID_NDK_ROOT rmdir $ANDROID_NDK_ROOT/android-ndk-r25b构建命令./build.sh /p:TargetOSAndroid /p:TargetArchitecturex64输出位置两类构建Browser 与 Android的输出均位于artifacts/bin的子目录中。在项目中引用自定义数据文件把生成的.dat文件复制到项目目录然后在.csproj中给出路径支持相对路径与绝对路径两种写法!-- 相对路径 -- WasmIcuDataFileNameicudt_custom.dat/WasmIcuDataFileName !-- 绝对路径$(MSBuildThisFileDirectory) 指向 .csproj 所在目录 -- WasmIcuDataFileName$(MSBuildThisFileDirectory)icudt_custom.dat/WasmIcuDataFileName仓库测试对自定义文件的预期行为做了详细建模。见 IcuTestsBase.cs测试用自定义文件icudt_custom.dat只包含cy-GB、is-IS、bs-BA、lb-LU四个区域以及回退区域en-US随后断言这四者的星期日名称Dydd Sul、sunnudagur、nedjelja、Sonndeg能被正确解析而fr-FR、hr-HR、ko-KR等未包含区域回退到en-US的Sunday。Blazor WebAssembly按文化加载与全量数据开关Blazor WebAssembly 场景下数据文件的加载策略有所不同。默认行为按应用文化加载Blazor 应用默认基于应用当前的 culture 加载对应分片文件与 WASM Console/Browser 的自动匹配逻辑一致。强制加载全量数据如果希望无论应用文化如何都加载完整 ICU 数据在.csproj中添加BlazorWebAssemblyLoadAllGlobalizationDatatrue/BlazorWebAssemblyLoadAllGlobalizationData加载自定义文件Blazor 加载自定义文件时使用BlazorIcuDataFileName属性取值同样可以是相对路径或完整路径写法与WasmIcuDataFileName一致。但有一个硬性限制Blazor 只支持加载文件名以icudt开头的文件例如icudt_custom.dat。这一限制在测试中有明确断言见 IcuTests.cs 的NonExistingCustomFileAssertError测试它覆盖了两种错误场景文件不存在如icudtNonExisting.dat构建报错Could not find $(BlazorIcuDataFileName)..., or when used as a path relative to the runtime pack提示查找失败该文件既不在项目目录也不在 runtime pack 的相对路径下。文件名不合规如incorrectName.dat构建报错File name in $(BlazorIcuDataFileName) has to start with icudt.即文件名必须以icudt开头。另外测试 FullIcuFromRuntimePackWithCustomIcu 还验证了一个属性优先级细节当BlazorWebAssemblyLoadAllGlobalizationData设为true时BlazorIcuDataFileName不再生效构建输出会给出警告$(BlazorIcuDataFileName) has no effect when $(BlazorWebAssemblyLoadAllGlobalizationData) is set to true.。这提醒我们全量数据开关优先于自定义文件属性二者不应同时使用。行为验证用仓库测试理解运行时语义仓库在 src/mono/wasm/Wasm.Build.Tests 目录下提供了完整的 ICU 相关集成测试可作为理解运行时行为的权威参考IcuTests.cs覆盖不变模式 vs 全量数据、自定义文件 vs 全量数据优先级、非法文件名与文件不存在等错误路径。IcuTestsBase.cs定义了各类分片EFIGS / CJK / no_CJK / full / custom的测试区域清单以及测试程序模板 —— 通过new CultureInfo(code)构造文化与culture.DateTimeFormat.GetDayName(...)读取本地化星期日名称并对比期望值。IcuShardingTests2.cs针对分片shard加载行为的分片级测试。GlobalizationMode.cs定义Invariant、FullIcu、Sharded、Custom等全局化模式枚举供测试驱动不同加载策略。测试程序的核心断言逻辑见 IcuTestsBase.cs值得留意当目标区域不在已加载数据分片中时若PredefinedCulturesOnly未开启new CultureInfo(code)不会抛异常但所有数据如星期日名称都会回退到en-US的值而一旦开启PredefinedCulturesOnlytrue构造不在数据中的区域会直接抛出CultureNotFoundException。这正好呼应了设计文档中关于移除en-US回退区域后出现异常与数据退化的警告。配置速查与注意事项将上文要点汇总为一份速查表场景MSBuild 属性说明WASM Console/Browser 指定文件WasmIcuDataFileName只能设一个值支持自定义.datInvariantGlobalizationfalse且WasmIncludeFullIcuDatafalse时生效WASM Console/Browser 加载全量数据WasmIncludeFullIcuData默认false置true时加载icudt.datWASM 应用开启不变模式InvariantGlobalization置true时不加载任何 ICU 数据相关属性全部失效Blazor 强制全量数据BlazorWebAssemblyLoadAllGlobalizationData置true时忽略BlazorIcuDataFileNameBlazor 加载自定义文件BlazorIcuDataFileName文件名必须以icudt开头支持相对/绝对路径除项目文件外不变模式还可以通过 runtimeconfig.json 的System.Globalization.Invariant配置或DOTNET_SYSTEM_GLOBALIZATION_INVARIANT环境变量开启且项目文件/runtimeconfig 中的设置优先级高于环境变量PredefinedCulturesOnly则控制缺失区域是抛异常还是回退到不变文化/root.txt数据。深入理解这两者与 ICU 数据加载的交互可阅读 Globalization Invariant Mode 设计文档。最后提醒自定义 ICU 数据裁剪时务必保留en-US回退区域、只增删includelist中的区域否则轻则出现Mon这类缩写退化、重则抛出Encountered infinite recursion ...或[CultureData.IcuGetLocaleInfo(LocaleStringData)] Failed异常。在调整分片与属性组合后建议参照仓库 IcuTestsBase.cs 的断言模式用CultureInfoDateTimeFormat.GetDayName对目标区域逐一验证本地化输出确保裁剪结果符合预期。【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

红外热像与关联规则挖掘:变压器套管内部放电的精准诊断

红外热像与关联规则挖掘:变压器套管内部放电的精准诊断

简介:基于红外检测技术的电力系统变压器套管绝缘缺陷故障检测,是一篇面向电力系统状态监测与带电检测领域的技术文献,针对套管在长期运行中可能出现的绝缘老化、损伤及缺陷故障,提出融合三维重构、模糊特征辨识、关联规则挖掘、信…

2026/9/18 22:38:45 阅读更多 →
本地知识库问答系统部署指南:Ollama+FAISS+Rerank+LLM全链路实践

本地知识库问答系统部署指南:Ollama+FAISS+Rerank+LLM全链路实践

如果你现在的目标非常明确,就是要在自己的机器上把一套本地知识库问答系统跑起来,那Ollama FAISS Embedding Rerank LLM这套组合目前是所有方案里最值得照着我抄作业的。我最近一个月把整条链路从零到一完整部署了至少三遍,踩遍了 Ollama…

2026/9/18 22:37:45 阅读更多 →
Mapster 构造函数映射指南:用 ConstructUsing 与 MapToConstructor 掌控目标对象创建

Mapster 构造函数映射指南:用 ConstructUsing 与 MapToConstructor 掌控目标对象创建

Mapster 构造函数映射指南:用 ConstructUsing 与 MapToConstructor 掌控目标对象创建 【免费下载链接】Mapster A fast, fun and stimulating object to object Mapper 项目地址: https://gitcode.com/GitHub_Trending/ma/Mapster Mapster 默认通过无参构造函…

2026/9/18 22:37:45 阅读更多 →

最新新闻

Glances 事件动作(Actions):基于 Mustache 模板的告警自动化配置完全指南

Glances 事件动作(Actions):基于 Mustache 模板的告警自动化配置完全指南

指标监控监控大盘CLI告警MCP 服务 【免费下载链接】glances Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, macOS and Windows operating systems. 项目地址: https://gitcode.com/gh_mirrors/gl/glances 点击查看 免费下载 导读&am…

2026/9/20 0:56:10 阅读更多 →
Glances vms 插件深度指南:用 Multipass 与 Virsh 引擎实时监控宿主机虚拟机

Glances vms 插件深度指南:用 Multipass 与 Virsh 引擎实时监控宿主机虚拟机

Glances vms 插件深度指南:用 Multipass 与 Virsh 引擎实时监控宿主机虚拟机 【免费下载链接】glances Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, macOS and Windows operating systems. 项目地址: https://gitcode.com/gh_mir…

2026/9/20 0:56:10 阅读更多 →
Hugo 短代码方法指南:Name 方法 —— 短代码文件名的获取、错误报告与源码实现

Hugo 短代码方法指南:Name 方法 —— 短代码文件名的获取、错误报告与源码实现

开发工具前端CLI 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址: https://gitcode.com/gh_mirrors/hu/hugo 点击查看 免费下载 导读 Name 是 Hugo 短代码(Shortcode)模板上下文 ShortcodeWithPage…

2026/9/20 0:56:10 阅读更多 →
Ray 嵌套任务(Nested Tasks)指南:用远程任务实现递归式嵌套并行

Ray 嵌套任务(Nested Tasks)指南:用远程任务实现递归式嵌套并行

人工智能分布式训练强化学习任务调度模型推理服务 【免费下载链接】ray Ray is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads. 项目地址: https://gitcode.com/gh_mirrors/ra/ray 点…

2026/9/20 0:56:10 阅读更多 →
非结构化数据存储安全管理:CAS/ECAS原理与防扩散实践

非结构化数据存储安全管理:CAS/ECAS原理与防扩散实践

简介:《企业非结构化数据存储和安全管控解决方案》是一份可直接复用的专业PPT资源,面向企业IT规划、存储架构设计及数据安全管理人员,解决非结构化数据“存储难、管理难、防扩散难”的典型问题。压缩包内共1个pptx文件,大小14.64M…

2026/9/20 0:55:10 阅读更多 →
从fetch到SSE:AI流式响应逐字解析实战指南

从fetch到SSE:AI流式响应逐字解析实战指南

1. 流式响应到底解决了什么问题做过 AI 对话产品的同学大概率都遇到过这个场景:用户点下发送按钮,然后盯着屏幕等上七八秒,界面纹丝不动,直到模型把整段回答全部生成完毕,才“啪”地一下整块文字蹦出来。体验上非常割裂…

2026/9/20 0:55:10 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →