piapia123
zh

INI / .properties ↔ JSON 互转

格式化

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

把 INI / `.properties` / `.conf` 这类配置文件转成 JSON,或反过来。两种方言放在一个工具里,用一个选项切换 —— 因为它们本来就是同一种东西的两个变体(`键 = 值` 加注释),而很多文件后缀是 `.conf`,光看后缀分不出该按哪种读。 差别按各自的正典来,不「统一处理」,这是这个工具最要紧的一点: · 引号:INI 里 `key = "值"` 的引号是包裹符号,剥掉;`.properties` 里引号就是普通字符,不剥(Java 的 `Properties` 就是这么读的)。 · 转义与续行:`\uXXXX`、`\n`、行尾反斜杠续行只在 `.properties` 下生效。INI 模式下值原样保留 —— 否则一份含 Windows 路径(`C:\dir\`)的 INI 会被续行规则吃掉一整行。 · 值尾空白:Java 只去掉值前面的空白,尾部保留;INI 两头都去。 另外两个格式本身没有的东西也讲清楚了:重复的键是后者覆盖前者(与 Java 及多数 INI 读取器一致);数组写成重复的键。

功能

  • 两个方向:INI → JSON、JSON → INI,方向可自动判断也可手动指定
  • 两种方言一个选项切换:INI(认 [段]、剥引号)与 .properties(认 ! 注释、空格分隔、转义、续行)
  • 段头 `[db]` 转成嵌套对象;同名的段出现两次会合并,而不是整个替换
  • 嵌套两层以上用点号段名 `[a.b]`;同一路径只写一个段头
  • 重复的键后者覆盖前者,并把被覆盖的键报出来 —— 那是真丢了的数据
  • `.properties` 的 `\uXXXX`、`\n`、`\: ` 转义与续行反斜杠都按 Java 的算法还原
  • 数字只在往返无损耗时转:`port = 5432` 是数字,`zip = 007` 保持字符串
  • `true` / `false` 转成布尔值,`True` / `yes` 保持字符串(不同实现写法不一,不替用户决定)
  • 输出时含换行、首尾空白或以 `#` `;` `!` 开头的值会自动加引号,不会被读成注释
  • JSON → INI 时遇到 null 会报错并指出路径(两种格式都没有 null)
  • 解析错误指出具体位置,而不是一句「格式不对」

使用方法

  1. 把 INI / .properties 或 JSON 粘进输入框 —— 能解析成 JSON 的按 JSON 处理,其余按 INI
  2. 确认「方言」选对了(`.properties` 文件要选第二种,转义与续行才会生效)
  3. 结果实时出现,方向也可以手动指定
  4. 点复制取走结果

常见问题

我该选 INI 还是 .properties?
看这份文件的来源。`.properties` 是 Java 世界的格式(`java.util.Properties`),特点是支持 `\uXXXX` 这类转义、行尾反斜杠续行、`!` 开头的注释,而且值两边的引号是内容而不是包裹符号。INI 是更宽泛的那一类(Windows 的 `.ini`、各种 `.conf`),有 `[段]` 结构,引号是包裹符号。文件后缀是 `.conf` 时看内容:有 `[段]` 就选 INI;出现 `\u` 转义或续行反斜杠就选 `.properties`。选错了的表现是值里多出或少掉反斜杠、引号,而解析本身不报错。
为什么同一个键写了两遍,只有一行留下?
因为重复的键后者覆盖前者是这两种格式的标准行为 —— Java 的 `Properties` 与绝大多数 INI 读取器都是这么读的。这里跟这个约定,但会把被覆盖的键在结果里报出来,因为那确实是丢失了的数据。如果你的本意是「一个键有多个值」,那在 INI 圈子里通行的写法是写成多行重复的键,读取端各自处理 —— 这里导出时用的就是这个约定,但导入时按标准只保留最后一个,所以那条路径是有损的。
数组和 JSON 里的 null 怎么办?
这两种格式都没有数组,也都没有 null。数组导出时写成重复的键(`tags = a` / `tags = b`),这是 INI 圈子里最常见的约定。null 默认会报错并指出是哪一个键,因为在默认行为下这个键会整个消失 —— 你会拿到一份少了一个字段的配置,而不会有任何提示。也可以选「写成空值」或「跳过这个键」。⚠️ 数组里的 null 不能跳过:拿掉一个元素会让后面每一项的下标都变,比报错更糟。
为什么 `port = 5432` 变成了数字,`zip = 007` 却是字符串?
判据是「往返无损耗」:把文本转成数字再转回字符串,与原来一模一样才转。`5432` 转过去转回来还是 `5432`,所以是数字;`007` 转成 7 再转回来是 `7`,与原串不同,所以保持 `"007"` —— 编号的前导零是它的一部分,改成 7 是不可逆的破坏。`true` / `false` 会转成布尔值(设置文件里 `debug = true` 读成字符串 `"true"`,会让下游的 `if (cfg.debug)` 恒为真),但 `True` / `yes` 保持字符串 —— 这两种写法在不同实现里含义不一,不替你决定。要全部按文本读,把「数字怎么读」改成「全部按文本」。

相关工具