1 / 1 / 0
Регистрация: 21.09.2013
Сообщений: 30
1

Разные кодировки файлов (ASCII, UTF-8, UTF-16)

01.06.2014, 21:42. Показов 9030. Ответов 1
Метки нет (Все метки)

Привет всем!

Нужно написать программу поиска файлов, содержащих заданную строку. Т.е. пользователь выбирает начальный каталог, задаёт строку поиска, после чего программа должна обойти файлы в выбранном каталоге и всех его подкаталогах и выдать имена тех файлов, в которых встречается заданная строка. Файлы могут быть бинарными, строка внутри файла может лежать в ASCII, в UTF-8 или в UTF-16.

Проблема в том, что никогда не работал с юникодом(но сегодня уже прочитал про него очень много).
Есть рабочий код, но он работает только с классической ANSI-кодировкой.
Есть ли в Delphi какие-либо средства для интерпретации UTF-8,UTF-16
Помогите, пожалуйста, переделать код под условие задачи.
Установлена Delphi 7 и Delphi 2010(возможно это важно).

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
uses
  FileCtrl;
 
procedure ProcFolder(const aPath, aTmpl : String; aSl : TStrings);
var
  F : File;
  Sr : TSearchRec;
  Attr, Len : Integer;
  Path, FileName, S : String; //AnsiString;
begin
  //Добавление завершающего слеша в строке пути.
  Path := IncludeTrailingPathDelimiter(aPath);
  aSl.Add('-----');
  aSl.Add('Папка: ' + Path);
  //Значение атрибутов, соответствующее любым файлам, исключая тома.
  Attr := faAnyFile - faVolumeID;
  try
    if FindFirst(Path + '*', Attr, Sr) = 0 then
    repeat
      //Имя очередного файла.
      FileName := Path + Sr.Name;
      //Если файл является папкой.
      if (Sr.Attr and faDirectory) = faDirectory then begin
        //Если папка не является ссылкой на текущую или родительскую папку,
        //то выполняем рекурсивный вызов.
        if (Sr.Name <> '.') and (Sr.Name <> '..') then
          ProcFolder(FileName, aTmpl, aSl);
      //Поиск в файле.
      end else begin
        AssignFile(F, FileName);
        try
          //Открытие файла в режиме чтение/запись с наименьшим блоком в 1 байт.
          Reset(F, 1);
          Len := FileSize(F);
          SetLength(S, Len);
          BlockRead(F, S[1], Len);
          CloseFile(F);
          //Поиск заданной подстроки и запись в список.
          if Pos(aTmpl, S) > 0 then aSl.Add(Sr.Name)
        except
          aSl.Add('Ошибка! Не удалось обработать файл: ' + Sr.Name);
        end;
      end;
    until FindNext(Sr) <> 0;
  finally
    FindClose(Sr);
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Path, STmpl : String; //AnsiString;
begin
  //Подстрока для поиска.
  STmpl := Edit1.Text;
  if STmpl = '' then begin
    ShowMessage('Подстрока для поиска не задана. Действие отменено.');
    Exit;
  end;
  //Путь к папке, в которой нужно произвести поиск.
  Path := ExtractFilePath(ParamStr(0)) + 'Files\';
  //Диалог выбора папки.
  if not SelectDirectory('Выбор папки', '', Path) then Exit;
  //Добавление завершающего слеша в строке пути.
  Path := IncludeTrailingPathDelimiter(Path);
 
  Memo1.Lines.Add('------------------------------');
  Memo1.Lines.Add('Путь: ' + Path);
  Memo1.Lines.Add('Искомая строка: ' + STmpl);
  Memo1.Lines.Add('Результаты поиска:');
  ProcFolder(Path, STmpl, Memo1.Lines)
end;
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2014, 21:42
Ответы с готовыми решениями:

Смена кодировки на UTF-8 (XE8)
На форме имеется компонент едит с редактируемым пользователем тексом. По нажатию кнопки текст из...

Внедрение UTF-8 кодировки в Delphi 7
Суть вопрос такова. Имеется модуль тестирования знаний датского языка с системой создания заданий...

Кодировки OEM, MAC, UTF-8, КОИ8,ISO 8859-5
Здравствуйте. Вот дописываю свою программу и у меня возникла следующая проблема. Надо организовать...

Конвертация из ASCII в UTF-32 или UTF-8 в UTF-32
Собсно сабж.

1
13089 / 5870 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
02.06.2014, 18:33 2
Цитата Сообщение от Sergey_Chizhov Посмотреть сообщение
Файлы могут быть бинарными, строка внутри файла может лежать в ASCII, в UTF-8 или в UTF-16.
...
Есть ли в Delphi какие-либо средства для интерпретации UTF-8,UTF-16
Как выполнять преобразования между кодировками показано, например, здесь:
Загрузка из файлов с преобразованием кодировок: ANSI -> UTF-8/UTF-16LE/UTF-16BE, UTF-8 -> ANSI/UTF-16LE/UTF-16BE, UTF-16(LE/BE) -> ANSI/UTF-8.
Там же, постом ниже, в виде отдельных функций:
Загрузка из файлов с преобразованием UTF-16(LE/BE) -> ANSI и UTF-8 -> ANSI.
Здесь сразу отмечу, что у меня там код правильно написан, но в комментариях про последовательность байт написано неверно. В комментариях:
Delphi
1
2
3
  //Проверка BOM (Byte Order Mark) - метка, показывающая правило
  //расположения байтов. #FE#FF - правило LE, #FF#FE - правило BE.
  //Если BOM нет, то считаем, что используется правило LE.
На самом деле, надо так:
Delphi
1
2
3
4
  //Проверка BOM (Byte Order Mark) - метка, показывающая правило расположения байтов.
  //Правило LE: последовательность байтов: #FF#FE - соответствующий код: $FEFF.
  //Правило BE: последовательность байтов: #FE#FF - соответствующий код: $FFFE.
  //Если BOM нет, то считаем, что используется правило LE.
LE/BE - это обозначения порядка следования байтов в записи UNICODE символов. LE (Little-Endian) - это когда младший байт расположен слева от старшего - т. е., младший байт расположен в младших адресах, старший байт - в старших адресах. BE (Big-Endian) - когда старший байт расположен справа от младшего.

Что касается поставленной задачи - здесь понадобится определить вид кодировки в файле. Затем, преобразовать искомый текст в ту кодировку, которая используется в файле. И далее, в файле, выполнить поиск этого перекодированного текста.
Есть ряд случаев, когда не так просто сделать точный вывод о кодировке текста. Например, файлы с кодировкой UTF-8 могут не содержать метки BOM (Byte Order Mark). В этом случае о кодировке придётся догадываться по содержимому. Символы в UTF-8 имеют переменную длину - от 1 до 3 байт. В случае однобайтных символов UTF-8 представление полностью совпадает с ASCII кодировкой. И тогда UTF-8 можно спутать с ANSI кодировкой, т. к., первая половина таблицы ANSI совпадает с ASCII. Также этот файл может оказаться в кодировке UTF-16BE. Т. к., по правилам, выработанным UNICODE консорциумом, файл в кодировке UTF-16BE может не содержать BOM. Но файл с кодировкой UTF-16BE - это редкость, конечно. Да и в кодировке UTF-16LE иногда записывают без BOM - хотя это прямое нарушение соглашений UNICODE.
Что касается последовательности записи байтов LE/BE - в архитектуре IBM PC и в ОС Windows/DOS принято правило LE.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.06.2014, 18:33
Помогаю со студенческими работами здесь

Изменение кодировки файла с ASCII на UTF-8
Не работает этот код function change_files_coding_to_UTF8($file_name) { $str =...

getBytes('UTF-16') даёт UTF-16LE или UTF-16BE?
Добрый день! Делаю J2ME-клиента к некому серверу, исходников которого у меня нет, но есть...

<globalization fileEncoding='utf-8' requestEncoding='utf-8' responseEncoding='utf-8' />
Если в коде пишу строку скажем Response.Write ('Вася дурак') - все срабатывает нормально, а если в...

Кодировки UTF-8 и UTF-16
Здравствуйте! Есть один вопрос! Например я создал файл test.php в кодировке UTF-8. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru