Какая кодировка используется при вызове fopen или open?

Когда мы вызываем системный вызов в Linux, например «open», или функцию stdio, например «fopen», мы должны предоставить «const char * filename». Мой вопрос в том, какая кодировка используется здесь? Это utf-8 или ascii или iso8859-x? Зависит ли это от настроек системы или среды?

Я знаю, что в MS Windows есть _wopen, которые принимают utf-16.


person xeranic    schedule 05.01.2010    source источник
comment
Связанный: serverfault. ком/вопросы/87055/   -  person    schedule 05.01.2010


Ответы (6)


Это строка байтов, интерпретация зависит от конкретной файловой системы.

person Andrew McGregor    schedule 05.01.2010

Это зависит от локали системы. Посмотрите на вывод команды «locale». Если переменные заканчиваются на UTF-8, то ваша локаль — UTF-8. Большинство современных Linux будут использовать UTF-8. Хотя Эндрю прав в том, что технически это просто строка байтов, если вы не соответствуете языковому стандарту системы, некоторые программы могут работать неправильно, и будет невозможно получить правильный пользовательский ввод и т. д. Лучше придерживаться UTF-8.

person Matthew Talbert    schedule 05.01.2010
comment
Обратите внимание, что могут быть файлы, имена которых закодированы в кодировке, отличной от системной по умолчанию, например, если вы распаковываете архив (tarball, ZIP и т. д.), который был упакован кем-то с кодировкой, отличной от вашей. - person alvherre; 05.01.2010
comment
Действительно, это очень верно. Разве мы не хотим, чтобы все использовали UTF-8? - person Matthew Talbert; 05.01.2010
comment
Нет, это не зависит от локали системы. Не существует такой вещи, как локаль системы. Есть только пользовательские локали. Результат open или fopen также не зависит от языкового стандарта пользователя. - person n. 1.8e9-where's-my-share m.; 11.06.2018

Вызовы файловой системы в Linux не зависят от кодировки, т.е. они не (не должны) знать о конкретной кодировке. Для них строка байтов, на которую указывает аргумент имени файла, передается в файловую систему как есть. Файловая система ожидает, что имена файлов имеют правильную кодировку (обычно UTF-8, как упоминал Мэтью Талберт).

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

person JesperE    schedule 05.01.2010
comment
Файловая система ожидает, что имена файлов имеют правильную кодировку. Обычные файловые системы Linux, такие как семейство ext, не ожидают никакой кодировки. Они ожидают строку байтов. Драйверы NTFS в Linux взаимодействуют с драйверами и кодировками, но это исключение. - person n. 1.8e9-where's-my-share m.; 11.06.2018

Как уже упоминалось выше, это будет строка байтов, и интерпретация будет открыта для базовой системы. Точнее, представьте себе C-функции; один в пространстве пользователя и один в пространстве ядра, которые принимают char * в качестве параметра. Кодировка в пользовательском пространстве будет зависеть от набора символов выполнения пользовательской программы (например, заданного -fexec-charset=charset в gcc). Кодировка, ожидаемая функцией ядра, зависит от набора символов выполнения, используемого во время компиляции ядра (не знаю, где взять эту информацию).

person tinkerbeast    schedule 22.01.2020

Имя файла является строкой байтов; независимо от языкового стандарта или любых других используемых вами соглашений о том, как должны быть закодированы имена файлов, строка, которую вы должны передать fopen и всем функциям, принимающим имена файлов/пути, является точной строкой байтов для имени файла. Например, если у вас есть файл с именем ö.txt в кодировке UTF-8 в NFC, а ваша локаль имеет кодировку UTF-8 и использует NFC, вы можете просто написать имя как ö.txt и передать его fopen. Однако, если ваша локаль основана на латинице-1, вы не можете передать латинскую-1 форму ö.txt ("\xf6.txt") в fopen и ожидать, что она будет успешной; это другая строка байтов и, следовательно, другое имя файла. Вам нужно будет передать "\xc3\xb6.txt" ("ö.txt", если вы интерпретируете это как Latin-1), ту же строку байтов, что и фактическое имя.

Эта ситуация очень отличается от Windows, с которой вы, кажется, знакомы, где имя файла is представляет собой последовательность 16-битных единиц, интерпретируемых как UTF-16 (хотя, насколько мне известно, они не обязательно должны быть действительными UTF -16), а имена файлов, переданные в fopen и т. д., интерпретируются в соответствии с текущей локалью как символы Unicode, которые затем используются для открытия/доступа к файлу на основе его имени UTF-16.

person R.. GitHub STOP HELPING ICE    schedule 23.01.2020

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

  1. Имена файлов закодированы в «системном языковом стандарте», который обычно является, но не обязательно должен совпадать с текущим языковым стандартом среды, который отражается командой locale (но некоторая предустановка в глобальном файле конфигурации).

  2. Имена файлов кодируются в UTF-8 независимо от каких-либо региональных настроек.

GTK+ решает эту проблему, предполагая использование UTF-8 и позволяя переопределить его либо текущей кодировкой локали, либо кодировкой, предоставленной пользователем.

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

Таким образом, суть такова: используйте либо UTF-8, либо то, что LC_ALL или LANG говорят вам по умолчанию, и укажите параметр переопределения, по крайней мере, для другой альтернативы.

person following    schedule 13.05.2015