从Java内创建新文件时,无法正确使用拉丁字符。文件名得到奇怪的字符而不是正确的字符

问题描述:

当前将一个int []从hashmap保存到一个文件中,该文件的关键字名称为int []。这个确切的密钥必须可以从另一个程序中获得。因此,我无法将文件名称切换为英文字符。但即使我使用ISO_8859_1作为文件名的字符集,文件也会在文件树中混淆。英文字母是正确的,但不是特殊字母。从Java内创建新文件时,无法正确使用拉丁字符。文件名得到奇怪的字符而不是正确的字符

 /** 
     * Save array to file 
     */ 
     public void saveStatus(){ 
      try { 
       for(String currentKey : hmap.keySet()) { 
        byte[] currentKeyByteArray = currentKey.getBytes(); 
        String bytesString = new String(currentKeyByteArray, StandardCharsets.ISO_8859_1); 
        String fileLocation = "/var/tmp/" + bytesString + ".dat"; 
        FileOutputStream saveFile = new FileOutputStream(fileLocation); 
        ObjectOutputStream out = new ObjectOutputStream(saveFile); 
        out.writeObject(hmap.get(currentKey)); 
        out.close(); 
        saveFile.close(); 
        System.out.println("Saved file at " + fileLocation); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

它可能与Linux是如何编码的字符或更可能与Java代码做呢?

编辑

我认为问题在于操作系统。因为当用猫看文本文件时,例如问题是一样的。但是vim能够正确解码这些字母。在那种情况下,我将不得不从终端改变语言设置?

+0

您不应该尝试将字符串中的字节转换为不同的字符集。在一个字符串中,编码是,而且应该只是UTF-16。 'getBytes()'在当前JVM的默认字符集中获取字节。 'new String(...,CharSet)'从字节中创建一个字符串,假定它们在给定的字符集中。这显然是错误的,因为你将它们提取为当前的字符集。 – RealSkeptic

+0

您是否有可能修改读取这些文件的程序?即你可以在文件名(base64,...)中对密钥进行编码,以避免文件名的有效字符高度依赖于文件系统的问题。 – sruetti

+0

@RealSkeptic应该如何传递任何编码参数? – ChristofferAB

您还必须更改getBytes函数中的字符集。

currentKey.getBytes(StandardCharsets.ISO_8859_1); 

而且,你为什么要使用StandardCharsets.ISO_8859_1?要接受更广泛的字符,请使用StandardCharsets.UTF_8

+0

事实上,字节不应该被提取或改变。 – RealSkeptic

+0

@Chinmay jain UTF_8将包含ISO_8859_1中的所有内容吗? – ChristofferAB

+0

是的,它将包含ISO_8859_1中的所有内容。 –

文件名或路径的有效字符因使用的文件系统而异。虽然它应该可能只使用一个Java字符串作为文件名(只要它不包含在给定的文件系统中无效字符),可能会有互操作性问题和错误。

换句话说,作为@RealSkeptic建议,应省略所有Charset-magic,应该工作。但改变环境可能会导致意外的行为。

根据您的要求,您可能需要对密钥进行编码,以确保它只使用缩小的字符集。 Base64的一个变体可能会工作(假定您的文件系统区分大小写!)。你甚至可能会找到一个库(Apache Commons?),它提供了一个函数来将字符串减少为文件名中安全使用的字符。

+0

谢谢!我会尝试你的建议。我意识到它可能与文件系统有关。 – ChristofferAB