1
string2020 OP 很无语,实在不行只能使用 convmv 了
|
2
string2020 OP chatgpt 也是推荐 convmv 。真没其他办法了吗?
|
3
AoEiuV020CN 2023-03-09 15:21:33 +08:00
不太理解,这个第一反应难道不是 FileReader ?还是说 fileReader 遇到了什么问题?
java.io.FileReader#FileReader(java.lang.String, java.nio.charset.Charset) |
4
AoEiuV020CN 2023-03-09 15:23:25 +08:00
哦,是说文件名,不是文件内容啊,
那从 parent 入手,listFiles 一个一个判断文件名是否是你要打开的那个试试, |
5
AoEiuV020CN 2023-03-09 15:27:48 +08:00
|
6
string2020 OP 这是个蛋疼的事。
你指定 utf-8 文件名去访问。文件系统里确实没有 和你指定的文件名相同的文件。因为他实际是 GBK 编码的。 如果你指定 GBK 编码的文件名去访问,实际是个乱码字符串,那在文件系统里更不存在这个文件名为乱码的文件了。 实际上就算在 linux 控制台,你也很难根据名字访问一个 gbk 文件名的文件。 |
7
string2020 OP @AoEiuV020CN listFiles 拿到的文件名就是乱码了。直接使用拿到的 file.exists()都不存在了
|
8
AoEiuV020CN 2023-03-09 18:30:02 +08:00
试了完全不行,
不管是 File, Path, URI ,不管怎么指定的文件名,最终都会被解析成当前 jvm 编码,当前编码无法表示的字节就没有任何办法, 像 0x01 这种完全无法打印的 java 还能正常处理, 像 0xCE 这种,无论如何都会被识别成一个 utf8 字符,然后转成三个字节,变不回 0xCE, |
9
zhilincom 2023-03-09 18:52:06 +08:00
查到这篇文章,不知道有用没? https://developer.aliyun.com/article/253507
文件名编码和系统配置相关,JVM 好像不支持自定义文件名编码吧?要么直接 JNA 调用系统函数操作文件? |
10
billlee 2023-03-09 19:00:21 +08:00
Java 改 JVM 编码到 ISO_8859_1, 然后 new String("汉字".getBytes("GBK"). StandardCharsets.ISO_8859_1) 应该可以。不能改 JVM 编码应该就没办法了。
|
11
jorneyr 2023-03-09 20:18:03 +08:00
InputStreamReader(InputStream in, Charset cs): 创建 reader 的时候指定编码。
|
12
felixlong 2023-03-09 22:02:20 +08:00
@string2020 Linux 的文件系统没有 GBK 的概念。你只把他当成 char* 就行。你的问题在于怎么用 Java 的 String 表示这些 char 而已。 直接用 unicode:String filename = "\u0001\u00CE"。
|
13
kenvix 2023-03-09 22:13:48 +08:00
看看底层 API 有没有办法拿到 byte[]型的文件名吧,先让 JVM 别急着 byte[]转 String
|
14
AoEiuV020CN 2023-03-09 22:14:48 +08:00 via Android
@felixlong 不行的,你可以试一下,
0x01 这种可以处理,0xCE 这种会被转来转去最后得到错误的文件名, |
15
AoEiuV020CN 2023-03-09 22:16:43 +08:00 via Android
@kenvix 关键就是没有办法,不管哪个 api ,暴露的都是 String ,
|
16
leonshaw 2023-03-09 22:23:27 +08:00
JNI...
|
17
SoloCompany 2023-03-09 22:55:50 +08:00
Files.newInputStream(Paths.get(new URI("file:///path/to/" + URLEncoder.encode("中文", "GB18030"))))
|
18
AoEiuV020CN 2023-03-09 23:00:49 +08:00
|
19
AoEiuV020CN 2023-03-09 23:04:19 +08:00 via Android
|
20
xiangyuecn 2023-03-09 23:07:34 +08:00
这个跟编码没有关系吧,你 java 先把文件夹里面的文件名全部打印出来,再复制粘贴不就好了
难道说还是有什么反人类的 bug |
21
leonshaw 2023-03-09 23:23:39 +08:00
@AoEiuV020CN 打开文件拿到 fd 以后应该就可以直接用 java.io 再打开 /proc/self/fd/x 了
|
22
tramm 2023-03-10 08:32:47 +08:00
有啥问题?
先把 utf8 的文件名转成 gbk 的 string, 然后再用 gbk 的 string 去访问不就行了嘛. 我用下面的试了下, 可以访问的啊, 还是说我理解错了你的意思?(FileUtil 是 HuTool 中的) @Test public void charsetTest(){ String content = "草泥马"; byte[] gbks = content.getBytes(Charset.forName("GBK")); // gbk 在 UTF8 下的字符串表示 String gbkInUtf8 = StrUtil.str(gbks, StandardCharsets.UTF_8); log.info(gbkInUtf8); // ������ FileUtil.writeUtf8String("fuck", "F:\\Projects\\Learn\\JavaProjects\\aio-learn\\Logs\\"+gbkInUtf8+".txt"); String s1 = FileUtil.readUtf8String("F:\\Projects\\Learn\\JavaProjects\\aio-learn\\Logs\\" + gbkInUtf8 + ".txt"); log.info(s1); List<String> fileNames = FileUtil.listFileNames("F:\\Projects\\Learn\\JavaProjects\\aio-learn\\Logs"); for (String fileName : fileNames) { String s = FileUtil.readString("F:\\Projects\\Learn\\JavaProjects\\aio-learn\\Logs\\" + fileName, StandardCharsets.UTF_8); log.info("{} - {}",fileName,s); } } |
23
tramm 2023-03-10 08:34:04 +08:00
@tramm
打印: 2023-03-10 08:27:31.489 [main] [INFO ] com.wdnj.xxb.jtt.CommonTest - ������ 2023-03-10 08:27:31.492 [main] [INFO ] com.wdnj.xxb.jtt.CommonTest - fuck 2023-03-10 08:27:31.497 [main] [INFO ] com.wdnj.xxb.jtt.CommonTest - ������.txt - fuck |
24
AoEiuV020CN 2023-03-10 09:01:21 +08:00 via Android
@tramm 按道理是这样的,但是你离开 java 再看看这个文件名的十六进制,压根不是 gbk 编码的汉字,
|
25
string2020 OP @billlee 改了编码,日志什么的其他操作是不是也受到到影响
|
26
string2020 OP @jorneyr 是文件名的编码不对,文件 exists 都不存在。
|
27
string2020 OP @felixlong 已经用 convmv 处理了,有空我试试
|
28
string2020 OP @AoEiuV020CN 确实蛋疼
|
29
string2020 OP @xiangyuecn 复制出来的是 gbk 编码的字符转为 utf8 的字符,也就是乱码。用乱码怎么找文件,exists 直接不存在
|
30
string2020 OP @tramm 转为 utf8 后的 gbk 字符是乱码,java 去访问文件的时候是找不到的,因为系统里没有文件名为乱码的文件。你用的这个文件是你以乱码为名新建的文件。实际我现在的文件是 gbk 编码的文件名,也就是名字只是编码不对,而不是乱码的名字。你在系统里直接建一个文件,用 convmv 转为 gbk ,再用你的方法访问,是访问不到的。
|
31
string2020 OP @AoEiuV020CN 确实能用 bytes 当文件名就能解决。太蛋疼,把现有文件全部 convmv 了。以后保存文件就保存为 utf8.文件都是 ftp 上来的,ftp 的编码没设置好,导致 window 上来的文件名都是 gbk.现在改成 utf8 后,用 ftp 客户端读取,文件名又全是乱码,需要设置为强制 utf8 才能正常。
|