Создать файл в UTF-8 с помощью FileWriter (Java)?
У меня есть следующий код, однако я хочу, чтобы он писал как файл UTF-8 для обработки иностранных символов. Есть ли способ сделать это, есть ли необходимость иметь параметр?
Я бы очень признателен за вашу помощь в этом. Спасибо.
try {
BufferedReader reader = new BufferedReader(new FileReader("C:/Users/Jess/My Documents/actresses.list"));
writer = new BufferedWriter(new FileWriter("C:/Users/Jess/My Documents/actressesFormatted.csv"));
while( (line = reader.readLine()) != null) {
//If the line starts with a tab then we just want to add a movie
//using the current actor name.
if(line.length() == 0)
continue;
else if(line.charAt(0) == '\t') {
readMovieLine2(0, line, surname.toString(), forename.toString());
} //Else we've reached a new actor
else {
readActorName(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
Ответы
Ответ 1
Конструкторы безопасного кодирования
Получение Java для правильного уведомления об ошибках кодирования является сложным. Вы должны использовать самый многословный и, увы, наименее используемый из четырех альтернативных конструкторов для каждого из InputStreamReader
и OutputStreamWriter
, чтобы получить правильное исключение при кодировании глюк.
Для ввода/вывода файлов всегда всегда используйте как второй аргумент как OutputStreamWriter
, так и InputStreamReader
аргумент fancy encoder:
Charset.forName("UTF-8").newEncoder()
Существуют и другие, даже более благоприятные возможности, но ни одна из трех более простых возможностей не работает для обработки исключений. Они делают:
OutputStreamWriter char_output = new OutputStreamWriter(
new FileOutputStream("some_output.utf8"),
Charset.forName("UTF-8").newEncoder()
);
InputStreamReader char_input = new InputStreamReader(
new FileInputStream("some_input.utf8"),
Charset.forName("UTF-8").newDecoder()
);
Что касается работы с
$ java -Dfile.encoding=utf8 SomeTrulyRemarkablyLongcLassNameGoeShere
Проблема заключается в том, что она не будет использовать форму аргумента полного кодирования для потоков символов, и поэтому вы снова пропустите проблемы с кодировкой.
Более длинный пример
Вот более длинный пример, который управляет процессом вместо файла, где мы продвигаем два разных потока входных байтов и один выходной поток байтов для всех потоков символов UTF-8 с полной обработкой исключений:
// this runs a perl script with UTF-8 STD{IN,OUT,ERR} streams
Process
slave_process = Runtime.getRuntime().exec("perl -CS script args");
// fetch his stdin byte stream...
OutputStream
__bytes_into_his_stdin = slave_process.getOutputStream();
// and make a character stream with exceptions on encoding errors
OutputStreamWriter
chars_into_his_stdin = new OutputStreamWriter(
__bytes_into_his_stdin,
/* DO NOT OMIT! */ Charset.forName("UTF-8").newEncoder()
);
// fetch his stdout byte stream...
InputStream
__bytes_from_his_stdout = slave_process.getInputStream();
// and make a character stream with exceptions on encoding errors
InputStreamReader
chars_from_his_stdout = new InputStreamReader(
__bytes_from_his_stdout,
/* DO NOT OMIT! */ Charset.forName("UTF-8").newDecoder()
);
// fetch his stderr byte stream...
InputStream
__bytes_from_his_stderr = slave_process.getErrorStream();
// and make a character stream with exceptions on encoding errors
InputStreamReader
chars_from_his_stderr = new InputStreamReader(
__bytes_from_his_stderr,
/* DO NOT OMIT! */ Charset.forName("UTF-8").newDecoder()
);
Теперь у вас есть три символьных потока, которые все увеличивают исключение при ошибках кодирования, соответственно называемых chars_into_his_stdin
, chars_from_his_stdout
и chars_from_his_stderr
.
Это немного сложнее, чем то, что вам нужно для вашей проблемы, решение которой я дал в первой половине этого ответа. Ключевым моментом является то, что это единственный способ обнаружить ошибки кодирования.
Просто не заставляйте меня начинать с PrintStream
исключений еды.
Ответ 2
Ditch FileWriter
и FileReader
, которые бесполезны именно потому, что они не позволяют вам указывать кодировку. Вместо этого используйте
new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)
и
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
Ответ 3
Вам необходимо использовать класс OutputStreamWriter
в качестве параметра записи для вашего BufferedWriter
. Он принимает кодировку. Ознакомьтесь с javadocs.
Примерно так:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("jedis.txt"), "UTF-8"
));
Или вы можете установить текущую системную кодировку с системным свойством file.encoding
в UTF-8.
java -Dfile.encoding=UTF-8 com.jediacademy.Runner arg1 arg2 ...
Вы также можете установить его как системное свойство во время выполнения с System.setProperty(...)
, если он нужен только для этого конкретного файла, но в таком случае, как я думаю, я бы предпочел OutputStreamWriter
.
Установив системное свойство, вы можете использовать FileWriter
и ожидать, что оно будет использовать UTF-8 в качестве кодировки по умолчанию для ваших файлов. В этом случае для всех файлов, которые вы читаете и пишете.
EDIT
Начиная с API 19, вы можете заменить строку "UTF-8" на StandardCharsets.UTF_8
Как указано в комментариях ниже tchrist, если вы намерены обнаруживать ошибки кодирования в своем файле, вам придется использовать подход OutputStreamWriter
и использовать конструктор, который получает кодировщик кодировки.
Что-то вроде
CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
encoder.onMalformedInput(CodingErrorAction.REPORT);
encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("jedis.txt"),encoder));
Вы можете выбирать между действиями IGNORE | REPLACE | REPORT
Также на этот вопрос уже был дан ответ здесь.
Ответ 4
С китайским текстом я попытался использовать Charset UTF-16 и, к счастью, он работает.
Надеюсь, это поможет!
PrintWriter out = new PrintWriter( file, "UTF-16" );
Ответ 5
Так как Java 7 есть простой способ обработки кодировки символов BufferedWriter и BufferedReaders. Вы можете создать BufferedWriter напрямую, используя класс Files вместо создания различных экземпляров Writer. Вы можете просто создать BufferedWriter, который рассматривает кодировку символов, вызывая:
Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8);
Об этом можно узнать в JavaDoc:
Ответ 6
Начиная с Java 11 вы можете сделать:
FileWriter fw = new FileWriter("filename.txt", Charset.forName("utf-8"));
Ответ 7
ОК, теперь 2019, и из Java 11 у вас есть конструктор с Charset:
FileWriter(String fileName, Charset charset)
К сожалению, мы все еще не можем изменить размер байтового буфера, и это установлен на 8192. (https://www.baeldung.com/java-filewriter)
Ответ 8
используйте OutputStream вместо FileWriter для установки типа кодировки
OutputStream outputStream = new FileOutputStream(file); // file is your File object where you want to write you data
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
outputStreamWriter.write(json); // json is your data
outputStreamWriter.flush();
outputStreamWriter.close();
Ответ 9
По-моему
Если вы хотите написать follow kind UTF-8. Вам следует создать массив байтов. Затем вы можете сделать следующее:
byte[] by=("<?xml version=\"1.0\" encoding=\"utf-8\"?>"+"Your string".getBytes();
Затем вы можете записать каждый байт в созданный файл.
Пример:
OutputStream f=new FileOutputStream(xmlfile);
byte[] by=("<?xml version=\"1.0\" encoding=\"utf-8\"?>"+"Your string".getBytes();
for (int i=0;i<by.length;i++){
byte b=by[i];
f.write(b);
}
f.close();