2016-08-31 3 views
0

Хорошо, я действительно борется с этим на некоторое время. У меня есть тысячи файлов с неправильными символами, которые были ошибочно извлекаемых сервером из архива, производя имена преобразуются сервером таким образом:Переименование файлов с символами Unicode/Non UTF

Оригинальное название файла (пример) является

QQ图片20160314173435.jpg 

файлы теперь представлены на сервере принял форму

QQ#U56fe#U724720160314173435.jpg 

где

图 = #U56fe 

и

片= #U7247 

Все файлы имеют те же 2 символов с diffeerent нумерации только ..

Я пробовал какую-либо функцию, я могу думать, в том числе 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 или некоторые unicode замещения представлены в UTF-8.

Не то, чтобы проблема заключалась не в создании новых файлов или папок, - что я могу обойтись без проблем. Проблема заключается в переименовании существующих файлов только с PHP. На самом деле работает любой другой метод переименования.

Странно то, что я протестировал один и тот же сценарий на другом локальном компьютере (UBUNTU), который хорошо работал - конечно, это указывает на то, что некоторые параметры ОС/PHP несут ответственность, но как?

А также - там должен быть какой-то способ, чтобы сказать сценарий, как использовать Кодовые/кодирование и динамически изменять что ..

+0

Возможного дубликат [Как использовать функции файловой системы в PHP, используя строки UTF-8?] (Http: // stackoverflow.com/questions/1525830/how-do-i-use-filesystem-functions-in-php-use-utf-8-строки) – roeland

+0

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

+0

@roland. Хехе .. Я тону, и ты описываешь воды :-) .. просто шучу. :-). Проблема понятна, но решение? Php имеет некоторые функции, которые должны изменить кодировку. и они работают (но не так, как ожидалось), производя разные символы). Еще больше - живой сервер - это сервер в Гонконге (CentOs), который полностью поддерживает китайский язык из моего опыта работы с другими сценариями. –

ответ

-1

В системе GNU/Linux, с помощью ш-совместимой оболочки (например, Баш), вы можете получить предварительное переименование, как это:

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 

Если вы удовлетворены предлагаемые переименования, на самом деле их, удалив слово «эхо» в приведенном выше высказывании:

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 
Смежные вопросы