Исправление ошибки: не отображаемый символ для кодировки 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 подпрограмма тоже.

Другие вопросы по тегам