В ответе укажите размер файла в байтах utf 8, слово байты писать не нужно

Обновлено: 21.11.2024

Экземпляры этого класса поддерживают как чтение, так и запись в файл с произвольным доступом. Файл с произвольным доступом ведет себя как большой массив байтов, хранящийся в файловой системе. Существует разновидность курсора или индекса в подразумеваемом массиве, который называется указатель файла; операции ввода читают байты, начиная с указателя файла, и перемещают указатель файла дальше прочитанных байтов. Если файл произвольного доступа создан в режиме чтения/записи, то доступны и операции вывода; операции вывода записывают байты, начиная с указателя файла, и продвигают указатель файла за пределы записанных байтов. Операции вывода, которые записывают за текущий конец подразумеваемого массива, вызывают расширение массива. Указатель файла можно прочитать с помощью метода getFilePointer и установить с помощью метода seek.

В целом для всех подпрограмм чтения в этом классе справедливо то, что если конец файла достигается до того, как будет прочитано желаемое количество байтов, генерируется исключение EOFException (своего рода IOException ). Если какой-либо байт не может быть прочитан по какой-либо причине, кроме конца файла, генерируется исключение IOException, отличное от EOFException. В частности, исключение IOException может быть вызвано, если поток был закрыт.

Сводка конструктора

Создает файловый поток с произвольным доступом для чтения и, при необходимости, для записи в файл, указанный аргументом File.

Создает файловый поток с произвольным доступом для чтения и, при необходимости, для записи в файл с указанным именем.

Краткое описание метода

Методы
Модификатор и тип Метод и описание
void close()

Устанавливает смещение указателя файла, измеряемое от начала этого файла, при котором происходит следующее чтение или запись.

Записывает b.length байтов из указанного массива байтов в этот файл, начиная с текущего указателя файла.

Преобразует аргумент типа double в тип long с помощью метода doubleToLongBits в классе Double , а затем записывает значение типа long в файл в виде восьмибайтового значения, старшим байтом вперед.

Преобразует аргумент типа float в тип int с помощью метода floatToIntBits в классе Float , а затем записывает значение типа int в файл в виде четырехбайтового числа, старшим байтом вперед.

Методы, унаследованные от класса java.lang.Object

Сведения о конструкторе

Файл произвольного доступа

Создает файловый поток с произвольным доступом для чтения и, при необходимости, для записи в файл с указанным именем. Создается новый объект FileDescriptor для представления подключения к файлу.

Аргумент mode указывает режим доступа, в котором файл должен быть открыт. Допустимые значения и их значения указаны для конструктора RandomAccessFile(File,String).

При наличии диспетчера безопасности его метод checkRead вызывается с аргументом имени в качестве аргумента, чтобы проверить, разрешен ли доступ для чтения к файлу. Если режим разрешает запись, метод менеджера безопасности checkWrite также вызывается с аргументом имени в качестве аргумента, чтобы проверить, разрешен ли доступ для записи в файл.

Файл произвольного доступа

Создает файловый поток с произвольным доступом для чтения и, при необходимости, для записи в файл, указанный аргументом File. Новый объект FileDescriptor создается для представления этого подключения к файлу.

< /tr>

Значение

Значение

"r" Открыть только для чтения. Вызов любого из методов write результирующего объекта вызовет исключение IOException.
"rw" Открыть для чтения и записи. Если файл еще не существует, будет предпринята попытка его создания.
"rws" Открыт для чтения и записи, как и в случае с "rw", а также требует, чтобы каждое обновление содержимого файла или метаданных записывалось синхронно на базовое устройство хранения.
"rwd" Открыть для чтения и записи, как с "rw", а также требуют, чтобы каждое обновление содержимого файла записывалось синхронно на базовое устройство хранения.

Режимы "rws" и "rwd" работают так же, как метод force(boolean) класса FileChannel, передавая аргументы true и false соответственно, за исключением того, что они всегда применяются к каждой операции ввода-вывода и поэтому часто более эффективны. Если файл находится на локальном запоминающем устройстве, то при возврате вызова метода этого класса гарантируется, что все изменения, внесенные в файл этим вызовом, будут записаны на это устройство.Это полезно для обеспечения того, чтобы важная информация не была потеряна в случае сбоя системы. Если файл не находится на локальном устройстве, такая гарантия не предоставляется.

Режим "rwd" можно использовать для уменьшения количества выполняемых операций ввода-вывода. Использование "rwd" требует только записи в хранилище обновлений содержимого файла; использование "rws" требует обновления как содержимого файла, так и его метаданных для записи, что обычно требует как минимум еще одной низкоуровневой операции ввода-вывода.

При наличии диспетчера безопасности его метод checkRead вызывается с указанием пути к файлу в качестве аргумента, чтобы проверить, разрешен ли доступ для чтения к файлу. Если режим разрешает запись, метод менеджера безопасности checkWrite также вызывается с аргументом пути, чтобы узнать, разрешен ли доступ для записи к файлу.

Сведения о методе

получить FD

получить канал

Позиция возвращаемого канала всегда будет равна смещению указателя файла этого объекта, возвращаемому методом getFilePointer. Изменение смещения указателя файла этого объекта, будь то явно или путем чтения или записи байтов, изменит положение канала и наоборот. Изменение длины файла с помощью этого объекта изменит длину, видимую через файловый канал, и наоборот.

Читает байт данных из этого файла. Байт возвращается как целое число в диапазоне от 0 до 255 (0x00-0x0ff). Этот метод блокируется, если вход еще не доступен.

Хотя RandomAccessFile не является подклассом InputStream , этот метод ведет себя точно так же, как метод InputStream.read() InputStream .

Считывает до len байт данных из этого файла в массив байтов. Этот метод блокируется до тех пор, пока не будет доступен хотя бы один байт ввода.

Хотя RandomAccessFile не является подклассом InputStream , этот метод ведет себя точно так же, как метод InputStream.read(byte[], int, int) InputStream .

Считывает до b.length байт данных из этого файла в массив байтов. Этот метод блокируется до тех пор, пока не будет доступен хотя бы один байт ввода.

Хотя RandomAccessFile не является подклассом InputStream , этот метод ведет себя точно так же, как метод InputStream.read(byte[]) InputStream .

Читать полностью

Читает b.length байтов из этого файла в массив байтов, начиная с текущего указателя файла. Этот метод многократно считывает файл до тех пор, пока не будет прочитано запрошенное количество байтов. Этот метод блокируется до тех пор, пока не будет прочитано запрошенное количество байтов, не будет обнаружен конец потока или не возникнет исключение.

Читать полностью

Читает ровно len байт из этого файла в массив байтов, начиная с текущего указателя файла. Этот метод многократно считывает файл до тех пор, пока не будет прочитано запрошенное количество байтов. Этот метод блокируется до тех пор, пока не будет прочитано запрошенное количество байтов, не будет обнаружен конец потока или не возникнет исключение.

пропустить байты

Этот метод может пропускать меньшее количество байтов, возможно, ноль. Это может быть результатом любого из ряда условий; достижение конца файла до того, как будут пропущены n байтов, — это только одна возможность. Этот метод никогда не генерирует исключение EOFException. Возвращается фактическое количество пропущенных байтов. Если n отрицательное, байты не пропускаются.

написать

написать

Записывает b.length байтов из указанного массива байтов в этот файл, начиная с текущего указателя файла.

написать

получить указатель файла

Устанавливает смещение указателя файла, измеряемое от начала этого файла, при котором происходит следующее чтение или запись. Смещение может быть установлено за пределами конца файла. Установка смещения за конец файла не меняет длину файла. Длина файла изменится только путем записи после того, как будет установлено смещение за конец файла.

длина

установить длину

Если текущая длина файла, возвращаемая методом length, больше аргумента newLength, файл будет усечен. В этом случае, если смещение файла, возвращенное методом getFilePointer, больше, чем newLength, то после возврата этого метода смещение будет равно newLength .

Если текущая длина файла, возвращаемая методом length, меньше аргумента newLength, файл будет расширен. В этом случае содержимое расширенной части файла не определяется.

закрыть

Закрывает этот файловый поток с произвольным доступом и освобождает все системные ресурсы, связанные с этим потоком. Закрытый файл с произвольным доступом не может выполнять операции ввода или вывода и не может быть повторно открыт.

Если у этого файла есть связанный канал, этот канал также закрывается.

readBoolean

Читает логическое значение из этого файла. Этот метод считывает один байт из файла, начиная с текущего указателя файла. Значение 0 представляет false . Любое другое значение представляет собой true .Этот метод блокируется до тех пор, пока не будет прочитан байт, не будет обнаружен конец потока или не возникнет исключение.

байт чтения

Читает восьмибитное значение со знаком из этого файла. Этот метод считывает байт из файла, начиная с текущего указателя файла. Если прочитан байт b , где 0 , то результат:

Этот метод блокируется до тех пор, пока не будет прочитан байт, не будет обнаружен конец потока или пока не возникнет исключение.

readUnsignedByte

Читает из этого файла восьмибитное число без знака. Этот метод считывает байт из этого файла, начиная с текущего указателя файла, и возвращает этот байт.

Этот метод блокируется до тех пор, пока не будет прочитан байт, не будет обнаружен конец потока или пока не возникнет исключение.

краткое чтение

Читает из этого файла 16-битное число со знаком. Метод считывает два байта из этого файла, начиная с текущего указателя файла. Если прочитаны два байта по порядку, это b1 и b2 , где каждое из двух значений находится в диапазоне от 0 до 255 включительно, тогда результат будет равен:

Этот метод блокируется до тех пор, пока не будут прочитаны два байта, не будет обнаружен конец потока или не возникнет исключение.

readUnsignedShort

Читает из этого файла 16-битное число без знака. Этот метод считывает два байта из файла, начиная с текущего указателя файла. Если считанные байты по порядку равны b1 и b2 , где 0 , то результат будет равен:

Этот метод блокируется до тех пор, пока не будут прочитаны два байта, не будет обнаружен конец потока или не возникнет исключение.

прочитатьсимвол

Читает символ из этого файла. Этот метод считывает два байта из файла, начиная с текущего указателя файла. Если считанные байты по порядку равны b1 и b2 , где 0 , то результат будет равен:

Этот метод блокируется до тех пор, пока не будут прочитаны два байта, не будет обнаружен конец потока или не возникнет исключение.

Чтение

Читает из этого файла 32-битное целое число со знаком. Этот метод считывает 4 байта из файла, начиная с текущего указателя файла. Если прочитаны байты по порядку: b1, b2, b3 и b4, где 0, то результат будет равен:

Этот метод блокируется до тех пор, пока не будут прочитаны четыре байта, не будет обнаружен конец потока или не возникнет исключение.

Долгое чтение

тогда результат равен:

Этот метод блокируется до тех пор, пока не будут прочитаны восемь байтов, не будет обнаружен конец потока или не возникнет исключение.

чтение с плавающей запятой

Читает число с плавающей запятой из этого файла. Этот метод считывает значение int, начиная с текущего указателя файла, как если бы он был методом readInt, а затем преобразует это целое число в число с плавающей запятой с помощью метода intBitsToFloat в классе Float .

Этот метод блокируется до тех пор, пока не будут прочитаны четыре байта, не будет обнаружен конец потока или не возникнет исключение.

Двойное чтение

Читает двойное значение из этого файла. Этот метод считывает длинное значение, начиная с текущего указателя файла, как будто с помощью метода readLong, а затем преобразует это длинное значение в двойное с помощью метода longBitsToDouble в классе Double .

Этот метод блокируется до тех пор, пока не будут прочитаны восемь байтов, не будет обнаружен конец потока или не возникнет исключение.

строка чтения

Читает следующую строку текста из этого файла. Этот метод последовательно считывает байты из файла, начиная с текущего указателя файла, пока не достигнет знака конца строки или конца файла. Каждый байт преобразуется в символ путем взятия значения байта для младших восьми битов символа и установки старших восьми битов символа равными нулю. Поэтому этот метод не поддерживает полный набор символов Unicode.

Строка текста заканчивается символом возврата каретки ( '\r' ), символом новой строки ( '\n' ), символом возврата каретки, за которым сразу следует символ новой строки, или концом файла . Символы конца строки отбрасываются и не включаются в возвращаемую строку.

Этот метод блокируется до тех пор, пока не будет прочитан символ новой строки, возврат каретки и байт, следующий за ним (чтобы узнать, является ли он новой строкой), не будет достигнут конец файла или не возникнет исключение.

прочитатьUTF

Читаются первые два байта, начиная с текущего указателя файла, как если бы это было readUnsignedShort . Это значение дает количество следующих байтов в закодированной строке, а не длину результирующей строки. Следующие байты затем интерпретируются как байты, кодирующие символы в модифицированном формате UTF-8, и преобразуются в символы.

Этот метод блокируется до тех пор, пока не будут прочитаны все байты, не будет обнаружен конец потока или пока не возникнет исключение.

написать логическое значение

Записывает логическое значение в файл как однобайтовое значение. Значение true записывается как значение (byte)1 ; значение false записывается как значение (byte)0 . Запись начинается с текущей позиции указателя файла.

запись байта

Записывает байт в файл как однобайтовое значение. Запись начинается с текущей позиции указателя файла.

написатьШорт

Записывает короткое замыкание в файл в виде двух байтов, старшим байтом вперед. Запись начинается с текущей позиции указателя файла.

написатьсимвол

Записывает char в файл как двухбайтовое значение, старший байт идет первым. Запись начинается с текущей позиции указателя файла.

записатьInt

Записывает в файл целое число в виде четырех байтов, старший байт идет первым. Запись начинается с текущей позиции указателя файла.

длинная запись

Записывает в файл длинное значение в виде восьми байтов, старшим байтом вперед. Запись начинается с текущей позиции указателя файла.

запись с плавающей запятой

Преобразует аргумент типа float в тип int с помощью метода floatToIntBits в классе Float , а затем записывает значение типа int в файл в виде четырехбайтового числа, старшим байтом вперед. Запись начинается с текущей позиции указателя файла.

написатьДвойной

Преобразует аргумент типа double в тип long с помощью метода doubleToLongBits в классе Double , а затем записывает это значение типа long в файл в виде восьмибайтового значения, старшим байтом вперед. Запись начинается с текущей позиции указателя файла.

записать байты

Записывает строку в файл в виде последовательности байтов. Каждый символ в строке записывается последовательно, отбрасывая его старшие восемь битов. Запись начинается с текущей позиции указателя файла.

написатьсимволы

Записывает в файл строку в виде последовательности символов. Каждый символ записывается в поток вывода данных как бы методом writeChar. Запись начинается с текущей позиции указателя файла.

записать UTF

Сначала в файл записываются два байта, начиная с текущего указателя файла, как если бы метод writeShort задавал количество следующих байтов. Это значение представляет собой количество фактически записанных байтов, а не длину строки. После длины каждый символ строки выводится последовательно, используя модифицированную кодировку UTF-8 для каждого символа.

  • Обзор:
  • Вложенный |
  • Поле | |
  • Подробности:
  • Поле | |

Сообщите об ошибке или функции.
Дополнительные справочные материалы по API и документацию для разработчиков см. в документации по Java SE. Эта документация содержит более подробные описания, предназначенные для разработчиков, с концептуальными обзорами, определениями терминов, обходными путями и примерами рабочего кода.
Авторские права © 1993, 2020, Oracle и/или ее дочерние компании. Все права защищены. Использование регулируется условиями лицензии. Также ознакомьтесь с политикой распространения документации.

Дополнительную информацию можно найти в нашем вводном руководстве по HTML и CSS для маркетологов.

Правда в том, что даже такая простая вещь, как текст, требует хорошо скоординированной, четко определенной системы для отображения в веб-браузерах. В этом посте я объясню основы одной технологии, центральной для текста в Интернете, UTF-8. Мы изучим основы хранения и кодирования текста и обсудим, как это помогает размещать привлекательные слова на вашем сайте.

Прежде чем мы начнем, вы должны быть знакомы с основами HTML и готовы погрузиться в несложные компьютерные науки.

Что такое UTF-8?

UTF-8 расшифровывается как «Формат преобразования Unicode — 8 бит». Нам это пока не поможет, поэтому давайте вернемся к основам.

Двоичный файл: как компьютеры хранят информацию

Для хранения информации компьютеры используют двоичную систему. В двоичном формате все данные представлены в виде последовательностей 1 и 0. Основной единицей двоичного кода является бит, представляющий собой одну единицу или 0. Следующая по величине единица двоичного кода, байт, состоит из 8 бит. Пример байта: «01101011».

Каждый цифровой объект, с которым вы когда-либо сталкивались, — от программного обеспечения до мобильных приложений, веб-сайтов и историй в Instagram — построен на этой системе байтов, которые связаны друг с другом таким образом, который имеет смысл для компьютеров. Когда мы говорим о размерах файлов, мы имеем в виду количество байтов. Например, килобайт — это примерно тысяча байтов, а гигабайт — примерно миллиард байтов.

Текст — это один из многих ресурсов, которые хранятся и обрабатываются компьютерами. Текст состоит из отдельных символов, каждый из которых представлен в компьютере строкой битов. Эти строки объединяются в цифровые слова, предложения, абзацы, любовные романы и т. д.

ASCII: преобразование символов в двоичные

Американский стандартный код для обмена информацией (ASCII) был ранней стандартизированной системой кодирования текста. Кодирование — это процесс преобразования символов человеческого языка в двоичные последовательности, которые могут обрабатываться компьютером.

Библиотека ASCII включает все прописные и строчные буквы латинского алфавита (A, B, C...), все цифры от 0 до 9 и некоторые распространенные символы (такие как /, ! и ?).Каждому из этих символов присваивается уникальный трехзначный код и уникальный байт.

В таблице ниже показаны примеры символов ASCII с соответствующими кодами и байтами.

Точно так же, как символы объединяются в слова и предложения в языке, двоичный код делает то же самое в текстовых файлах. Итак, предложение «Быстрая коричневая лиса перепрыгивает через ленивую собаку». представленный в двоичном формате ASCII, будет:

Это мало что значит для нас, людей, но для компьютера это хлеб с маслом.

Количество символов, которые может представлять ASCII, ограничено количеством доступных уникальных байтов, поскольку каждый символ получает один байт. Если вы посчитаете, то обнаружите, что существует 256 различных способов сгруппировать восемь единиц и нулей вместе. Это дает нам 256 различных байтов или 256 способов представления символа в ASCII. Когда в 1960 году была введена ASCII, это было нормально, поскольку разработчикам требовалось всего 128 байт для представления всех нужных им английских букв и символов.

Но по мере глобального распространения вычислительной техники компьютерные системы стали хранить текст на других языках, помимо английского, многие из которых использовали символы, отличные от ASCII. Были созданы новые системы для сопоставления других языков с одним и тем же набором из 256 уникальных байтов, но наличие нескольких систем кодирования было неэффективным и запутанным. Разработчикам требовался лучший способ кодирования всех возможных символов в одной системе.

Юникод: способ хранения всех символов

Введите Unicode, систему кодирования, которая решает проблему пробелов ASCII. Как и в ASCII, в Unicode каждому символу присваивается уникальный код, называемый кодовой точкой. Однако более сложная система Unicode может создавать более миллиона кодовых точек, чего более чем достаточно для учета каждого символа любого языка.

Юникод теперь является универсальным стандартом для кодирования всех человеческих языков. И да, он даже включает смайлики.

Ниже приведены некоторые примеры текстовых символов и соответствующие им кодовые точки. Каждая кодовая точка начинается с «U» для «Unicode», за которой следует уникальная строка символов для представления символа.

Если вы хотите узнать, как генерируются кодовые точки и что они означают в Unicode, ознакомьтесь с этим подробным объяснением.

Итак, теперь у нас есть стандартизированный способ представления каждого символа, используемого каждым человеческим языком, в одной библиотеке. Это решает проблему множественных систем маркировки для разных языков — любой компьютер на Земле может использовать Unicode.

Однако Unicode сам по себе не хранит слова в двоичном виде. Компьютерам нужен способ перевода Unicode в двоичный код, чтобы его символы можно было хранить в текстовых файлах. Здесь на помощь приходит кодировка UTF-8.

UTF-8: последняя часть головоломки

UTF-8 – это система кодирования Unicode. Он может преобразовать любой символ Unicode в соответствующую уникальную двоичную строку, а также может преобразовать двоичную строку обратно в символ Unicode. В этом смысл «UTF» или «формата преобразования Unicode».

Помимо UTF-8, для Unicode существуют и другие системы кодирования, но UTF-8 уникальна, поскольку представляет символы в однобайтовых блоках. Помните, что один байт состоит из восьми битов, отсюда и «-8» в его имени.

В частности, UTF-8 преобразует кодовую точку (которая представляет один символ в Unicode) в набор от одного до четырех байтов. Первые 256 символов в библиотеке Unicode, включая символы, которые мы видели в ASCII, представлены как один байт. Символы, которые появляются позже в библиотеке Unicode, кодируются как двухбайтовые, трехбайтовые и, возможно, четырехбайтовые двоичные единицы.

Ниже приведена та же таблица символов, что и выше, с выводом UTF-8 для каждого добавленного символа. Обратите внимание, что некоторые символы представлены одним байтом, в то время как другие используют больше.

Почему UTF-8 преобразовывает одни символы в один байт, а другие — в четыре байта? Короче, для экономии памяти. Используя меньше места для представления более распространенных символов (например, символов ASCII), UTF-8 уменьшает размер файла, позволяя использовать гораздо большее количество менее распространенных символов. Эти менее распространенные символы закодированы в два или более байта, но это нормально, если они хранятся экономно.

Пространственная эффективность — ключевое преимущество кодировки UTF-8. Если бы вместо этого каждый символ Unicode был представлен четырьмя байтами, текстовый файл, написанный на английском языке, был бы в четыре раза больше по размеру того же файла, закодированного с помощью UTF-8.

Еще одним преимуществом кодировки UTF-8 является ее обратная совместимость с ASCII. Первые 128 символов в библиотеке Unicode совпадают с символами в библиотеке ASCII, и UTF-8 переводит эти 128 символов Unicode в те же двоичные строки, что и ASCII. В результате UTF-8 может без проблем преобразовать текстовый файл, отформатированный в ASCII, в удобочитаемый текст.

Символы UTF-8 в веб-разработке

UTF-8 – это наиболее распространенный метод кодировки символов, используемый сегодня в Интернете, а также набор символов по умолчанию для HTML5. Более 95% всех веб-сайтов, включая ваш собственный, хранят символы таким образом.Кроме того, распространенные методы передачи данных через Интернет, такие как XML и JSON, кодируются в соответствии со стандартами UTF-8.

Поскольку теперь это стандартный метод кодирования текста в Интернете, все страницы вашего сайта и базы данных должны использовать кодировку UTF-8. Система управления контентом или конструктор веб-сайтов по умолчанию сохраняют ваши файлы в формате UTF-8, но все же рекомендуется убедиться, что вы придерживаетесь этой рекомендации.

Текстовые файлы, закодированные с помощью UTF-8, должны указывать это программному обеспечению, которое их обрабатывает. В противном случае программное обеспечение не сможет правильно преобразовать двоичный файл обратно в символы. В файлах HTML вы можете увидеть строку кода, подобную следующей, вверху:

Это сообщает браузеру, что HTML-файл закодирован в UTF-8, чтобы браузер мог преобразовать его обратно в разборчивый текст.

UTF-8 и UTF-16

Как я уже упоминал, UTF-8 — не единственный метод кодирования символов Unicode. Существует также UTF-16. Эти методы различаются количеством байтов, необходимых для хранения символа. UTF-8 кодирует символ в двоичную строку из одного, двух, трех или четырех байтов. UTF-16 кодирует символ Юникода в строку из двух или четырех байтов.

Это различие очевидно из их имен. В UTF-8 наименьшее двоичное представление символа составляет один байт или восемь бит. В UTF-16 наименьшее двоичное представление символа составляет два байта или шестнадцать бит.

И UTF-8, и UTF-16 могут преобразовывать символы Unicode в двоичные файлы, удобные для компьютера, и обратно. Однако они не совместимы друг с другом. Эти системы используют разные алгоритмы для преобразования кодовых точек в двоичные строки, поэтому двоичный вывод для любого заданного символа будет выглядеть по-разному при использовании обоих методов:

Кодировка UTF-8 предпочтительнее UTF-16 на большинстве веб-сайтов, поскольку она использует меньше памяти. Напомним, что UTF-8 кодирует каждый символ ASCII всего одним байтом. UTF-16 должен кодировать эти же символы двумя или четырьмя байтами. Это означает, что текстовый файл на английском языке, закодированный с помощью UTF-16, будет как минимум вдвое больше, чем тот же файл, закодированный с помощью UTF-8.

UTF-16 эффективнее, чем UTF-8, только на некоторых веб-сайтах, отличных от английского. Если веб-сайт использует язык с более ранними символами в библиотеке Unicode, UTF-8 будет кодировать все символы как четыре байта, тогда как UTF-16 может кодировать многие из тех же символов только как два байта. Тем не менее, если ваши страницы заполнены буквами ABC и 123, придерживайтесь UTF-8.

Расшифровка мира кодировки UTF-8

Это было много слов о словах, так что давайте подытожим то, что мы рассмотрели:

  1. Компьютеры хранят данные, включая текстовые символы, в двоичном формате (1 и 0).
  2. ASCII был одним из первых способов кодирования или преобразования символов в двоичный код, чтобы компьютеры могли их хранить. Однако в ASCII недостаточно места для представления нелатинских символов и чисел в двоичном формате.
  3. Решением этой проблемы стал Unicode. Unicode присваивает уникальный «код» каждому символу в любом человеческом языке.
  4. UTF-8 — это метод кодировки символов Unicode. Это означает, что UTF-8 берет кодовую точку для данного символа Unicode и переводит ее в двоичную строку. Он также делает обратное, читая двоичные цифры и преобразовывая их обратно в символы.
  5. В настоящее время UTF-8 является самым популярным методом кодирования в Интернете, поскольку он может эффективно хранить текст, содержащий любой символ.
  6. UTF-16 — это еще один метод кодирования, но он менее эффективен для хранения текстовых файлов (за исключением тех, которые написаны на некоторых языках, отличных от английского).

Перевод Unicode — это не то, о чем большинству из нас нужно думать при просмотре или разработке веб-сайтов, и именно в этом суть — создать единую систему обработки текста, которая работает для всех языков и веб-браузеров. Если он работает хорошо, вы этого не заметите.

Но если вы обнаружите, что страницы вашего веб-сайта занимают слишком много места или если ваш текст замусорен символами ▢s и �s, пришло время применить ваши новые знания UTF-8 на практике.

Общие вопросы, касающиеся UTF или форм кодировки

Часто задаваемые вопросы по UTF-8

Часто задаваемые вопросы по UTF-16

Часто задаваемые вопросы по UTF-32

Часто задаваемые вопросы о метке порядка байтов (BOM)

Общие вопросы, касающиеся UTF или формы кодировки

< th>Самая большая кодовая точка
Имя UTF-8 UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE
Наименьшая кодовая точка 0000 0000 0000 0000< /td> 0000 0000 0000
10FFFF 10FFFF 10FFFF 10FFFF 10FFFF 10FFFF 10FFFF
Размер блока кода 8 бит 16 бит 16 бит 16 бит 32 бита 32 бита 32 бита
Порядок байтов Н/Д обратный порядок байтов li ttle-endian big-endian little-endian
Наименьшее количество байтов на символ 1 2 2 2 4 4 4
Большинство байтов на символ 4 4 4< /td> 4 4 4 4

Часто задаваемые вопросы по UTF-8

Часто задаваемые вопросы по UTF-16

Вопрос. Что такое UTF-16?

О. В UTF-16 используется одна 16-битная кодовая единица для кодирования наиболее распространенных 63 000 символов и пара 16-битных кодовых единиц, называемых суррогаты, чтобы кодировать 1 миллион менее часто используемых символов в Unicode.

Первоначально Unicode был разработан как чистая 16-битная кодировка, предназначенная для представления всех современных сценариев. (Древние сценарии должны были быть представлены символами для частного использования.) Со временем, особенно после добавления более 14 500 составных символов для совместимости с устаревшими наборами, стало ясно, что 16-битных недостаточно для пользовательского сообщества. Из этого возник UTF-16. [AF]

В: Что такое суррогаты?

О: Суррогаты – это кодовые точки из двух специальных диапазонов значений Unicode, зарезервированные для использования в качестве начальных и конечных значений парного кода. единицы в UTF-16. Ведущие, также называемые старшими, суррогаты — от D80016 до DBFF16, а замыкающие, или нижние, суррогаты — от DC0016 до DFFF< под>16. Их называют суррогатными, так как они не представляют символы напрямую, а только как пару.

В: Каков алгоритм преобразования из UTF-16 в коды символов?

О: Стандарт Unicode раньше содержал короткий алгоритм, теперь есть только таблица распределения битов. Вот три коротких фрагмента кода, которые переводят информацию из таблицы распределения битов в код C, который будет преобразовываться в UTF-16 и обратно.

Используя следующие определения типов

первый фрагмент вычисляет старший (или ведущий) суррогат по коду символа C.

где X, U и W соответствуют меткам, используемым в таблице 3-5 Распределение битов UTF-16. Следующий фрагмент делает то же самое для младшего суррогата.

Наконец, обратная сторона, где hi и lo — старший и младший заместители, а C — результирующий символ

В чем разница между UTF-8 и UTF-8 без спецификации? Что лучше?

UTF-8 лучше автоматически определяется по содержимому, чем по спецификации. Метод прост: попробуйте прочитать файл (или строку) в кодировке UTF-8 и, если это удастся, предположим, что данные в кодировке UTF-8. В противном случае предположим, что это CP1252 (или какая-то другая 8-битная кодировка). Любая восьмибитная кодировка, отличная от UTF-8, почти наверняка будет содержать последовательности, не разрешенные UTF-8. Чистый ASCII (7-битный) интерпретируется как UTF-8, но и в этом случае результат правильный.

Сканирование больших файлов на наличие содержимого UTF-8 требует времени. Спецификация значительно ускоряет этот процесс. На практике часто приходится делать и то, и другое. Виновником в настоящее время является то, что большая часть текстового контента по-прежнему не является Unicode, и я все еще сталкиваюсь с инструментами, которые говорят, что они поддерживают Unicode (например, UTF-8), но выдают свой контент с другой кодовой страницей.

@Tronic Я действительно не думаю, что "лучше" подходит в данном случае. Это зависит от окружающей среды. Если вы уверены, что все файлы UTF-8 помечены спецификацией, то проверка спецификации является "лучшим" способом, поскольку это быстрее и надежнее.

UTF-8 не имеет спецификации. Когда вы помещаете кодовую точку U+FEFF в начало файла UTF-8, необходимо соблюдать особую осторожность при работе с ней. Это всего лишь одна из тех лжи Microsoft, например кодировка "Юникод", когда такой вещи не существует.

"Современные мейнфреймы (и AIX) поддерживают UTF-8 с прямым порядком байтов" UTF-8 не имеет конечности!нет перетасовки байтов, чтобы поместить пары или группы из четырех в правильный «порядок» для конкретной системы! Чтобы обнаружить последовательность байтов UTF-8, может быть полезно отметить, что первый байт многобайтовой последовательности «кодовая точка» (байты, которые НЕ являются «обычными» ASCII) имеет установленный бит MS и все от одного до трех еще последовательно меньшие значащие биты, за которыми следует бит сброса. Общее количество этих установленных битов на один меньше байтов, которые находятся в этой кодовой точке, и они ВСЕ будут иметь установленный старший разряд.

21 Ответ 21

Спецификация UTF-8 – это последовательность байтов в начале текстового потока (0xEF, 0xBB, 0xBF), которая позволяет читателю более надежно угадать, что файл закодирован в UTF-кодировке. 8.

Обычно BOM используется для обозначения порядка следования байтов в кодировке, но, поскольку порядок следования байтов не имеет отношения к UTF-8, в BOM нет необходимости.

Согласно стандарту Unicode, спецификация для файлов UTF-8 не рекомендуется:

2.6 Схемы кодирования

<р>. Использование спецификации не требуется и не рекомендуется для UTF-8, но может встречаться в контекстах, где данные UTF-8 преобразуются из других форм кодирования, использующих спецификацию, или когда спецификация используется в качестве подписи UTF-8. Дополнительную информацию см. в подразделе «Знак порядка следования байтов» в Разделе 16.8, Специальные предложения.

Возможно, это не рекомендуется, но, судя по моему опыту преобразования иврита, спецификация иногда имеет решающее значение для распознавания UTF-8 в Excel и может иметь значение между Jibrish и ивритом

Несмотря на то, что это не рекомендуется стандартом, это разрешено, и я предпочитаю иметь что-то, что действует как подпись UTF-8, а не альтернативы предположения или предположения. Программное обеспечение, совместимое с Unicode, должно/должно справляться с его присутствием, поэтому я лично поощряю его использование.

@bames53: Да, в идеальном мире сохранение кодировки текстовых файлов в качестве метаданных файловой системы было бы лучшим способом их сохранения. Но большинство из нас, живущих в реальном мире, не могут изменить файловую систему ОС, на которой запускаются наши программы, поэтому использование независимой от платформы подписи спецификации стандарта Unicode кажется лучшей и наиболее практичной альтернативой ИМХО.< /p>

@martineau Буквально вчера я наткнулся на файл со спецификацией UTF-8, которая не была UTF-8 (это был CP936). К сожалению, те, кто несет ответственность за огромную боль, вызванную спецификацией UTF-8, в значительной степени не обращают на это внимания.

Другие отличные ответы уже ответили на это:

  • Официальной разницы между UTF-8 и UTF-8 в спецификации нет.
  • Строка UTF-8 в формате BOM будет начинаться с трех следующих байтов. ЭФ ББ БФ
  • Эти байты, если они есть, должны игнорироваться при извлечении строки из файла/потока.

Но, в качестве дополнительной информации, спецификация для UTF-8 может быть хорошим способом "понюхать", если строка была закодирована в UTF-8. Или это может быть допустимая строка в любой другой кодировке.

Например, данные [EF BB BF 41 42 43] могут быть:

Поэтому, хотя может быть здорово распознать кодировку содержимого файла, просматривая первые байты, вы не должны полагаться на это, как показано в примере выше

Кодировки нужно знать, а не угадывать.

@deceze Это, вероятно, лингвистически недопустимо: сначала ï (что допустимо), затем какие-то кавычки без пробела между ними (недопустимо). ¿ указывает на то, что это испанский язык, но ï не используется в испанском языке. Вывод: это не латиница-1 с достоверностью намного выше, чем без нее.

@user Конечно, это не обязательно имеет смысл. Но если ваша система полагается на угадывание, вот тут-то и возникают неопределенности. Какой-то злонамеренный пользователь намеренно отправляет текст, начинающийся с этих трех букв, и ваша система внезапно предполагает, что она смотрит на UTF-8 со спецификацией, обрабатывает текст как UTF-8, где он должен использовать Latin-1, и имеет место некоторая инъекция Unicode. Просто гипотетический пример, но вполне возможный. Вы не можете судить о кодировке текста по его содержанию, и точка.

"Кодировки нужно знать, а не угадывать". Сердце и душа проблемы. +1, добрый сэр. Другими словами: либо стандартизируйте свой контент и скажите: «Мы всегда используем эту кодировку. Точка. Пишите так. Читайте так», либо разработайте расширенный формат, позволяющий хранить кодировку в виде метаданных. (Последнее, вероятно, также нуждается в какой-то «стандартной кодировке начальной загрузки». Например, сказать: «Часть, которая говорит вам, что кодировка всегда ASCII».)

Существует как минимум три проблемы с размещением спецификации в файлах с кодировкой UTF-8.

  1. Файлы, не содержащие текста, больше не являются пустыми, поскольку они всегда содержат спецификацию.
  2. Файлы, содержащие текст, который находится в подмножестве ASCII UTF-8, сами по себе больше не являются ASCII, поскольку спецификация не является ASCII, что приводит к поломке некоторых существующих инструментов, и пользователи могут быть не в состоянии заменить такие устаревшие инструменты.
  3. Невозможно объединить несколько файлов вместе, поскольку каждый файл теперь имеет спецификацию в начале.

И, как уже упоминалось, не достаточно и не нужно иметь спецификацию, чтобы определить, что что-то является UTF-8:

  • Этого недостаточно, поскольку произвольная последовательность байтов может начинаться с точной последовательности, составляющей спецификацию.
  • В этом нет необходимости, потому что вы можете просто прочитать байты, как если бы они были в кодировке UTF-8; если это удается, это по определению допустимая UTF-8.

Относительно пункта 1 «Файлы, не содержащие текста, больше не пусты, поскольку они всегда содержат спецификацию», это (1) объединяет уровень файловой системы ОС с интерпретируемым уровнем содержимого, а также (2) ошибочно предполагает, что использование одной спецификации также должен поместить спецификацию в каждый пустой файл. Практическое решение (1) состоит в том, чтобы не делать (2). По сути, жалоба сводится к тому, что «возможно нецелесообразно помещать спецификацию в пустой файл, что препятствует наиболее простому обнаружению логически пустого файла (путем проверки размера файла)». Тем не менее, хорошее программное обеспечение должно с этим справляться, поскольку оно имеет свое предназначение.

Относительно пункта 3: "Невозможно объединить несколько файлов вместе, потому что каждый файл теперь имеет спецификацию в начале", это просто неправильно. У меня нет проблем с объединением файлов UTF-8 с BOM, так что это вполне возможно. Я думаю, может быть, вы имели в виду, что Unix-land cat не даст вам чистый результат, результат, который имеет спецификацию только в начале. Если вы имели в виду это, то это потому, что кошка работает на уровне байтов, а не на уровне интерпретируемого содержимого, и аналогичным образом кошка не может работать, скажем, с фотографиями. Тем не менее, это не приносит большого вреда. Это связано с тем, что спецификация кодирует неразрывный пробел нулевой ширины.

Вот примеры использования спецификации, которые на самом деле вызывают серьезные проблемы, но многие люди не знают об этом.

BOM ломает скрипты

Сценарии оболочки, сценарии Perl, сценарии Python, сценарии Ruby, сценарии Node.js или любой другой исполняемый файл, который должен запускаться интерпретатором — все они начинаются со строки шебанга, похожей на одну из этих:

Символы шебанга представлены одними и теми же двумя байтами в расширенной кодировке ASCII, включая UTF-8, которая обычно используется для скриптов и других текстовых файлов в современных Unix-подобных системах. Однако файлы UTF-8 могут начинаться с необязательного знака порядка байтов (BOM); если функция «exec» специально определяет байты 0x23 и 0x21, то наличие спецификации (0xEF 0xBB 0xBF) перед шебангом предотвратит выполнение интерпретатора сценариев. Некоторые авторитетные источники рекомендуют не использовать метку порядка следования байтов в сценариях POSIX (Unix-подобных) [14] по этой причине, а также из соображений более широкой совместимости и философских соображений. Кроме того, в UTF-8 нет необходимости в отметке порядка следования байтов, поскольку в этой кодировке нет проблем с порядком байтов; он служит только для идентификации кодировки как UTF-8. [выделение добавлено]

Спецификация недопустима в JSON

Реализации НЕ ДОЛЖНЫ добавлять метку порядка следования байтов в начало текста JSON.

BOM является избыточным в JSON

Это не только незаконно в JSON, но и не нужно определять кодировку символов, потому что есть более надежные способы однозначно определить как кодировку символов, так и порядок следования байтов, используемые в любом потоке JSON (подробности см. в этом ответе).< /p>

BOM ломает синтаксические анализаторы JSON

Это не только запрещено в JSON и не нужно, но фактически ломает все программное обеспечение, определяющее кодировку с помощью метода, представленного в RFC 4627:

Определение кодировки и порядка следования байтов JSON, проверка первых четырех байтов на наличие байта NUL:

Теперь, если файл начинается с BOM, он будет выглядеть так:

  1. UTF-32BE не начинается с трех NUL, поэтому он не будет распознан
  2. UTF-32LE: за первым байтом не следуют три NUL, поэтому он не будет распознан
  3. UTF-16BE имеет только один NUL в первых четырех байтах, поэтому он не будет распознан
  4. UTF-16LE имеет только один NUL в первых четырех байтах, поэтому он не будет распознан

В зависимости от реализации все они могут быть неправильно интерпретированы как UTF-8, а затем неверно истолкованы или отклонены как недействительные UTF-8 или вообще не распознаны.

Кроме того, если реализация проверяет правильность JSON, как я рекомендую, она отклонит даже входные данные, которые действительно закодированы как UTF-8, поскольку они не начинаются с символа ASCII

rfc7159, который заменяет rfc4627, на самом деле предполагает, что поддержка BOM может быть не такой уж плохой. По сути, отсутствие спецификации — это просто двусмысленный ляп, так что старое программное обеспечение Windows и Unix, не поддерживающее Unicode, все еще может обрабатывать utf-8.

Похоже, что JSON нуждается в обновлении, чтобы поддерживать его, то же самое со скриптами Perl, скриптами Python, скриптами Ruby, Node.js. Тот факт, что эти платформы решили не включать поддержку, не обязательно убивает использование BOM. Apple уже несколько лет пытается убить Adobe, и Adobe все еще существует. Но поучительный пост.

@EricGrange, вы, кажется, очень сильно поддерживаете спецификацию, но не понимаете, что это сделало бы вездесущий, универсально полезный формат оптимально-минимум «обычный текст» пережитком прошлое до UTF8! Добавление любого вида (внутриполосного) заголовка к потоку простого текста по определению налагает обязательный протокол на простейшие текстовые файлы, что делает его никогда более " самый простой"! И для какой выгоды? Для поддержки всех других древних кодировок CP, которые также не имели сигнатур, чтобы вы могли спутать их с UTF-8? (Кстати, ASCII — это тоже UTF-8. Значит, для них тоже спецификация? ;) Да ладно.)

Этот ответ и есть причина, по которой я задал этот вопрос! Я создал свои bash-скрипты в Windows и столкнулся с множеством проблем при публикации этих скриптов в Linux! То же самое с файлами jason.

В чем разница между UTF-8 и UTF-8 без BOM?

Краткий ответ: в UTF-8 спецификация кодируется как байты EF BB BF в начале файла.

Изначально предполагалось, что Unicode будет кодироваться в UTF-16/UCS-2. Спецификация была разработана для этой формы кодирования. Когда у вас есть 2-байтовые единицы кода, необходимо указать, в каком порядке находятся эти два байта, и общепринятым соглашением для этого является включение символа U+FEFF в качестве «метки порядка байтов» в начале данных. Символ U+FFFE постоянно не назначается, поэтому его присутствие можно использовать для обнаружения неправильного порядка байтов.

UTF-8 имеет одинаковый порядок байтов независимо от порядка следования байтов платформы, поэтому метка порядка байтов не требуется. Однако он может встречаться (как последовательность байтов EF BB FF ) в данных, которые были преобразованы в UTF-8 из UTF-16, или как «подпись», указывающая, что данные имеют формат UTF-8.

Без. Как ответил Мартин Кот, стандарт Unicode этого не рекомендует. Это вызывает проблемы с программным обеспечением, не поддерживающим спецификацию.

Лучший способ определить, является ли файл кодировкой UTF-8, – это выполнить проверку правильности. UTF-8 имеет строгие правила относительно того, какие последовательности байтов допустимы, поэтому вероятность ложного срабатывания незначительна. Если последовательность байтов выглядит как UTF-8, скорее всего, так оно и есть.

-1 относительно «Это вызывает проблемы с программным обеспечением, не поддерживающим BOM.», Это никогда не было проблемой для меня, но, наоборот, отсутствие спецификации вызывает проблемы с программным обеспечением, поддерживающим BOM (в частности, Visual C++) была проблема. Таким образом, это утверждение очень специфично для платформы, узкой точки зрения страны Unix, но представлено в заблуждение так, как будто оно применимо в целом. Чего нет.

Вы даже можете подумать, что у вас есть чистый ASCII-файл, просто взглянув на байты. Но это может быть и файл utf-16, где вам придется смотреть на слова, а не на байты. Современное программное обеспечение должно знать о спецификациях. Тем не менее чтение utf-8 может завершиться ошибкой при обнаружении недопустимых последовательностей, кодовых точек, которые могут использовать меньшую последовательность, или кодовых точек, которые являются суррогатными. Чтение utf-16 также может завершиться ошибкой, если есть потерянные суррогаты.

@Alf, я не согласен с вашей интерпретацией отношения, не связанного с спецификацией, как "специфичной для платформы, узкой точки зрения Unix". Для меня единственная причина, по которой ограниченность могла бы заключаться в «стране Unix», заключалась в том, что MS и Visual C++ появились раньше *NIX, чего не было. Тот факт, что MS (я полагаю сознательно) начала использовать спецификацию в UTF-8, а не в UTF-16, наводит меня на мысль, что они способствовали взлому sh , perl , g++ и многих других бесплатных и мощных инструментов. Хотите, чтобы все работало? Просто купите версии MS. MS создала проблему, специфичную для платформы, точно так же, как катастрофа с их диапазоном \x80-\x95.

UTF-8 с BOM лучше идентифицируется. Я пришел к этому выводу трудным путем. Я работаю над проектом, в котором одним из результатов является файл CSV, включающий символы Юникода.

Если CSV-файл сохранен без спецификации, Excel считает, что это ANSI, и отображает тарабарщину. Как только вы добавите «EF BB BF» впереди (например, повторно сохранив его с помощью «Блокнота» с кодировкой UTF-8 или Notepad++ с кодировкой UTF-8 и спецификацией), Excel откроет его нормально.

Спасибо за этот отличный совет, если вы создаете файлы UTF-8 для использования в Excel. Однако в других обстоятельствах я бы все равно следовал другим ответам и пропустил спецификацию.

Это также полезно, если вы создаете файлы, которые содержат только ASCII, а позже к ним могут быть добавлены не-ASCII. Я только что столкнулся с такой проблемой: программное обеспечение, которое ожидает utf8, создает файл с некоторыми данными для редактирования пользователем. Если исходный файл содержит только ASCII, открывается в каких-то редакторах, а затем сохраняется, он оказывается в латинице-1 и все ломается. Если я добавлю спецификацию, она будет определена редактором как UTF8, и все будет работать.

Я нашел несколько инструментов, связанных с программированием, которые требуют, чтобы спецификация правильно распознавала файлы UTF-8. Visual Studio, SSMS, SoureTree.

Где вы прочитали рекомендацию по использованию спецификации в этом RFC? В лучшем случае настоятельно рекомендуется не запрещать это при определенных обстоятельствах, когда это сложно сделать.

Очень раздражает, когда он появляется в труднодоступных для отладки местах или когда тестированием пренебрегают. Так что лучше избегать его, если вы не должны его использовать.

Да, я потратил часы на выявление проблемы, вызванной файлом, закодированным как UTF-8 вместо UTF-8 без BOM. (Проблема обнаружилась только в IE7, так что это привело меня в погоню за гусем. Я использовал Django «include».)

Будущие читатели: обратите внимание, что проблема твита, о которой я упоминал выше, не была строго связана с BOM, но если бы это было так, то твит был бы искажен аналогичным образом, но в начале твита.

@user984003 Нет, проблема в том, что Microsoft ввела вас в заблуждение. То, что он называет UTF-8, не является UTF-8. То, что он называет UTF-8 без BOM, на самом деле является UTF-8.

@JoelFan Я уже не могу вспомнить, но я думаю, что каламбур мог быть задуман, несмотря на заявление автора :)

Вопрос. В чем разница между UTF-8 и UTF-8 без спецификации? Что лучше?

Вот несколько выдержек из статьи Википедии о метках порядка байтов (BOM), которые, как мне кажется, дают четкий ответ на этот вопрос.

О значении спецификации и UTF-8:

Стандарт Unicode разрешает спецификацию в UTF-8, но не требует и не рекомендует ее использование. Порядок байтов не имеет значения в UTF-8, поэтому он используется только в UTF-8, чтобы в начале сигнализировать о том, что текстовый поток закодирован в UTF-8.

Аргумент в пользу НЕ использования спецификации:

Основной причиной отказа от использования спецификации является обратная совместимость с программным обеспечением, не поддерживающим Unicode. Другой причиной отказа от использования спецификации является использование UTF-8 в качестве кодировки по умолчанию.

Аргумент ЗА с использованием спецификации:

Что лучше, С или БЕЗ спецификации:

IETF рекомендует, чтобы, если протокол либо (а) всегда использовал UTF-8, либо (б) имел другой способ указать, какая кодировка используется, то он «СЛЕДУЕТ запретить использование U+FEFF как подпись.”

Мой вывод:

Используйте спецификацию только, если совместимость с программным приложением абсолютно необходима.

Также обратите внимание, что, хотя в упомянутой статье Википедии указано, что многие приложения Microsoft полагаются на спецификацию для правильного определения UTF-8, это не относится к всем приложениям Microsoft. Например, как указал @barlop, при использовании командной строки Windows с UTF-8 † команды такого типа и другие не ожидают наличия спецификации. Если спецификация присутствует, это может быть проблематично, как и для других приложений.

† Команда chcp предлагает поддержку UTF-8 (без спецификации) через кодовую страницу 65001.

Читайте также: