将unix/linux文件名字符集转换为windows

将unix/linux文件名字符集转换为windows,linux,windows,unix,unicode,filenames,Linux,Windows,Unix,Unicode,Filenames,我使用mkdir()通过PHP以波斯语和阿拉伯语创建了一些目录 我想将文件夹移动到windows中,但文件夹名称有问题 示例:我写道:“سلام” 但在窗口中显示未知字符:“طغŒططھظطط§……ظ 似乎应该转换为UTF-8以外的其他编码 对不起,如果我的英语不是很好 多谢各位 编辑: 我使用此Powershell代码并为我工作: Get-ChildItem | ForEach-Object { $filename = Split-Path -Leaf $_ $new = [Text.

我使用mkdir()通过PHP以波斯语和阿拉伯语创建了一些目录

我想将文件夹移动到windows中,但文件夹名称有问题

示例:我写道:“سلام”

但在窗口中显示未知字符:“طغŒططھظطط§……ظ

似乎应该转换为UTF-8以外的其他编码

对不起,如果我的英语不是很好

多谢各位

编辑: 我使用此Powershell代码并为我工作:

Get-ChildItem | ForEach-Object {
  $filename = Split-Path -Leaf $_
  $new = [Text.Encoding]::Utf8.GetString([Text.Encoding]::Default.GetBytes($filename))
  if ($_.Name -ne $new) {
    Rename-Item $_ $new
  }
}
enter code here
但是我希望上面的代码也能更正所有子文件夹的名称

似乎应该转换为UTF-8以外的其他编码

是:当您在基于字节的C标准库文件接口中使用文件名字符串时(这是PHP和大多数其他跨平台语言所做的),您将获得Windows默认(“ANSI”)代码页。这种编码依赖于语言环境,更糟糕的是,它从来都不是UTF-8

根据上述文件名判断,您的默认代码页是1256阿拉伯语。如果您将文件名编码为cp1256,则应该可以:

$localfilename= iconv('utf-8', 'windows-1256', $filename);
然而:

  • 这意味着您只能在文件名中使用阿拉伯语(和ASCII)字符-任何其他Unicode字符都将中断

  • 如果部署在默认代码页不是1256的其他服务器上,则此操作自然会失败。服务器通常在美国地区运行,而选择代码页1252西欧

虽然您通常可以更改代码页,并且UTF-8原则上在Windows中作为代码页65001提供,但它有一系列错误,可能使其无法用于此目的-UTF-8是Windows下的二等公民。(在任何情况下,在web服务器线程内更改区域设置都是不可靠的。)

让完整Unicode文件名在Windows中工作的唯一方法是调用本机Win32 API函数来访问文件(使用UTF-16LE字符串),而不是使用C标准库函数。这就是PowerShell/.NET所做的-因为它是Windows特定的软件,所以可以直接使用Win32函数。Python还支持转到Win32而不是C的Unicode文件名

但是,PHP目前没有这种功能。您可以使用直接调用Win32 API来手动执行此操作,但这确实不方便


这就是为什么尽可能避免使用任意输入作为文件名的原因之一

你到底是如何在Linux和Windows之间移动文件夹的?是的。我在Linux中通过PHP使用了mkdir,现在想转到Windows…是的,但是怎么做?Flashdrive、硬盘或类似的东西?哪个文件系统?()还是通过网络复制?你是压缩文件还是复制文件?Windows磁盘是FAT还是NTFS也很重要:我相信Windows在内部使用UTF-16。第一个解决方案非常好。我在一段时间内使用了该代码来重命名子目录。。。但是,对于文件夹,返回错误:注意:iconv():在输入字符串中检测到非法字符。tnx:)@Ramin:是的,当遇到阿拉伯语代码页1256中不存在的任何字符时,就会发生这种情况。如果您使用目标编码
windows-1256//IGNORE
,则它将自动丢弃这些字符,而不会引发错误,但显然这意味着丢失数据。最后,我使用代码替换并防止丢失一些数据(对于波斯语/波斯语语言):$localfilename=str_ireplace('ی','ي',$localfilename);然后我们可以重命名文件夹:)这是正确的方法吗<代码>ي(U+064A,阿拉伯语Yeh)出现在cp1256中,而
ی
(U+06CC,波斯语Yeh)不存在。还有相当多的其他阿拉伯字符不是1256年的,因此,如果你必须用新数据再次使用,这可能不够……是的,我知道一些波斯语字符,如('1711;'、'1688;'、'1662;')不是阿拉伯语。但是这个方法对我来说非常有效,没有丢失任何数据!