2015-08-03 5 views
12

Учитывая следующий код, который пытается создать 2 папки в текущем пути MATLAB:Unicode пути с MATLAB

%% 
u_path1 = native2unicode([107, 97, 116, 111, 95, 111, 117, 116, 111, 117], 'UTF-8'); % 'kato_outou' 
u_path2 = native2unicode([233 129 142, 230 184 161, 229 191 156, 231 173 148], 'UTF-8'); % '過渡応答' 

mkdir(u_path1); 
mkdir(u_path2); 

первый mkdir вызов успешен, а второй выходит из строя, с сообщением об ошибке «имя файла, каталог имя или синтаксис метки тома ". Однако создание папок вручную на панели «Текущая папка» ([щелкните правой кнопкой мыши] ⇒ Новая папка ⇒ [имя пасты]) не вызывает проблем. Такие сбои появляются в большинстве функций ввода/вывода низкого уровня MATLAB (dir, fopen, copyfile, movefile и т. Д.), И я хотел бы использовать все эти функции.

Среда:

  • Win7 Enterprise (32 бит, NTFS)
  • MATLAB R2012a

таким образом, файловая система поддерживает символы Unicode в пути, и MATLAB может хранить истинные строки Unicode (а не «подделывать» их).

mkdirofficial documentation элегантно {1} избегает этой проблемы, заявив, что правильный синтаксис для вызова функции является:

mkdir('folderName') 

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

Интересно, есть ли способ обойти эти ограничения. Меня бы интересовали решения, которые:

  • не полагаются на недокументированные/неподдерживаемые материалы MATLAB;

  • не связаны с общесистемными изменениями (например, с изменением информации об операционной системе);

  • может в конечном итоге полагаться на не-родные библиотеки MATLAB, так как полученные обработчики/объекты могут быть преобразованы в собственные объекты MATLAB и управляться как таковые;

  • может в конечном итоге полагаться на манипуляции с путями, которые могли бы сделать их пригодными для использования стандартными функциями MATLAB, даже если Windows специфична (например, пути с короткими именами).

Позже редактировать

Что я ищу в реализации для следующих функций, которые будут ТЕНЬ оригиналы в коде, который уже написано:

function listing = dir(folder); 
function [status,message,messageid] = mkdir(folder1,folder2); 
function [status,message,messageid] = movefile(source,destination,flag); 
function [status,message,messageid] = copyfile(source,destination,flag); 
function [fileID, message] = fopen(filename, permission, machineformat, encoding); 
function status = fclose(fileID); 
function [A, count] = fread(fileID, sizeA, precision, skip, machineformat); 
function count = fwrite(fileID, A, precision, skip, machineformat); 
function status = feof(fileID); 
function status = fseek(fileID, offset, origin); 
function [C,position] = textscan(fileID, varargin); %'This one is going to be funny' 

Не все типы вывода должны быть взаимозаменяемы с оригинальными функциями MATLAB, однако должны быть согласованы между вызовами функций (например, fileID между fopen и fclose). Я собираюсь обновить этот список объявлений с помощью реализаций, как только я их получу/напишу.


{1} для очень рыхлых значений слова "элегантный".

+3

Я ничего не знаю о Matlab, но эти функции, скорее всего, тонкие оберток над функциями ввода/вывода стандартной библиотеки C файла. Эти интерфейсы явно принимают имена файлов в виде строк байтов, которые Windows преобразует в собственный формат UTF-16 с использованием кодовой страницы ANSI. Для приложения, использующего функции stdio, нет способа получить доступ к файлам, чьи имена содержат символы вне этой кодировки (а кодовая страница ANSI никогда не будет полезной, как UTF). – bobince

+0

@bobince То, как эти функции ведут себя, я подозреваю, что тоже. Тем не менее, я надеялся, что они обернут скорее системные вызовы (которые полностью поддерживают функции базовой файловой системы), чем стандартные функции библиотеки, которые ограничены их исторической аргументацией/типом. –

ответ

0

Попробуйте использовать UTF-16, если вы работаете в Windows, потому что NTFS использует UTF-16 для кодирования имени файла, а Windows имеет два набора API-интерфейсов: те, которые работают с так называемыми «Windows Codepages» (1250, 1251, 1252 и т. Д.). .) и использовать тип данных C char и те, которые используют wchar_t. Последний тип имеет размер 2 байта в Windows, которого достаточно для хранения кодовых блоков UTF-16.

Причина, по которой ваш первый вызов работал, состоит в том, что первые 128 кодовых точек в стандарте Unicode закодированы в UTF-8 идентично 128 символам ASCII (что сделано специально для обратной совместимости). UTF-8 использует 1-байтовые кодовые единицы (вместо 2-байтовых кодовых блоков для UTF-16), и обычно программное обеспечение, такое как MATLAB, не обрабатывает имена файлов, поэтому им нужно просто хранить байтовые последовательности и передавать их в OS API. Второй вызов завершился неудачно, поскольку байтовые последовательности UTF-8, представляющие кодовые точки, вероятно, отфильтрованы Windows, потому что некоторые байтовые значения запрещены в именах файлов. В совместимых с POSIX операционных системах большинство API-интерфейсов являются байт-ориентированными, а стандартный pretty much prevents вы используете существующие многобайтовые кодировки в API (например, UTF-16, UTF-32), и вам необходимо использовать API и кодировки char* с 1-байтным кодом единицы:

POSIX.1-2008 места только следующие требования к кодированным значений символов в портативном наборе символов:

...

  • кодированные значения, связанные с и должны быть инвариантными по l, поддерживаемых реализацией.
  • Закодированные значения, связанные с элементами переносимого набора символов, представлены в одним байтом. Более того, если значение хранится в объекте символа типа C-языка, он гарантированно будет положительным (кроме NUL, который всегда равен нулю).

Не все POSIX-совместимую операционных систем, отличных от проверки на период имен файлов или слэш так что вы можете довольно много магазина мусора в именах файлов. Mac OS X, как система POSIX, использует байт-ориентированные (char*) API, но лежащую в основе HFS + uses UTF-16 в NFD (форма нормализации D), поэтому некоторая обработка выполняется на уровне ОС перед сохранением имени файла.

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

Итак, как это соотносится с MATLAB? Ну, это кросс-платформенный и из-за этого приходится иметь дело со многими проблемами. Один из них заключается в том, что Windows имеет API для Windows Codepages и некоторые запрещенные символы в именах файлов, в то время как другие операционные системы этого не делают. Они могли бы выполнять зависящие от системы проверки, но это было бы намного сложнее протестировать и поддерживать (много ошибок, которые я предполагаю).

Мой лучший совет - использовать UTF-16 для Windows, реализовать проверки на платформе или использовать ASCII, если вам нужна переносимость.

+0

Спасибо за обширный ответ. Несколько комментариев: 1) вызовы 'native2unicode' производят UTF-16 (или, по меньшей мере, UCS-2) из ​​байтов UTF-8. Это легко проверить при преобразовании строки 'u_path2' в числовой:' double (u_path2) 'дает' [36942, 28193, 24540, 31572] 'как и ожидалось для строки 4-идеограммы. 2) Я понимаю, почему эти функции могут не работать (хотя для среды программирования, которая заявляет о себе на переднем крае техники, неспособная реализовать стандарт 90-х годов, является довольно хромой). Я готов предложить расширенное решение, а не решить ограниченную проблему. :-) –

+0

насчет: 'u_path2 = native2unicode ([233 129 142, 230 184 161, 229 191 156, 231 173 148], 'UTF-16');' ли эту работу на Windows? –

+0

Он дает ту же ошибку при попытке создать папку. Однако содержимое строки изменяется (как и ожидалось). –

3

Некоторая полезная информация о том, как MATLAB обрабатывает имена файлов (и символы в целом), доступна в комментариях this UndocumentedMatlab post (особенно тех, которые Стив Эддинс, который работает в MathWorks). Короче говоря:

"MathWorks начал конвертировать все обработки в базе кода MATLAB в UTF-16 строку .... и мы приблизились к нему постепенно"

--Steve Eddins , Декабрь 2014.

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

Ниже приведен список функций, которые были протестированы пользователями на разных платформах, в соответствии с функциональностью, которая была запрошена в вопросе:

  • Следующая команда создает каталог с UTF16 символами в имени ("תיקיה" на иврите, в данном примере) в пределах от MATLAB:

    java.io.File(fullfile(pwd,native2unicode(... 
          [255 254 234 5 217 5 231 5 217 5 212 5],'UTF-16'))).mkdir(); 
    

    Проверено на:

    • Windows 7 с MATLAB R2015a по Dev-iL
    • OSX Йосемити (10.10.4) с MATLAB R2014b по Matt
  • Следующие команды также, кажется, для создания каталогов успешно:

    mkdir(native2unicode([255 254 234 5 217 5 231 5 217 5 212 5],'utf-16')); 
    mkdir(native2unicode([215,170,215,153,215,167,215,153,215,148],'utf-8')); 
    

    Испытано на:

    • Windows 10 с MATLAB R2015a имеющий feature('DefaultCharacterSet') =>windows-1255 от Dev-iL
    • OSX Йосемитов (10.10.4) с MATLAB R2014b по Matt
      Значение feature('DefaultCharacterSet') не имеет никакого влияния здесь потому, что кодирование явно определенно в команде native2unicode.
  • следующие команды успешно открыть файл, имеющий Юникода как в его названии и как его содержание:

    fid = fopen([native2unicode([255,254,231,5,213,5,209,5,229,5],'utf-16') '.txt']); 
    txt = textscan(fid,'%s'); 
    

    Проверено на:

    • Windows 10 с MATLAB R2015a имея feature('DefaultCharacterSet') = >windows-1255 by Dev-iL. Примечание. Отсканированный текст отображается правильно в Переменные вид. Текстовый файл можно редактировать и сохранять из редактора MATLAB с символами UTF.
    • OSX Йосемитская (10.10.4) с помощью MATLAB R2014b Matt
      If feature('DefaultCharacterSet') установлен в utf-8 перед использованием textscan, выход celldisp(txt) отображается правильно. То же самое относится к Переменные вид.
+1

@Matt - На самом деле идея заключалась в том, что это будет список, и любой желающий может добавить дополнительные функции от тех, которые запросили OP. Мой ответ был началом списка, с большим количеством пунктов, которые будут позже. Поэтому я думаю, что ваше редактирование должно быть в основном отменено. –

+0

Достаточно честно ... Я вернул свое редактирование. – Matt

Смежные вопросы