Лингвоспецифические символы в именах файлов

niktuba
4/13/2007, 12:03:58 AM
Работаю с файлами, поступающими из многих национальных версий Windows XP. Многие программы отказываются с ними работать. Скажем, работают с файлом
Без имени.doc
только тогда, когда language for non-unicode programs установлен в Russian.
Но тогда становятся недоступны файлы с именами типа
Cópia de segurança de bd.doc
Нет ли какой утилиты, которая бы просматривала каталог и все его подкаталоги и исправляла идиотские буквы на английские?
Скажем, так, что файл
яйца.doc становился бы yaitsa.doc, а
en français.xls --- en francais.xls
DELETED
4/14/2007, 5:39:01 PM
(niktuba @ 12.04.2007 - время: 20:03) Работаю с файлами, поступающими из многих национальных версий Windows XP. Многие программы отказываются с ними работать. Скажем, работают с файлом

Не понял. Недоступны в проводнике? В диалоге "открыть"? Или как? У меня стоит по-умолчанию US и спокойно создаются, открываются и т.д. и китайские, и русские, и французские...
niktuba
4/14/2007, 9:00:18 PM
(JeyLo @ 14.04.2007 - время: 13:39) (niktuba @ 12.04.2007 - время: 20:03) Работаю с файлами, поступающими из многих национальных версий Windows XP. Многие программы отказываются с ними работать. Скажем, работают с файлом

Не понял. Недоступны в проводнике? В диалоге "открыть"? Или как? У меня стоит по-умолчанию US и спокойно создаются, открываются и т.д. и китайские, и русские, и французские...
Не, в проводнике и у меня все хорошо - вне зависимости от того, что там у меня стоит в Regional Options. Не работают именно программы, причем такие, от которых я не могу отказаться, типа переводчиков, Beyond Compare 2 и клиентская часть программного пакета, с промощью которого я могу подавать заявки на специфические конкурсы научных проектов в Португалии и Бразилии. А как вычистишь весь диск от файлов с нац. символами в имени - работает все на ура.
DELETED
4/15/2007, 2:30:47 AM
(niktuba @ 14.04.2007 - время: 17:00) А как вычистишь весь диск от файлов с нац. символами в имени - работает все на ура.
Понятно. Старые программы, не поддерживающие юникод и работающие с файловой системой через ... неважно, через чего.

Есть ренеймеры, которые поддерживают юникод и регулярные выражения. С Вашего позволения я это предоставлю несколько поздней. :)

Не понятна только цитируемая фраза. Очень не понятна. Неужели программы не работают, если где-то есть international characters?
niktuba
4/15/2007, 3:18:54 AM
(JeyLo @ 14.04.2007 - время: 22:30) (niktuba @ 14.04.2007 - время: 17:00) А как вычистишь весь диск от файлов с нац. символами в имени - работает все на ура.
Не понятна только цитируемая фраза. Очень не понятна. Неужели программы не работают, если где-то есть international characters?
Виновен, выразился не очень ясно. Если где-то есть - это про Beyond Compare 2, когда программа сравнивает содержимое двух дисков с данными. Конечно, просто наличие файлов с нац. символами, пока их не трогаешь, ни к каким плохим последствиям не приводит. Плохо то, что какие-то идиоты написали программы для работы с португальскими документами, предупреждая, что всякие сетевые операции хорошо проходят только с файлами, у которых "англобуквенные" имена. И те же проги дают по умолчанию имена файлов на основании первых слов содержимого, вызывая к жизни досументы типа fundação.dat.


(JeyLo @ 14.04.2007 - время: 22:30)
Есть ренеймеры, которые поддерживают юникод и регулярные выражения. С Вашего позволения я это предоставлю несколько поздней. :)
Спасибо!
DELETED
4/25/2007, 1:44:56 AM
Нету таких ренеймеров. Теперь есть. В аттачменте исполняемый консольный файл. Запускается из директории, в которой есть файлы для переименования. Уходит рекурсивно по всем поддиректориям. Вопросов по переименованию не задает. Тупо переименовывает.

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

NT/XP/W3.

Для любопытных фастфуд-исходник:
CODE #define _WIN32_WINNT 0x0501

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <shlwapi.h>

#pragma comment (lib , "shlwapi.lib")

#undef MAX_PATH
#define MAX_PATH 32767

typedef struct _REPLACEMENT_TABLE {
DWORD dwOriginal;
LPWSTR lpwstrReplace;
} REPLACEMENT_TABLE, *PREPLACEMENT_TABLE;

REPLACEMENT_TABLE g_CharReplacementTable[] = {
{ 0x0410, _T("A") },
{ 0x0411, _T("B") },
{ 0x0412, _T("V") },
{ 0x0413, _T("G") },
{ 0x0414, _T("D") },
{ 0x0415, _T("E") },
{ 0x0416, _T("ZH") },
{ 0x0417, _T("Z") },
{ 0x0418, _T("I") },
{ 0x0419, _T("I") },
{ 0x041A, _T("K") },
{ 0x041B, _T("L") },
{ 0x041C, _T("M") },
{ 0x041D, _T("N") },
{ 0x041E, _T("O") },
{ 0x041F, _T("P") },
{ 0x0420, _T("R") },
{ 0x0421, _T("S") },
{ 0x0422, _T("T") },
{ 0x0423, _T("U") },
{ 0x0424, _T("F") },
{ 0x0425, _T("KH") },
{ 0x0426, _T("TS") },
{ 0x0427, _T("CH") },
{ 0x0428, _T("SH") },
{ 0x0429, _T("SHCH") },
{ 0x042A, _T("'") },
{ 0x042B, _T("Y") },
{ 0x042C, _T("'") },
{ 0x042D, _T("E") },
{ 0x042E, _T("YU") },
{ 0x042F, _T("YA") },
{ 0x0430, _T("a") },
{ 0x0431, _T("b") },
{ 0x0432, _T("v") },
{ 0x0433, _T("g") },
{ 0x0434, _T("d") },
{ 0x0435, _T("ye") },
{ 0x0436, _T("zh") },
{ 0x0437, _T("z") },
{ 0x0438, _T("i") },
{ 0x0439, _T("i") },
{ 0x043A, _T("k") },
{ 0x043B, _T("l") },
{ 0x043C, _T("m") },
{ 0x043D, _T("n") },
{ 0x043E, _T("o") },
{ 0x043F, _T("p") },
{ 0x0440, _T("r") },
{ 0x0441, _T("s") },
{ 0x0442, _T("t") },
{ 0x0443, _T("u") },
{ 0x0444, _T("f") },
{ 0x0445, _T("kh") },
{ 0x0446, _T("ts") },
{ 0x0447, _T("ch") },
{ 0x0448, _T("sh") },
{ 0x0449, _T("shch") },
{ 0x044A, _T("'") },
{ 0x044B, _T("y") },
{ 0x044C, _T("'") },
{ 0x044D, _T("e") },
{ 0x044E, _T("yu") },
{ 0x044F, _T("ya") },
{ 0x0451, _T("e") },
{ 0x0000, 0x0000 },
};


LPWSTR GetTransliteratedCharacter (WCHAR wchValue ) {
PREPLACEMENT_TABLE pTable = (PREPLACEMENT_TABLE)&g_CharReplacementTable;
while ( pTable[0].dwOriginal != 0 ) {
 if ( pTable[0].dwOriginal == DWORD (wchValue) ) {
  return pTable[0].lpwstrReplace;
 };
 pTable++;
};
return 0;
}

void ReplaceInternationalCharacters (LPWSTR lpwszDirName, LPWSTR lpwszFileName) {
WCHAR wszTemp[MAX_PATH + 1];
StrCpyW (wszTemp, _T("") );
LPWSTR lpwszPtr = lpwszFileName;
do {
 if ( ((DWORD)lpwszPtr[0]) & 0xFF00 ) {
  LPWSTR szT = GetTransliteratedCharacter(lpwszPtr[0]);
  if ( szT ) {
   StrCatW(wszTemp, szT );
  } else {
   StrNCatW(wszTemp, lpwszPtr, sizeof (WCHAR));
  }
 } else {
  StrNCatW(wszTemp, lpwszPtr, sizeof (WCHAR));
 }
 lpwszPtr = CharNextW (lpwszPtr );
} while ( lpwszPtr[0] );

WCHAR wszCurFile[MAX_PATH + 1];
WCHAR wszNewFile[MAX_PATH + 1];

wsprintf ( wszCurFile, _T("%s\\%s"), lpwszDirName, lpwszFileName );
wsprintf ( wszNewFile, _T("%s\\%s"), lpwszDirName, wszTemp );

DWORD dwErrorCode = ERROR_ALREADY_EXISTS;

while ( dwErrorCode == ERROR_ALREADY_EXISTS ) {
 MoveFileW ( wszCurFile, wszNewFile );
 dwErrorCode = GetLastError();

 if ( dwErrorCode == ERROR_ALREADY_EXISTS ) {
  wsprintf ( wszNewFile, _T("%s\\[%u] %s"), lpwszDirName, rand(), wszTemp );
 }
};

wprintf ( _T("\t%s\n"), wszNewFile );
}

void BrowseDir ( LPWSTR lpwszDirName, LPWSTR lpwszSubDirName = 0 ) {
WIN32_FIND_DATAW FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
WCHAR wszCurrentDir[MAX_PATH + 1];

StrCpyW ( wszCurrentDir, lpwszDirName );
StrCatW ( wszCurrentDir, _T("\\") );
if ( lpwszSubDirName ) {
 StrCatW ( wszCurrentDir, lpwszSubDirName );
 StrCatW ( wszCurrentDir, _T("\\") );
};
StrCatW ( wszCurrentDir, _T("*") );

hFind = FindFirstFileW((LPWSTR)&wszCurrentDir, &FindFileData);

if (hFind != INVALID_HANDLE_VALUE) {
 StrCpyW ( wszCurrentDir, lpwszDirName );
 if ( lpwszSubDirName ) {
  StrCatW ( wszCurrentDir, _T("\\") );
  StrCatW ( wszCurrentDir, lpwszSubDirName );
 };
 while (FindNextFileW(hFind, &FindFileData) != 0) {
  if ( !(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
   LPWSTR lpwszPtr = FindFileData.cFileName;
   do {
    if ( ((DWORD)lpwszPtr[0]) & 0xFF00 ) {
     ReplaceInternationalCharacters(wszCurrentDir, FindFileData.cFileName);
     break;
    };
    lpwszPtr = CharNextW (lpwszPtr );
   } while ( lpwszPtr[0] );
  } else {
   if ( FindFileData.cFileName[0] != _T('.') ) {
    BrowseDir ( wszCurrentDir, FindFileData.cFileName );
   };
  }
 };
} else {
 wprintf (_T("Unable to retrieve directory content.\n\t%s\n\tError is %u.\n"), wszCurrentDir + 4, GetLastError());
};

return;
}

int wmain (int argc, WCHAR* argv[]) {
wprintf (_T("IntRen: Tiny international character killer.\ncopyright 2007 JeyLo & SexNarod\nUsage: IntRen <dir_name> (optional)\n\n") );
WCHAR lpwszRootDir[MAX_PATH+1]; // Root Dir

if ( argc == 2 && argv[1] ) {
 wsprintf ( lpwszRootDir, _T("\\\\?\\%s"), argv[1] );
} else if ( !GetCurrentDirectoryW ( MAX_PATH, (LPWSTR)&lpwszRootDir ) ) {
 wprintf (_T("Unable to detect current Dir. Error code is %u.\n"), GetLastError() );
 return 0;
};

wprintf (_T("Working root is:\n\t%s.\n\n"), lpwszRootDir );

BrowseDir ( lpwszRootDir );

return 0;
}

barrakuda
4/25/2007, 7:15:38 AM
Есть такая известная программа - Total Commander и к нему есть плагин Translit_wdx 1.6
Скачать плагин можно здесь: https://wincmd.ru/plugring/Translit.html
С помощью него можно выполнять групповое переименование с русского в транслит(типа Моя фотка в Moya fotka) и обратно, также можно менять кодировку имён файлов с utf-8 на win1251 например.
Тот, кто знает как легко в Тотале переименовывать файлы оценит этот плагин.
Всё что нужно - скачать Тотал, а на мой взгляд его должен всякий иметь на компе, кому приходиться массово работать с файлами.
Плагины устанавливаются автоматически, так что настраивать ничего не придётся.
Попробуйте.
DELETED
4/25/2007, 3:38:18 PM
(barrakuda @ 25.04.2007 - время: 03:15) С помощью него можно выполнять групповое переименование с русского в транслит(типа Моя фотка в Moya fotka) и обратно, также можно менять кодировку имён файлов с utf-8 на win1251 например.
Однако он не переименовывает португальские, французские и т.д. Кроме того не поддерживаются длинные пути.
niktuba
4/27/2007, 4:13:01 AM
(JeyLo @ 24.04.2007 - время: 21:44) Нету таких ренеймеров. Теперь есть. В аттачменте исполняемый консольный файл. Запускается из директории, в которой есть файлы для переименования. Уходит рекурсивно по всем поддиректориям. Вопросов по переименованию не задает. Тупо переименовывает.

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

Dear JeyLo,

Огромное спасибо. Извините, что не сразу ответил. Как только будет время - опишу специфические символы, их там не пара, а гораздо больше.

Niktuba
niktuba
4/28/2007, 3:49:02 AM
(JeyLo @ 24.04.2007 - время: 21:44)Сейчас переименовывает _только_ файлы русского языка. Подкиньте мне пару специфических символов для определения таблицы, вставлю.


Собственно, все, что встречается в европейских языках, представлено в этой таблице
CODE
0x00C1  [Á]  Aacute LATIN CAPITAL LETTER A WITH ACUTE, Á
0x00E1  [á]  aacute LATIN SMALL LETTER A WITH ACUTE, á
0x00C2  [Â]  Acirc LATIN CAPITAL LETTER A WITH CIRCUMFLEX, Â
0x00E2  [â]  acirc LATIN SMALL LETTER A WITH CIRCUMFLEX, â
0x00C6  [Æ]  AElig LATIN CAPITAL LETTER AE, Æ
0x00E6  [æ]  aelig LATIN SMALL LETTER AE, æ
0x00C0  [À]  Agrave LATIN CAPITAL LETTER A WITH GRAVE, À
0x00E0  [à]  agrave LATIN SMALL LETTER A WITH GRAVE, à
0x00C5  [Å]  Aring LATIN CAPITAL LETTER A WITH RING ABOVE, Å
0x00E5  [å]  aring LATIN SMALL LETTER A WITH RING ABOVE, å
0x00C3  [Ã]  Atilde LATIN CAPITAL LETTER A WITH TILDE, Ã
0x00E3  [ã]  atilde LATIN SMALL LETTER A WITH TILDE, ã
0x00C4  [Ä]  Auml LATIN CAPITAL LETTER A WITH DIAERESIS, Ä
0x00E4  [ä]  auml LATIN SMALL LETTER A WITH DIAERESIS, ä
0x00C7  [Ç]  Ccedil LATIN CAPITAL LETTER C WITH CEDILLA, Ç
0x00E7  [ç]  ccedil LATIN SMALL LETTER C WITH CEDILLA, ç
0x00C9  [É]  Eacute LATIN CAPITAL LETTER E WITH ACUTE, É
0x00E9  [é]  eacute LATIN SMALL LETTER E WITH ACUTE, é
0x00CA  [Ê]  Ecirc LATIN CAPITAL LETTER E WITH CIRCUMFLEX, Ê
0x00EA  [ê]  ecirc LATIN SMALL LETTER E WITH CIRCUMFLEX, ê
0x00C8  [È]  Egrave LATIN CAPITAL LETTER E WITH GRAVE, È
0x00E8  [è]  egrave LATIN SMALL LETTER E WITH GRAVE, è
0x00D0  [Ð]  ETH LATIN CAPITAL LETTER ETH, Ð
0x00F0  [ð]  eth LATIN SMALL LETTER ETH, ð
0x00CB  [Ë]  Euml LATIN CAPITAL LETTER E WITH DIAERESIS, Ë
0x00EB  [ë]  euml LATIN SMALL LETTER E WITH DIAERESIS, ë
0x00CD  [Í]  Iacute LATIN CAPITAL LETTER I WITH ACUTE, Í
0x00ED  [í]  iacute LATIN SMALL LETTER I WITH ACUTE, í
0x00CE  [Î]  Icirc LATIN CAPITAL LETTER I WITH CIRCUMFLEX, Î
0x00EE  [î]  icirc LATIN SMALL LETTER I WITH CIRCUMFLEX, î
0x00CC  [Ì]  Igrave LATIN CAPITAL LETTER I WITH GRAVE, Ì
0x00EC  [ì]  igrave LATIN SMALL LETTER I WITH GRAVE, ì
0x00CF  [Ï]  Iuml LATIN CAPITAL LETTER I WITH DIAERESIS, Ï
0x00EF  [ï]  iuml LATIN SMALL LETTER I WITH DIAERESIS, ï
0x00D1  [Ñ]  Ntilde LATIN CAPITAL LETTER N WITH TILDE, Ñ
0x00F1  [ñ]  ntilde LATIN SMALL LETTER N WITH TILDE, ñ
0x00D3  [Ó]  Oacute LATIN CAPITAL LETTER O WITH ACUTE, Ó
0x00F3  [ó]  oacute LATIN SMALL LETTER O WITH ACUTE, ó
0x00D4  [Ô]  Ocirc LATIN CAPITAL LETTER O WITH CIRCUMFLEX, Ô
0x00F4  [ô]  ocirc LATIN SMALL LETTER O WITH CIRCUMFLEX, ô
0x00D2  [Ò]  Ograve LATIN CAPITAL LETTER O WITH GRAVE, Ò
0x00F2  [ò]  ograve LATIN SMALL LETTER O WITH GRAVE, ò
0x00D8  [Ø]  Oslash LATIN CAPITAL LETTER O WITH STROKE, Ø
0x00F8  [ø]  oslash LATIN SMALL LETTER O WITH STROKE, ø
0x00D5  [Õ]  Otilde LATIN CAPITAL LETTER O WITH TILDE, Õ
0x00F5  [õ]  otilde LATIN SMALL LETTER O WITH TILDE, õ
0x00D6  [Ö]  Ouml LATIN CAPITAL LETTER O WITH DIAERESIS, Ö
0x00F6  [ö]  ouml LATIN SMALL LETTER O WITH DIAERESIS, ö
0x00DF  [ß]  szlig LATIN SMALL LETTER SHARP S, ß
0x00DE  [Þ]  THORN LATIN CAPITAL LETTER THORN, Þ
0x00FE  [þ]  thorn LATIN SMALL LETTER THORN, þ
0x00DA  [Ú]  Uacute LATIN CAPITAL LETTER U WITH ACUTE, Ú
0x00FA  [ú]  uacute LATIN SMALL LETTER U WITH ACUTE, ú
0x00DB  [Û]  Ucirc LATIN CAPITAL LETTER U WITH CIRCUMFLEX, Û
0x00FB  [û]  ucirc LATIN SMALL LETTER U WITH CIRCUMFLEX, û
0x00D9  [Ù]  Ugrave LATIN CAPITAL LETTER U WITH GRAVE, Ù
0x00F9  [ù]  ugrave LATIN SMALL LETTER U WITH GRAVE, ù
0x00DC  [Ü]  Uuml LATIN CAPITAL LETTER U WITH DIAERESIS, Ü
0x00FC  [ü]  uuml LATIN SMALL LETTER U WITH DIAERESIS, ü
0x00DD  [Ý]  Yacute LATIN CAPITAL LETTER Y WITH ACUTE, Ý
0x00FD  [ý]  yacute LATIN SMALL LETTER Y WITH ACUTE, ý
0x00FF  [ÿ]  yuml LATIN SMALL LETTER Y WITH DIAERESIS, ÿ

Как я понял из контекста, для апгрейда достаточно вставить в
REPLACEMENT_TABLE g_CharReplacementTable
следующий код:
CODE
{ 0x00C1, _T("A") },
{ 0x00E1, _T("a") },
{ 0x00C2, _T("A") },
{ 0x00E2, _T("a") },
{ 0x00C6, _T("AE") },
{ 0x00E6, _T("ae") },
{ 0x00C0, _T("A") },
{ 0x00E0, _T("a") },
{ 0x00C5, _T("A") },
{ 0x00E5, _T("a") },
{ 0x00C3, _T("A") },
{ 0x00E3, _T("a") },
{ 0x00C4, _T("A") },
{ 0x00E4, _T("a") },
{ 0x00C7, _T("C") },
{ 0x00E7, _T("c") },
{ 0x00C9, _T("E") },
{ 0x00E9, _T("e") },
{ 0x00CA, _T("E") },
{ 0x00EA, _T("e") },
{ 0x00C8, _T("E") },
{ 0x00E8, _T("e") },
{ 0x00D0, _T("D") },
{ 0x00F0, _T("d") },
{ 0x00CB, _T("E") },
{ 0x00EB, _T("e") },
{ 0x00CD, _T("I") },
{ 0x00ED, _T("i") },
{ 0x00CE, _T("I") },
{ 0x00EE, _T("i") },
{ 0x00CC, _T("I") },
{ 0x00EC, _T("i") },
{ 0x00CF, _T("I") },
{ 0x00EF, _T("i") },
{ 0x00D1, _T("N") },
{ 0x00F1, _T("n") },
{ 0x00D3, _T("O") },
{ 0x00F3, _T("o") },
{ 0x00D4, _T("O") },
{ 0x00F4, _T("o") },
{ 0x00D2, _T("O") },
{ 0x00F2, _T("o") },
{ 0x00D8, _T("O") },
{ 0x00F8, _T("o") },
{ 0x00D5, _T("O") },
{ 0x00F5, _T("o") },
{ 0x00D6, _T("O") },
{ 0x00F6, _T("o") },
{ 0x00DF, _T("ss") },
{ 0x00DE, _T("P") },
{ 0x00FE, _T("p") },
{ 0x00DA, _T("U") },
{ 0x00FA, _T("u") },
{ 0x00DB, _T("U") },
{ 0x00FB, _T("u") },
{ 0x00D9, _T("U") },
{ 0x00F9, _T("u") },
{ 0x00DC, _T("U") },
{ 0x00FC, _T("u") },
{ 0x00DD, _T("Y") },
{ 0x00FD, _T("y") },
{ 0x00FF, _T("y") },

Am I right?
Еще раз спасибо!