Unicode路径的MATLAB实现

Unicode路径的MATLAB实现,matlab,unicode,low-level-io,Matlab,Unicode,Low Level Io,以下代码试图在当前MATLAB路径中创建2个文件夹: %% 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); mkd

以下代码试图在当前MATLAB路径中创建2个文件夹:

%%
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
调用成功,第二个调用失败,错误消息为“文件名、目录名或卷标语法不正确”。但是,在“当前文件夹”GUI面板中手动创建文件夹([右键单击]⇒新文件夹⇒[粘贴名称])没有遇到任何问题。这种故障出现在大多数MATLAB的低级I/O函数中(
dir
fopen
copyfile
movefile
等),我想使用所有这些函数

环境是:

  • Win7企业版(32位,NTFS)
  • MATLAB R2012a
因此,文件系统支持path中的Unicode字符,MATLAB可以存储真正的Unicode字符串(而不是“伪造”它们)

mkdir
优雅地{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} 对于“优雅”一词的松散含义,如果您在Windows上,请尝试使用UTF-16,因为NTFS使用UTF-16进行文件名编码,Windows有两套API:一套用于所谓的“Windows代码页”(1250、1251、1252等),另一套使用C的
char
数据类型,另一套使用
wchar\u t
。后一种类型在Windows上的大小为2字节,足以存储UTF-16代码单元

第一次调用成功的原因是,Unicode标准中的前128个代码点以UTF-8编码,与128个ASCII字符相同(这是为了向后兼容而进行的)。UTF-8使用1字节代码单元(而不是UTF-16的2字节代码单元),通常MATLAB等软件不处理文件名,因此它们只需要存储字节序列并将其传递给OS API。第二个调用失败,因为表示代码点的UTF-8字节序列可能被Windows过滤掉,因为某些字节值在文件名中被禁止。在符合POSIX标准的操作系统上,大多数API都是面向字节的,标准API不允许您在API中使用现有的多字节编码(例如UTF-16、UTF-32),您必须使用
char*
API和带有1字节代码单位的编码:

POSIX.1-2008仅对编码设备提出以下要求: 可移植字符集中字符的值:

  • 与实现支持的所有语言环境相关联的编码值应保持不变
  • 与可移植字符集成员相关联的编码值均以单个字节表示。此外,如果 值存储在C语言类型char的对象中,它保证为正(NUL除外,NUL始终为零)
并非所有符合POSIX的操作系统都会验证除句点或斜杠之外的文件名,因此您几乎可以在文件名中存储垃圾。Mac OS X作为POSIX系统,使用面向字节的(
char*
)API,但底层的HFS+UTF-16采用(规范化格式D),因此在保存文件名之前,在操作系统级别进行一些处理

Windows不执行任何类型的Unicode规范化,并以UTF-16(如果使用NTFS)或Windows代码页(不确定它们在文件系统级别如何处理此问题-可能是通过转换)中传递的任何形式存储文件名

那么,这与MATLAB有什么关系呢?它是跨平台的,因此必须处理许多问题。其中之一是Windows有用于Windows代码页的
char
API和文件名中的某些禁止字符,而其他操作系统没有。他们可以实现依赖于系统的检查,但这将更难测试和支持(我想可能是大量的代码搅动)


我最好的建议是在Windows上使用UTF-16,实现平台相关检查,或者在需要可移植性的情况下使用ASCII。

有关MATLAB如何处理文件名(以及一般字符)的一些有用信息可以在的评论中找到(特别是MathWorks的Steve Eddins的评论)简而言之:

“MathWorks开始将MATLAB代码库中的所有字符串处理转换为UTF-16…我们已经逐步实现了这一目标”

--Steve Eddins,2014年12月

这句话意味着MATLAB版本越新,支持UTF-16的功能就越多。这反过来意味着如果存在更新MATLAB版本的可能性,则可能是e
java.io.File(fullfile(pwd,native2unicode(...
          [255 254 234 5 217 5 231 5 217 5 212 5],'UTF-16'))).mkdir();
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'));
fid = fopen([native2unicode([255,254,231,5,213,5,209,5,229,5],'utf-16') '.txt']);
txt =  textscan(fid,'%s');