Java 解决错误:编码UTF8的不可映射字符

Java 解决错误:编码UTF8的不可映射字符,java,perl,maven,utf8-decode,Java,Perl,Maven,Utf8 Decode,我有一个maven项目,字符编码在我的父pom中设置为UTF-8 <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>

我有一个maven项目,字符编码在我的父pom中设置为UTF-8

    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.3.2</version>
      <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin>

这两行不会启动或执行重新编码:

open(my $INFILE,  '<:encoding(cp1252)',  $filename) or die $!;
open(my $OUTFILE, '>:encoding(UTF-8)', $filename) or die $!;
如果文件足够小(提示:源代码通常足够小),则还可以将其加载到内存中:

use File::Slurp;

my $contents = read_file $filename, { binmode => ':encoding(cp1252)' };
write_file $filename, { binmode => ':encoding(UTF-8)' }, $contents;

如果您使用的是Linux或Mac OS X,则可以使用
iconv
将文件转换为UTF-8。Java1.7不允许非utf8字符,但Java1.6允许(尽管它会产生警告)。我知道,因为我的Mac电脑上有Java 1.7,因此我无法编译我们的一些代码,而Windows用户和我们的Linux连续构建机器可以,因为他们仍然使用Java 1.6

Perl脚本的问题是,您正在打开一个文件进行读取,而打开的是同一个文件进行写入,但使用的是同一个文件名。打开文件进行写入时,将删除其内容

#! /usr/bin/env perl
use warnings;
use strict;
use feature qw(say);

use File::Find;

use strict;
use warnings;
use autodie;

use constant  {
    SOURCE_DIR       => 'src',
};


my @file_list;
find {
    next unless -f;
    next unless /\.java$/;
    push $file_list, $File::Find::name;
}, SOURCE_DIR;

for my $file ( @file_list ) {
    open my $file_fh, "<:encoding(cp1252)", $file;
    my @file_contents = <$file_fh>;
    close $file_fh;

    open my $file_fh, ">:encoding(utf8)", $file;
    print {$file_fh} @file_contents;
    close $file_fh;
}
#/usr/bin/env perl
使用警告;
严格使用;
使用特征qw(例如);
使用File::Find;
严格使用;
使用警告;
使用自动模具;
使用常数{
SOURCE_DIR=>“src”,
};
我的@file_列表;
发现{
其次,除非-f;
下一步除非/\.java$/;
推送$file\u列表,$file::Find::name;
},SOURCE_DIR;
对于我的$file(@file\u list){
打开我的$file_fh,“:encoding(utf8)”,$file;
打印{$file\u fh}@file\u内容;
关闭$file\u fh;
}
注意,我正在将整个文件读入内存中,这对于Java源代码应该是可以的。即使是一个庞大的源文件(10000行,平均行长120个字符)也将超过1.2兆字节。除非您使用的是TRS-80,否则1.2兆字节的文件不应该是内存问题。如果您想对其严格要求,请使用
File::Temp
创建要写入的临时文件,然后使用
File::Copy
重命名该临时文件。两者都是标准的Perl模块


您也可以将整个程序包含在
find
子例程中。

您是否检查过导致异常的文件确实是UTF-8编码的?请注意,我的项目中有3000个java文件,因此手动访问每个文件并以UTF编码保存不是正确的方法。是否有一个perl脚本来解决这个问题?将代码放在问题中,并用perl重新标记它。您会问为什么perl脚本不能工作。这与Java没有多大关系。`是一个有效的ASCII/UTF-8,因此您可能需要在其他地方查找问题字符。为什么不计算出文件的编码字符并将其设置为Eclipse中的编码类型呢。您的pom.xml可以保持定义为UTF-8,因为我怀疑它是否包含任何非ASCII字符。“它正在给我造成编译错误”不是一个很好的问题描述。首先是什么错误?这意味着编写perl确实是解决这个问题的正确方法……就像3000个文件一样involved@user2604052我不知道,因为我不认为在默认设置下,或者在没有使用非ASCII字符的情况下,重新编码文件是必要的。我的回答只指出了当前的Perl脚本是如何工作的。是的,你是正确的……如果我们从项目开始就遵循utf-8编码,这是不必要的……但在我的例子中,因为文件是ansi格式的……我相信这应该将它们从ansi转换为utf-8,从而解决编译错误
use File::Slurp;

my $contents = read_file $filename, { binmode => ':encoding(cp1252)' };
write_file $filename, { binmode => ':encoding(UTF-8)' }, $contents;
#! /usr/bin/env perl
use warnings;
use strict;
use feature qw(say);

use File::Find;

use strict;
use warnings;
use autodie;

use constant  {
    SOURCE_DIR       => 'src',
};


my @file_list;
find {
    next unless -f;
    next unless /\.java$/;
    push $file_list, $File::Find::name;
}, SOURCE_DIR;

for my $file ( @file_list ) {
    open my $file_fh, "<:encoding(cp1252)", $file;
    my @file_contents = <$file_fh>;
    close $file_fh;

    open my $file_fh, ">:encoding(utf8)", $file;
    print {$file_fh} @file_contents;
    close $file_fh;
}