导入与导出
词库、短语、方案包、整机备份的导入导出入口、文件格式与合并策略,含 WindDict / Rime / TSV 格式规范
清风的数据流转分成两类:文本类(词库、短语)直接导出为可读的 .wdict.yaml;聚合类(方案包、整机备份)打包为自描述的 .zip。这个分层决定了下面每一节的形态——文本类可以手工编辑、可以用 Git 管,聚合类则带清单、带校验、带合并策略。
所有文本类格式一律要求 UTF-8 编码
本页涉及的文本文件——WindDict、Rime .dict.yaml、TSV 文本、纯词列表 .txt——导入时都按 UTF-8 读取,非 UTF-8 编码(如 GBK、ANSI)会直接读取失败,不会尝试探测或转码。带 UTF-8 BOM 的文件会被自动剥除,无需手动处理;但用记事本等编辑器另存时要显式选择「UTF-8」而非系统默认的「ANSI」。
行尾不限:LF(\n)、CRLF(\r\n)、以及仅 CR(\r,2001 年以前的 Mac OS 约定)都能正确按行切分,导入端在入口统一折成 \n,不需要你事先转换。
总览
| 数据 | 导出格式 | 导入可接受 | 入口 |
|---|---|---|---|
| 方案词库(用户词 / 临时词 / 词频 / 候选调整) | WindDict .wdict.yaml(多段可选) | WindDict、Rime .dict.yaml、TSV 文本、纯词列表 .txt(自动出码)0.116 新增 | 设置 → 词库 |
| 快捷短语 | WindDict .wdict.yaml | WindDict | 设置 → 词库 → 快捷短语 |
| 方案包(方案 + 引用资源) | .zip(零层级) | .zip / .wpkg 0.118 新增 | 设置 → 方案,或高级 → 导入 |
| 配置片段(配置项子集) | —— | .toml 文件 / 剪贴板文本 0.118 新增 | 设置 → 高级 → 导入 |
| 方案文本(小方案纯文本) | —— | 剪贴板文本 0.118 新增 | 设置 → 高级 → 导入 |
| 整机备份(全部用户数据) | .zip(带 manifest.toml) | .zip | 设置 → 高级 → 备份与还原 |
| 主题 | —— | .toml 文件 / HTTPS 链接 | 设置 → 外观 → 获取更多主题 |
三个入口互不通用
方案包与整机备份都是 .zip,但格式完全不同,各自的导入端都会识别并拒绝对方:备份页选到方案包会提示「该文件不是整机备份包」,方案页选到备份包会提示「该文件是整机备份包或旧格式归档」。
WindDict 文件格式(.wdict.yaml)
词库与短语的导出格式。一个文件 = YAML 头 + 若干 TSV 数据段,段与段之间用 --- !段名 分隔。
# WindInput 用户数据文件
wind_dict:
version: 1
generator: WindInput
exported_at: 2026-08-03T10:00:00+08:00
schema_id: wubi86
engine_type: codetable
sections:
words:
columns: [code, text, weight, count]
freq:
columns: [code, text, count, last_used]
--- !words
a 工 9999 42
ggll 五笔字型 500 0
--- !freq
def 有 7 1754186400头部字段
| 字段 | 必需 | 说明 |
|---|---|---|
wind_dict: | 是 | 格式标识。头部没有这一行就不认 |
version | 是 | 格式版本,当前只认 1;其它值直接报错 |
generator | 否 | 生成方,导出恒写 WindInput |
exported_at | 否 | 导出时间(RFC 3339) |
schema_id | 否 | 来源方案 ID,供导入端显示 |
engine_type | 否 | 来源引擎类型(codetable / pinyin / mixed),导入时用于跨类型校验,见下 |
sections | 否 | 各段的列声明;缺失则按该段的默认列解析 |
数据段与列
段标签写作 --- !段名,段内每行一条记录,字段用制表符分隔。文件可以只含其中几段,导入端只处理实际存在的段。
| 段标签 | 内容 | 默认列 |
|---|---|---|
words | 用户词库 | code, text, weight, count |
temp_words | 临时词库(自动造词的暂存区) | code, text, weight, count |
freq | 词频记录 | code, text, count, last_used |
shadow | 候选调整(置顶 / 隐藏) | action, code, word, position, cand_id |
phrases | 快捷短语 | code, text, weight, position, enabled |
各列语义:
weight—— 静态排序分;count—— 选词次数(调频热度),导入时取两边较大值合并last_used—— 最近使用时间,秒级时间戳action——pin(固定到position)或del(隐藏);del行的position/cand_id列留空cand_id—— 动态短语的稳定 ID,用于精准匹配同码同文的短语候选;无则留空enabled/ 布尔值一律写1/0
列顺序以头部声明为准
解析时按 sections 里该段声明的 columns 顺序取字段,不是按位置硬编码。因此老版本导出的三列 words 段(没有 count)仍能正确读入,缺失的列回退默认值。
转义规则
TSV 字段内若含以下字符,导出时转义、导入时还原:
| 原字符 | 写作 |
|---|---|
反斜杠 \ | \\ |
| 换行 | \n |
| 制表符 | \t |
不含这三者的字段原样输出,所以绝大多数行是纯明文,肉眼可读、可手改。
命令栏语法的条目($CC / $SS / $AA 与含 {} 的模板)是例外:反斜杠不参与本层转义,原样进出。那条源码里的 \ 由表达式解析独占,这里再转一次就是双重展开,路径会静默坏掉。换行与制表仍要转义——TSV 一条记录一行、Tab 分列,不转就把文件切散了。详见换个地方写,还是两个。
拼音编码带音节空格
拼音方案的 code 列写成带空格的音节码(ni hao 而非 nihao),与 Rime 源词库同形。落库时拆成扁平键 + 音节边界,列结构不变,因此老的无空格文件天然兼容——只是没有边界信息,消费端降级处理。
单音节词往返会丢失边界标记(ni 写出来还是 ni),这是刻意接受的损失:单音节没有切分歧义,且边界缺失在消费端一律是「放行」而非「拒绝」。
导入时补齐边界 0.118 新增
导入拼音方案的词库时,没写空格的行会按「音节数 = 汉字数」自动求解切分。导入对话框给两个选项:
| 选项 | 行为 |
|---|---|
| 由程序补充(默认) | 求出唯一解的补上边界后入库 |
| 不补充 | 这些行整条跳过,不入库 |
切不出唯一解的行(音节数与字数对不上)两种选项下都会被拒绝。导入结果里补齐、跳过、拒绝三个数分开统计。只对拼音方案生效——码表词组码没有音节语义。
容错
- 文件可带 BOM,不影响解析
- 空行跳过;
words/temp_words/freq段字段数少于 2、shadow段少于 3、phrases段少于列数的行计入跳过数 shadow段action不是pin/del,或code/word为空的行跳过- 数字列解析失败回退
0,该行仍然收录,不算跳过 - 文件里出现未知段标签直接忽略
导入结果会逐段回报「新增 / 更新 / 未变 / 跳过」的条数。
词库导入导出
在设置 → 词库页选中方案后操作。
导出:勾选数据类型
导出对话框里勾选要导出的数据类型,全部写进同一个 .wdict.yaml(默认文件名 方案ID-时间戳.wdict.yaml)。可选类型随方案引擎类型变化:
| 方案类型 | 默认导出的段 |
|---|---|
| 码表 | 用户词库、临时词库、词频、候选调整 |
| 拼音 | 用户词库、临时词库、词频、候选调整 0.115 新增 |
| 混输 | 候选调整 |
0.115 之前导出的拼音词库不含候选调整
那时拼音下还不能置顶,这一段本就是空的。但如果你用旧版本导出、在新版本还原,且还原方式选了替换,替换的只是文件里实际带有的段——文件里没有候选调整段,现有规则不会被清掉。
拼音家族共用一份数据
全拼、双拼、混输的拼音子方案在存储上折叠为同一个数据域(pinyin)。导出双拼方案得到的就是整个拼音家族的数据,导入亦然。
导入:格式识别
导入不要求你选格式,按文件内容判定。核心程序(core)先判三种带编码的格式:
| 判据(按顺序) | 判为 |
|---|---|
头部(首个 --- 分隔行之前)含 wind_dict: | WindDict |
存在一整行只有 ... | Rime 词库 |
任一非空、非 # 开头的行含制表符 | TSV 文本 |
| 以上都不满足 | core 判「无法识别」 |
Rime 词库(.dict.yaml) —— 头部到 ... 分隔行为止。列取头部的 columns: 列表,缺声明则用 Rime 默认的 [text, code, weight]。编码列内部空白折叠为单个空格(ni hao → ni hao),空格作为音节真值保留下来。缺 text 或 code 的行跳过;权重支持浮点,截断取整;解析失败回退 0。没有 ... 分隔行则报错。
TSV 文本 —— 每行 编码<TAB>词条[<TAB>权重],# 开头为注释。以下行跳过:列数少于 2、编码或词条为空、编码含非可打印 ASCII(这一条用来拦「词在前、码在后」的列序颠倒文件与乱码文件)。权重列可省,缺省 0。
Rime / TSV 只能导入用户词库
这两种外部格式没有词频、候选调整等概念,导入时一律只写入用户词库一段。要迁移完整数据请用 WindDict 格式。
纯词列表(.txt,一行一个词,自动出码)0.116 新增
前三种格式都要求文件里显式写出编码。纯词列表反过来:文件只有词、没有编码,导入时按你选的目标方案现场生成编码。这一档的识别与出码调度在设置页本地完成,不是 core 的 detect_dict_format 判据之一——core 会把这类文件判为「无法识别」,是设置页在把文件交给 core 之前先自行复核,通过则转成 TSV 后再走既有的 TSV 导入通道。
中国
计算机
人工智能识别判据:非空、非 # 开头的行里,「像词」的行占比需 ≥ 90%,否则仍按「无法识别」处理。「像词」= 全部由 CJK 表意文字组成、长度 ≤ 12 字、行内不含空白。真实词表常夹带标题、分隔线一类噪声行,10% 的容错额度就是留给这些行的——它们不会拖累整份文件被拒绝,但过了整体判据后,逐行过滤仍会把它们计入下面的「跳过」。
不做一行多词的切分
你好 世界 究竟是一个词条还是两个,无法从文件本身判定——含内部空白、含非 CJK 字符(含中英文标点、全角字符、假名、谚文)、超过 12 字的行一律按「不像词」跳过,不会被拆成多个词。要导入多个词,请每行一个。
选完文件后,设置页即时给出回显,例如:
识别为 纯词列表 · 3180 个词(跳过 3 行 · 去重 12) 编码将按「五笔86 · 码表」现场生成,出不了码的词会被跳过。
这一步是纯本地解析,不发 RPC;文件内重复词按首次出现去重,其余计入「去重」。真正的出码发生在点击「合并导入」/「替换导入」时:按每批 1000 词分批调用 dict.encodeWords,出好码的行拼成 编码<TAB>词条<TAB>权重 交给既有 TSV 导入通道处理(因此合并 / 替换语义、去重键与 TSV 完全一致,见下)。分批是为了避开单次 RPC 5 秒超时——大词表不会失败,只是多花几秒。
编码规则与单词加词(cmdbar dict.add)完全一致:拼音方案出的是带空格的音节码(如 ni hao),码表方案按方案的 [[encoder.rules]] 从单字全码组装。生僻字或方案未配拆字规则时可能出不了码,这类词会被跳过,不阻塞其余词导入,导入完成后的提示会报出「出不了码」的数量;若全部词都出不了码,则不会提交导入,直接提示确认目标方案是否选对。
换目标方案要重新导入
纯词列表不带来源编码信息,出码只在点导入的那一刻按当前选中的方案生成一次。切换「导入到」的目标方案不会触发重新出码——需要给另一个方案生成词库,请重新走一遍导入流程。
其余限制与 Rime / TSV 相同:只写入用户词库一段;权重没有列可读,需在对话框的「权重」输入框里自己填一个默认值(这一栏仅纯词列表格式显示);目标方案为混输时不接受,提示与「混输不收用户词库」一致。
格式下拉目前只提供「自动识别」与「纯词列表(自动出码)」两档:前者按上面的判据自动分流,后者用于严格判据误判时手动纠正(比如一份词表里恰好塞了较多噪声行、被判定为「无法识别」)。强制指定 WindDict / Rime / TSV 尚未接入。
跨引擎类型校验
WindDict 文件头带 engine_type 时,导入端会与目标方案比对,不一致直接拒绝:
该文件为「码表」类型词库,与当前「拼音」方案不一致,导入会导致编码错乱,已阻止。
五笔的 ggll 与拼音的 ni hao 属于两套编码域,混进去只会得到一堆永远打不出来的词条。老文件没有这个头部字段时不校验,照常导入。
合并与替换
| 策略 | 语义 |
|---|---|
| 合并导入(默认) | 保留本地已有条目,同键的以导入数据为准更新(count 取两边较大值) |
| 替换导入 | 先清空该方案对应的数据段,再写入 |
去重键:用户词库 / 临时词库 / 词频 / 候选调整为「方案 + 编码 + 文本」,短语为「编码 + 文本」。
导入前会先跑一次预览(不落盘),回报文件含哪些段、各段将新增 / 更新 / 未变 / 跳过多少条,确认后才执行。
快捷短语导入导出
在设置 → 词库 → 快捷短语中导入导出,格式同为 WindDict,只含 phrases 一段(默认文件名 phrases.wdict.yaml)。短语独有 position 列(同编码同权重时的先后),导入会保留该列的值。详见自定义短语。
方案包(.zip)
单个方案连同其引用资源打成的分发包。在设置 → 方案页选中方案后用「导出」/「导入」,也可从高级页统一导入进入。
- 新后缀
.wpkg0.118 新增:格式与.zip完全相同,注册文件关联后可双击导入 - 包内可带随包配置 0.118 新增:把「装上方案」和「配好相关配置」合成一步
- 导出会把你在设置页对该方案做的定制一并折叠进包 0.118 新增:定制指向的词库、双拼布局、字根字体也随包走,对方装上即得到与你一样的方案
包内布局
zip 条目名 = 用户方案目录(schemas/)下的相对路径,没有任何目录前缀,导入时原样落盘、零改写:
package.toml 可选元信息(导出恒写,导入不强制)
wubi86.schema.toml 方案文件(根条目)
wubi86/wubi86_ext.dict.yaml 引用的词库
wubi86/HeiTiZiGen.ttf 引用的字根字体
shuangpin/my_layout.toml 引用的自定义双拼布局零前缀是刻意的:方案文件里对词库、双拼布局、拆字表、字体的引用都是相对路径,保持同样的相对结构,导入端不需要重写任何一条引用。
package.toml
[package]
format_version = 2
app_version = "0.118.0"
platform = "windows"
created_at = "2026-08-03T10:00:00+08:00"
[schema]
id = "wubi86"
version = "1.2"
[refs]
system = ["wubi86/wubi86_jidian.dict.yaml"]
missing = []其余字段可缺省——导入端读不到就显示「未知」。
format_version是包格式版本号 0.118 新增:缺省视为 1(旧格式,照常导入);高于当前程序支持的版本则拒绝导入并提示升级。携带随包配置的包必须声明format_version = 2
[refs] 记录两类不在包内的引用:
system—— 指向程序自带数据目录的引用。这类文件人人都有,不打包,只记路径missing—— 导出时就已经找不到的引用,供接收方排查
资源收集规则
导出时解析方案文件里的全部引用路径,按三类处理:
| 命中位置 | 处理 |
|---|---|
| 用户数据目录 | 打包进 zip |
| 程序自带数据目录 | 记入 refs.system,不打包 |
| 都找不到 | 记入 refs.missing |
词库另有一条约定:引用写的是 x.dict.yaml、但用户目录下只有编译好的 x.wdat 时,打包同名的 .wdat,包内条目名也随之改成 .wdat——否则接收方会得到一个名叫 yaml、内容却是二进制的文件,两头都读不了。
随包配置(config_patch.toml) 0.118 新增
包根目录下可以放一份 config_patch.toml,内容是一份配置片段——方案作者用它把「装方案」和「配好引导键等配置」合成一步:
# 示例:给快符方案接上分号引导键
[keys.key_actions]
semicolon = "special:kf"- 导入确认对话框会多出「将修改的配置」区块,逐项列出「当前值 → 新值」
- 片段有任何一项校验不过,整个包拒绝导入(方案文件也不落)
- 确认后先落方案文件、再应用配置;这份文件本身不会被写进方案目录
- 映射表键(按键功能表等)按逐条并入语义合并,不会清掉用户已有条目
导入判据
- 根目录下有
*.schema.toml→ 认为是方案包(没有package.toml也能导入,方便手工打包) - 根目录下没有任何
.schema.toml→ 拒绝,提示「不是有效的方案包」 - 含
manifest.toml/manifest.json→ 拒绝,提示误选了整机备份包或旧格式归档 format_version高于当前程序支持的版本 → 拒绝,提示升级 0.118 新增- 含
config_patch.toml但没有声明format_version = 2→ 拒绝(旧版程序会把这份文件当死文件落进方案目录,打包方必须声明版本)0.118 新增 - 条目超过 2000 个,或解压后总大小超过 256 MB → 拒绝 0.118 新增(真实方案包远低于此,触发说明包有问题)
导入前预览显示:方案 ID 与版本、创建时间、新增文件 / 已存在 / 系统引用 / 缺失各多少个。随后选择:
- 合并 —— 跳过已存在的同名文件(计入「已存在」数)
- 替换 —— 覆盖同名文件
写盘用「先写临时文件再改名」,中途失败不会留下半个文件(已写完的文件保留,不回滚)。
方案包不含个人数据
方案包只有方案配置与引用资源,不含你的用户词、词频、候选调整。把方案分享给别人不会连带泄露个人输入记录;换机时要带走个人数据请用整机备份。
方案文本 0.118 新增
方案包的纯文本形态:一段 TOML 文本内嵌各文件原文,从剪贴板导入时自动识别。用法见配置分发与导入 · 方案文本,这里只讲格式:
[package]
format_version = 2 # 必填。缺失即拒绝,高于当前支持的版本也拒绝
kind = "schema_text" # 必填。识别标志,没有它整段文本按配置片段处理
[schema] # 可选,供确认对话框免解析显示
id = "kf"
version = "1.0"
[[files]]
path = "kf.schema.toml" # schemas\ 下的相对路径,规则同方案包零前缀布局
content = '''
(文件原文)
'''- 根目录(
path不含/)必须有至少一个*.schema.toml - 可以带
path = "config_patch.toml"条目,语义同方案包的随包配置 - 限制:全文 ≤ 2 MB、最多 64 个文件;路径规则与方案包相同(穿越即拒)
- 生成端注意
content的引号选择:文件内容里出现'''时要换用其他 TOML 字符串写法
导入落盘后与 zip 导入完全一致——文本只是分发形态,存储仍是方案目录下的普通文件。
整机备份(.zip)
设置 → 高级 → 备份与还原。操作流程见备份与还原,这里只讲格式。
manifest.toml
包根目录下的自描述清单,还原前免解压即可读取并显示摘要:
format = "windinput-bundle"
kind = "backup"
spec_version = 1
app_version = "0.114.0"
platform = "windows"
created_at = "2026-08-03T10:00:00+08:00"
[[contents]]
type = "dict"
path = "userdata/user_words/wubi86.wdict"
[contents.meta]
schema = "wubi86"| 字段 | 说明 |
|---|---|
format | 恒为 windinput-bundle,不匹配即拒绝 |
kind | backup(整机备份)。备份页只接受这个值 |
spec_version | 归档格式版本,当前 1。高于当前支持的版本直接拒绝并提示升级清风 |
app_version / platform / created_at | 来源版本、平台(windows / darwin)、创建时间 |
contents | 条目清单:每项的 type、包内 path、可选 meta(如所属方案) |
包内布局
manifest.toml
config/config.toml type="config"
userdata/user_words/<方案>.wdict type="dict" meta.schema
userdata/temp_words/<方案>.wdict type="temp" meta.schema
userdata/freq/<方案>.jsonl type="freq" meta.schema
userdata/shadow/<方案>.jsonl type="shadow" meta.schema
userdata/phrases.wdict type="phrase"
userdata/common_chars.jsonl type="common_chars"
userdata/completions.jsonl type="completion" (0.122 起:邮箱后缀 + 网址历史)
charsets/<字符类>.yaml type="charset"
userdata/stats.jsonl type="stats" (勾选「包含统计数据」时)
userdata/stats_meta.json type="stats_meta" (同上)
schemas/<用户方案目录整树> type="schema_file"
themes/<用户主题目录整树> type="theme_file"
state/state.toml type="state" (勾选「包含界面状态」时)输入补全的学习数据(邮箱后缀与网址历史)自 0.122 起0.122 新增一并进包,两类装在同一个 completions.jsonl 里,每行自带类别。
用户数据逐表导出为文本而非直接搬数据库文件:词库与短语用 WindDict 格式,词频、候选调整、统计用 JSON Lines(每行一个 JSON 对象)。这样跨版本、跨平台都稳,也避开了 Windows 上数据库文件被占用的麻烦。
方案与主题按整目录树原样打包;数据表按方案拆分子目录,归属由 manifest 条目的 meta.schema 标注——因此有数据但已停用的方案也会被备份到。
缓存与日志不进包
%LOCALAPPDATA%\WindInput\ 下的 cache/、logs/ 一律排除:前者可从词库源文件重建,后者无迁移价值。state.toml(窗口位置等界面状态)本机相关,默认也不含,需要时勾选「包含界面状态」。
还原范围与策略
还原时可勾选还原范围,对应清单条目的 type:
| 勾选项 | 覆盖的 type |
|---|---|
| 配置 | config |
| 词库数据 | dict、temp、phrase、freq、shadow |
| 统计 | stats、stats_meta |
| 用户方案 | schema_file |
| 主题 | theme_file |
| 界面状态 | state |
策略在文件域与数据域上语义不同:
| 合并还原 | 替换还原 | |
|---|---|---|
| 文件域(配置、方案、主题、界面状态) | 已存在的文件跳过,计入冲突数 | 覆盖同名文件 |
| 数据域(词库、短语、词频、候选调整) | 逐条 upsert 合并 | 先清空该域再导入 |
| 统计 | 已存在的日期跳过 | 先清空再导入 |
还原完成后自动重载配置、重建短语与受影响方案的缓存,无需重启。
安全限制
所有归档与文本类导入对条目路径做统一守卫,只放行「普通路径段」:拦截 ..、绝对路径、盘符相对路径(C:foo)、UNC 路径,以及段内含冒号的名称(Windows 的 NTFS 备用数据流)。构造恶意包无法把文件写到用户数据目录之外。
从 HTTPS 链接导入主题时会先交给核心程序校验内容再落盘;导入前对话框会提示确认来源可信。
- 方案文本另有全文 2 MB、64 个文件的上限 0.118 新增
windinput://一键安装的方案包下载仅接受 windinput.com 官方域,上限 64 MB,下载后仍走完整的导入确认 0.118 新增
跨平台还原不做自动转换
备份包记录了来源平台,但热键、应用规则里的路径这类平台专属项不会自动转换。从 Windows 的备份还原到 macOS(或反之)时,这些项需要自行复核。
相关阅读
对这篇文档有疑问,或发现内容有误?
欢迎到文档仓库提 issue,写明问题时附上本页链接即可。