有谁会,使用 Java 打开一个 文件名是 GBK 编码的文件?(在系统编码为 UTF-8 的 Linux 下,不能使用 convmv 进行文件名转码)

2023-03-09 13:56:11 +08:00
 string2020
2784 次点击
所在节点    程序员
31 条回复
string2020
2023-03-09 13:58:45 +08:00
很无语,实在不行只能使用 convmv 了
string2020
2023-03-09 14:01:50 +08:00
chatgpt 也是推荐 convmv 。真没其他办法了吗?
AoEiuV020CN
2023-03-09 15:21:33 +08:00
不太理解,这个第一反应难道不是 FileReader ?还是说 fileReader 遇到了什么问题?
java.io.FileReader#FileReader(java.lang.String, java.nio.charset.Charset)
AoEiuV020CN
2023-03-09 15:23:25 +08:00
哦,是说文件名,不是文件内容啊,
那从 parent 入手,listFiles 一个一个判断文件名是否是你要打开的那个试试,
AoEiuV020CN
2023-03-09 15:27:48 +08:00
我问了下 chatGPT ,他的意思是直接 new String 时指定编码没有问题,
我没试过,但你可以试试,把字符串 getBytes 指定编码 gbk ,再 new String 指定系统编码 utf8 ,再传给 File ,
string2020
2023-03-09 16:25:16 +08:00
这是个蛋疼的事。
你指定 utf-8 文件名去访问。文件系统里确实没有 和你指定的文件名相同的文件。因为他实际是 GBK 编码的。
如果你指定 GBK 编码的文件名去访问,实际是个乱码字符串,那在文件系统里更不存在这个文件名为乱码的文件了。
实际上就算在 linux 控制台,你也很难根据名字访问一个 gbk 文件名的文件。
string2020
2023-03-09 16:26:04 +08:00
@AoEiuV020CN listFiles 拿到的文件名就是乱码了。直接使用拿到的 file.exists()都不存在了
AoEiuV020CN
2023-03-09 18:30:02 +08:00
试了完全不行,
不管是 File, Path, URI ,不管怎么指定的文件名,最终都会被解析成当前 jvm 编码,当前编码无法表示的字节就没有任何办法,
像 0x01 这种完全无法打印的 java 还能正常处理,
像 0xCE 这种,无论如何都会被识别成一个 utf8 字符,然后转成三个字节,变不回 0xCE,
zhilincom
2023-03-09 18:52:06 +08:00
查到这篇文章,不知道有用没? https://developer.aliyun.com/article/253507
文件名编码和系统配置相关,JVM 好像不支持自定义文件名编码吧?要么直接 JNA 调用系统函数操作文件?
billlee
2023-03-09 19:00:21 +08:00
Java 改 JVM 编码到 ISO_8859_1, 然后 new String("汉字".getBytes("GBK"). StandardCharsets.ISO_8859_1) 应该可以。不能改 JVM 编码应该就没办法了。
jorneyr
2023-03-09 20:18:03 +08:00
InputStreamReader(InputStream in, Charset cs): 创建 reader 的时候指定编码。
felixlong
2023-03-09 22:02:20 +08:00
@string2020 Linux 的文件系统没有 GBK 的概念。你只把他当成 char* 就行。你的问题在于怎么用 Java 的 String 表示这些 char 而已。 直接用 unicode:String filename = "\u0001\u00CE"。
kenvix
2023-03-09 22:13:48 +08:00
看看底层 API 有没有办法拿到 byte[]型的文件名吧,先让 JVM 别急着 byte[]转 String
AoEiuV020CN
2023-03-09 22:14:48 +08:00
@felixlong 不行的,你可以试一下,
0x01 这种可以处理,0xCE 这种会被转来转去最后得到错误的文件名,
AoEiuV020CN
2023-03-09 22:16:43 +08:00
@kenvix 关键就是没有办法,不管哪个 api ,暴露的都是 String ,
leonshaw
2023-03-09 22:23:27 +08:00
JNI...
SoloCompany
2023-03-09 22:55:50 +08:00
Files.newInputStream(Paths.get(new URI("file:///path/to/" + URLEncoder.encode("中文", "GB18030"))))
AoEiuV020CN
2023-03-09 23:00:49 +08:00
说到 jni 的话就想到 jna , 用 jna 就完全没问题了,

https://gist.github.com/AoEiuV020/668ba0ab3ae96db95ecfd07fe04dec21
AoEiuV020CN
2023-03-09 23:04:19 +08:00
xiangyuecn
2023-03-09 23:07:34 +08:00
这个跟编码没有关系吧,你 java 先把文件夹里面的文件名全部打印出来,再复制粘贴不就好了

难道说还是有什么反人类的 bug

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922567

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX