назначение указания байтов при чтении текстового файла с другим форматом кодирования

#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 с помощью a FileReader , который может автоматически переводить байты в символы, используя стандартную кодировку, указанную вами в конструкторе. 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. Спасибо, я думаю, что теперь я понял больше.