好吧,我真的很纠结这个问题一段时间了。我有数千个字符错误的文件,这些文件被服务器错误地从一个zip文件中提取出来,产生了由服务器以这种方式转换的名称:
原文件名(例如)为
QQ图片20160314173435.jpg
现在呈现在服务器上的文件的形状为
QQ#U56fe#U724720160314173435.jpg
,
图 = #U56fe
和
片= #U7247
所有文件都是相同的2个字符,只是编号不同..
我已经尝试了任何我能想到的函数,包括iconv
族,mb_
族,str_raplace
甚至htmlentities_de/encode
等。等。
每个字符要么不工作,要么会产生其他奇怪的字符。
我现在的代码是:
// iconv_set_encoding('input_encoding','GB18030');
// print_r($enc);
if ($handle = opendir('./')) {
while (false !== ($fileName = readdir($handle))) {
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
echo $ext .PHP_EOL;
if ( $ext == 'jpg' ){
echo "========" . mb_detect_encoding($fileName).PHP_EOL . "'r'n";
$newName = mb_convert_encoding($fileName, "UTF-8",mb_detect_encoding($fileName));
// $newName = str_replace("#","''",$fileName);
// $newName = str_replace("#U56fe",iconv("UTF-8","GB2312","图"),$newName);
// $newName = html_entity_decode($newName,ENT_NOQUOTES,"GB2312");
// $newName = urlencode($newName);
// $newName = urldecode($newName);
//
// Tried //GB2312 // GB18030
// $newName = iconv(mb_detect_encoding($newName, mb_detect_order(), true), "GB18030", $newName);
// echo $newName .PHP_EOL;
// $newName = iconv("UTF-8", "GB18030", $fileName);
// $newName = iconv("GB18030", "UTF-8", $fileName);
// $newName = iconv("ISO-8859-9//TRANSLIT", "UTF-8", $fileName);
// echo $newName .PHP_EOL;
// $newName = mb_convert_encoding($fileName, 'UTF-8', 'HTML-ENTITIES');
// tried both copy and rename+unlink
//rename($fileName, $newName);
copy ($fileName,$newName);
}
}
closedir($handle);
}
我留下了一些失败的尝试只是为了显示已经尝试过的,但实际上我尝试了更多(包括开始的iconv_set_encoding
)。
我已经在本地(win7/xampp)和实时服务器(centos/Cpanel)上尝试了脚本。
经过这么多次失败,我甚至不确定名称是ASCII
, UTF-8
还是UTF-8
中表示的unicode
替代。
并不是说问题不在于创建新文件或文件夹——我可以毫无问题地做到这一点。第三个问题是只使用PHP
重命名现有文件。任何其他重命名方法实际上都是有效的。
奇怪的是,我在另一台本地机器(UBUNTU)上测试了相同的脚本-它工作得很好-当然,这表明某种程度上是OS/PHP设置负责-但如何?
并且-必须有一些方法告诉脚本如何使用copages/编码和动态更改…
在GNU/Linux系统上,使用sh兼容的shell(如bash),您可以像这样获得重命名的预览:
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/''''u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
echo mv "$f" "$h"
fi
done
如果您对建议的重命名感到满意,请实际执行它们,通过删除上面语句中的单词"echo":
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/''''u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
mv "$f" "$h"
fi
done