繁体   English   中英

解决错误:无法映射的字符用于编码UTF8

[英]Solving error: unmappable character for encoding UTF8

我有一个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>

但是在Java文件中,已经使用了某些字符,例如` or ,这对我造成了编译错误。

在Eclipse中(属性----资源-----文本文件编码和Windows--preferences --- workspace ---文本文件编码),我将编码指定为UTF-8。 请让我知道如何解决此问题。

执行转换工作的PERL代码

use strict;
use warnings;
use File::Find;
use open qw/:std :utf8/;

my $dir = "D:\\files";


find({ wanted => \&collectFiles}, "$dir");

sub collectFiles {
    my $filename = $_;
        if($filename =~ /.java$/){
        #print $filename."\n";
        startConversion($filename);
    }
}

sub startConversion{
    my $filename = $_;
    print $filename."\n";
    open(my $INFILE,  '<:encoding(cp1252)',  $filename) or die $!;
    open(my $OUTFILE, '>:encoding(UTF-8)', $filename) or die $!;
}

这两行不开始也不执行重新编码:

open(my $INFILE,  '<:encoding(cp1252)',  $filename) or die $!;
open(my $OUTFILE, '>:encoding(UTF-8)', $filename) or die $!;

使用>打开文件将其截断,这将删除内容。 有关更多详细信息,请参见open文档

相反,您必须从第一个文件中读取数据(该文件自动解码),然后将其写回到另一个文件中(该文件自动编码)。 由于此处的源文件和目标文件是相同的,并且由于Windows下文件处理的怪癖,我们应该将输出写入临时文件:

use autodie;  # automatic error handling :)

open my $in,  '<:encoding(cp1252)', $filename;
open my $out, '>:encoding(UTF-8)', "$filename~";  # or however you'd like to call the tempfile
print {$out} $_ while <$in>;  # copy the file, recoding it
close $_ for $in, $out;

rename "$filename~" => $filename;  # BEWARE: doesn't work across logival volumes!

如果文件足够小(提示:通常是源代码),那么您也可以将它们加载到内存中:

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。 Java 1.7不允许使用非utf8字符,但Java 1.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;
}

注意我正在将整个文件读到内存中,这对于Java源代码应该可以。 即使是庞大的源文件(10,000行长,平均行长为120个字符)也将刚刚超过1.2兆字节。 除非您使用的是TRS-80,否则1.2 MB的文件应该不是内存问题。 如果要严格执行此操作,请使用File::Temp创建要写入的临时文件,然后使用File::Copy重命名该临时文件。 两者都是标准的Perl模块。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM