获取文件名为UTF-8? (ä,ü,ö......总是'?')

时间:2011-05-24 22:21:57

标签: java encoding utf-8

我必须读取一些文件的名称并将它们作为字符串放在列表中。它不是那么难我只是对ä,ö,ü等一些人物有一些问题...他们总是像'?'在我的字符串中。

问题是什么?那么编码。好吧,这应该很容易......这就是我的想法。所以我尝试使用如下函数:

new String(insert.getBytes("UTF-8") 要么 new String(insert.getBytes("ISO-8859-1"), "UTF-8") 因为大多数文件都是ISO-8859-1

没有帮助。这是我的代码:

...
File[] fileList = dir.listFiles();
String insert;
for(File f : fileList) {
...
insert=f.getName().substring(0,f.getName().length()-4);
                insert=insert.charAt(0)+insert.substring(1,insert.length()).toLowerCase().replaceFirst("([0-9]*(_s?(i)?(_dat)?)*$)", "").replaceFirst("_", " ");
...
System.out.println("test UTF8: " + new String(insert.getBytes("UTF-8"))); //not helping
System.out.println("test ISO , UTF8: " + new String(insert.getBytes("ISO-8859-1"), "UTF-8")); //not helping
...
names.add(insert);
}

最后有很多带'?'的字符串我列表中的字符。 如何解决问题?如果不仅有ISO-8859-1文件,那么最好的方法是什么? (假设有很多未知的编码文件)

谢谢!

5 个答案:

答案 0 :(得分:3)

鉴于在该问题下来回扩展的评论,现在看起来这可能是字体问题或(或许更可能是)文件名编码问题。

我让Lissy运行以下命令让我们弄清问题是什么。如果她确定文件名中包含“ä”,但是当ls文件名时该字符没有出现,那么此命令将告诉我们这是字体还是编码问题。

touch filenäme
ls filen*me

如果在ls的输出中显示“filenäme”,那么我们知道问题在于在该系统上创建/复制文件。如果创建文件的程序没有意识到文件系统编码是什么,或者为了做正确的事情太愚蠢,就会发生这种情况。 convmv程序可能是解决此问题的最佳方法。

convmv -f ENCODING -t utf8 -r .

问题是什么是正确的编码。可能性包括UTF-16,cp850或iso8859-1。 convmv --list将显示当前已知(对您的系统)编码的列表。由于上面列出的命令只显示它可能会执行的操作,因此可以安全地使用不同的编码运行多次,直到找到一个对所有文件

如果这是字体问题,我们必须查看

答案 1 :(得分:1)

文件名内容的编码与文件名本身的编码无关。

您应该从System.out.println(insert)

获得正确的结果

如果不这样做,则意味着shell具有与系统的默认字符编码不同的字符编码(这种情况很少发生;它通常是在shell中切换编码的显式命令的结果)。

如果在shell中列出目录时文件名正确显示,我希望它们能够正确显示,而无需在Java程序中指定编码。


如果shell无法显示该字符(它将替换字符0xFFFD( )替换为这些不可打印的字符),那么您无法从Java应用程序中更改它。您需要更改终端字符编码,安装正确的字体等;这是一个操作系统问题,而不是Java问题。

同时,即使您的终端无法显示正确的结果,Java程序也应正确处理字符编码而无需您的干预。

File API背后的库正在为您的系统找出正确的字符编码并对字符进行必要的解码。同样,数据库驱动程序应与数据库协商以确定正确的编码,并代表您的应用程序对字节执行任何必要的编码。

答案 2 :(得分:1)

String中出现意外的问号,spalts等,表示某个地方在从一个字符集转换为另一个字符集时无法识别特定字符。

在您的情况下,问题可能发生在几个地方:

  • 当您的Java程序从目录中读取文件名时(在dir.listFiles()调用中),可能会发生这种情况。

  • 将字符打印到控制台流时可能会发生这种情况。

在任何一种情况下,根本原因很可能是Java认为语言环境设置应该与操作系统和/或命令shell正在使用的设置之间不匹配。

作为实验,尝试从命令行列出包含有问题文件名的目录。你在那里看到问号或其他splats吗?

要执行的第二个实验是修改Java程序以将一个问题字符串转储为表示每个字符的字符代码的数字序列。您是否看到ASCII / Unicode '?'的字符代码。

答案 3 :(得分:0)

在你写的评论中写道:

  

@mdrg:好吧,这是一个问题。我必须读取文件的名称,然后将它们放入数据库中。还有很多'?' ,那不应该...... - Lissy 27分钟前

我的猜测是,您插入文件名的列指定US-ASCII作为编码,并用替换字符替换该范围之外的字符,在您的情况下是替换字符。

因此,您必须在数据库表中找到存储文件名的列的编码。各种产品都有各种语法来检索该信息。

答案 4 :(得分:0)

在Java 1.6中,您可以使用System.console()而不是System.out.println()来向控制台显示突出显示的字符。

public class Test {
  public static void main(String args[]){
   String s = "caractères français :  à é \u00e9"; // Unicode for "é"
   System.console().writer().println(s);
  }
}

,输出

C:\temp>java Test
caractères français :  à é é