#java
Вопрос:
У меня есть некоторые вопросы об указании количества байтов при чтении файла с другим форматом кодирования.
У меня есть такой текстовый файл:
и у меня есть такой код:
public static String read(File file) throws IOException {
InputStream in = new FileInputStream(file);
// How many bytes are fetched at a time
byte[] bytes = new byte[92]; /// what number to specify inside the byte[ ] here?
// does it have to equal the "size" of the file?
// so it is 92 when my text file is 92 bytes?
// and it will be 52 if my text file is 52 bytes?
// An array of bytes used to receive reads
StringBuilder sb = new StringBuilder();
// Read the length of byte array. If it is - 1, it means there is no data
int length = 0;
// Cycle data
while ((length = in.read(bytes)) != -1) {
// Converts the read to a string
sb.append(new String(bytes,"UTF-16le" )); // I think specifying number of bytes
// affect this line here right? but what
//specifically does it affect String(bytes, "UTF-16le")
}
// Close stream
in.close();
}
return sb.toString();
Чего я не понимаю, так это того, что делает байт кода[] байт = новый байт[92] именно в этом фрагменте кода? число внутри байта [ ], что оно делает? Я пробовал разные номера, когда сохранял свой текстовый файл в различных кодировках. Например, если я сохраню свой текстовый файл в кодировке UTF-16le, размер моего файла составит 92 байта. Поэтому, если я не укажу там 92, то моя среда IDE неправильно отобразит эти символы внутри текстового файла. Итак, скажем, я указываю 32, затем я получил это (в котором теперь есть дополнительное пространство и символ «b» в конце).:
и если я укажу 77, я получу это:
поэтому он отображается неправильно.
Также, если я сохранил свой текстовый файл в кодировке UTF-8, и размер файла теперь составляет 59 байт. И если я укажу в коде 59, то символы будут отображаться правильно. Но другого числа не будет. Итак, могу я узнать, что здесь делает установка размеров массива байтов? должен ли он быть равен размеру (байтам) текстового файла, в котором расположены символы?
Не мог бы кто-нибудь любезно объяснить подробно, для чего здесь задается размер количества байтов?
sb.append(new String(bytes,"UTF-16le" ))
Комментарии:
1. Вы понимаете, что означает UTF-16? То есть, как байты переводятся в символы Юникода?
2. Это не совсем ответ на ваш вопрос, но чтение текстовых файлов Юникода в байтах не так просто, как может показаться. Таким образом, легко привести к повреждению данных, если считываемые байты неправильно совпадают с границами символов. Лучше обернуть ваш
FileInputStream
с помощью aFileReader
, который может автоматически переводить байты в символы, используя стандартную кодировку, указанную вами в конструкторе. docs.oracle.com/javase/8/docs/api/java/io/…
Ответ №1:
byte[] bytes = new byte[92]
это означает, что зарезервируйте для меня 92 байта места для размещения необработанных данных. ОБРАТИТЕ внимание на разницу между байтами и символами(которые могут быть несколькими байтами).
length = in.read(bytes)
считывает байты до тех пор, пока больше не будет доступно или буфер bytes
не заполнится. Вы должны посмотреть на length
возвращаемую переменную, чтобы определить, сколько байтов считывается, и добавить только эти байты в строковый буфер.
sb.append(new String(bytes,"UTF-16le" ))
пытается декодировать все байты в bytes
буфере, используя указанную схему кодирования символов. Это включает в себя любые байты в буфере, которые существуют после длины последнего считывания, которое является источником ваших дополнительных символов.
Комментарии:
1. Спасибо, я думаю, что теперь я понял больше.