Я пытаюсь записать байты в файл в кодировке windows -1252. Приведенный ниже пример, записывающий необработанные байты с плавающей точкой в файл, аналогичен тому, что я делаю в моей настоящей программе.
В данном примере я пишу необработанный гекс 1,0f для проверки .текст. Поскольку необработанный гекс 1,0f равен 3f 80 00 00 , я ожидаю получить ? € (NUL) (NUL) , как видно из Windows 1252 Статья в Википедии , 0x3f должна соответствовать '? ', 0x80 должна соответствовать ' € ' и 0x00 - это ' NUL '. Все идет хорошо, пока я на самом деле не пытаюсь записать в файл; в этот момент я получаю исключение java .nio.charset.UnmappableCharacterException на консоли, и после того, как программа остановится на этом исключении, в файле будет только один символ '?' в этом. Полный вывод консоли находится под кодом ниже.
Похоже, Java считает кодовую точку 0x80 не отображаемой в кодовой странице windows -1252. Однако это кажется неправильным - все кодовые точки должны отображаться в реальные символы в этой кодовой странице. Проблема определенно связана с кодовой точкой 0x80 , как будто я пытаюсь с 0,5f ( 3f 00 00 00 ), он с удовольствием пишет ? (NUL) (NUL) ( NUL) в файл, и не выдает исключение. Эксперимент с другими кодовыми страницами тоже не работает; Если посмотреть на кодировки ключей, поддерживаемые Java языком здесь , то только серия UTF не даст мне исключения, но из-за их кодировки они не дают мне кодовую точку 0x80 в фактический файл.
Я попытаюсь использовать вместо этого байты, чтобы мне не приходилось беспокоиться о строковом кодировании, но кто-нибудь может сказать мне, почему мой код ниже дает мне исключение?
Код:
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CharsetTest {
public static void main(String[] args) {
float max = 1.0f;
System.out.println("Checking " + max);
String stringFloatFormatHex = String.format("%08x", Float.floatToRawIntBits(max));
System.out.println(stringFloatFormatHex);
byte[] bytesForFile = javax.xml.bind.DatatypeConverter.parseHexBinary(stringFloatFormatHex);
String stringForFile = new String(bytesForFile);
System.out.println(stringForFile);
String charset = "windows-1252";
try {
Writer output = Files.newBufferedWriter(Paths.get("test.txt"), Charset.forName(charset));
output.write(stringForFile);
output.close();
} catch (IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
Консольный выход:
Checking 1.0
3f800000
?�
Input length = 1
java.nio.charset.UnmappableCharacterException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:282)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:285)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.BufferedWriter.close(BufferedWriter.java:265)
at CharsetTest.main(CharsetTest.java:21)