Исправление ошибки: не отображаемый символ для кодировки UTF8
У меня есть проект Maven, кодировка символов установлена в 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 - настройки --- Рабочая область --- Кодировка текстового файла) я указал кодировку как 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 $!;
}
2 ответа
Эти две строки не запускаются или не выполняют перекодирование:
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 делает (хотя выдает предупреждение). Я знаю, потому что у меня есть Java 1.7 на моем Mac, и я не могу скомпилировать часть нашего кода из-за этого, в то время как пользователи 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. Даже гигантский исходный файл (длиной 10000 строк и средней длиной 120 символов) будет иметь размер чуть более 1,2 мегабайта. Если вы не используете TRS-80, файл объемом 1,2 мегабайта не должен быть проблемой с памятью. Если вы хотите быть строгим, используйте File::Temp
создать временный файл для записи, а затем использовать File::Copy
переименовать этот временный файл. Оба являются стандартными модулями Perl.
Вы также можете приложить всю программу в find
подпрограмма тоже.