Получение «ÿþI» в качестве выходных данных при чтении из файла .log с использованием delphi - PullRequest
5 голосов
/ 06 октября 2011

Я пытаюсь прочитать данные из файла .log и обработать его содержимое.Файл журнала создается другим приложением.Когда я использую команду readln в Delphi и отображаю содержимое файла в заметке, я получаю только одну строку данных (ÿþI) из файла с более чем 6000 строками данных.

    procedure TForm1.Button1Click(Sender: TObject);
    Var
        F : TextFile;
        s : string;
    begin
        AssignFile(F, 'data.log');
        Reset(F);

        while not Eof(F) do
        begin
            Readln(F, s);
            Memo1.Lines.Add(s);
        end;
    end;

Кто-нибудь знает, в чем может быть проблема?

Ответы [ 3 ]

4 голосов
/ 06 октября 2011

Вы имеете дело с файлом UTF-16 (о чем свидетельствуют первые два символа), и Delphi 2007 к этому не подготовлен, поэтому он прекращает чтение с первого байта $ 0, поскольку Readln считает, что строка заканчиваетсятам.

Вам нужно будет использовать другой метод чтения файла, и вам придется читать в WideString (и, вероятно, преобразовать это в строку).Поскольку Delphi 2007 не поддерживает Unicode должным образом, я думаю, вам также придется самостоятельно разбивать строки, но у меня нет такой возможности, поэтому я не совсем уверен.

3 голосов
/ 07 октября 2011

Как сказал Майкл, вы имеете дело с файлом в кодировке UTF-16, поэтому вам придется загружать и декодировать его вручную.Существуют различные WideString -поддерживаемые TStringList -подобные классы, плавающие в сети, или Borland имеет собственную реализацию в модуле WideStrings, попробуйте использовать один из них вместо ввода-вывода из файла Pascal, например:

procedure TForm1.Button1Click(Sender: TObject);
var
  SL : TWideStringList;
  I: Integer;
  s : string;
begin
  SL := TWideStringList.Create;
  try
    SL.LoadFromFile('data.log');
    Memo1.Lines.BeginUpdate;
    try
      for I := 0 to SL.Count-1 do
        Memo1.Lines.Add(SL[I]);
    finally
      Memo1.Lines.EndUpdate;
    end;
  finally
    SL.Free;
  end;
end; 

Или:

uses
  .., WideStrings;

procedure TForm1.Button1Click(Sender: TObject);
var
  SL : TWideStringList;
begin
  SL := TWideStringList.Create;
  try
    SL.LoadFromFile('data.log');
    Memo1.Lines.Assign(SL);
  finally
    SL.Free;
  end;
end; 

В качестве альтернативы, установите копию TNTWare или TMS, которые оба имеют компоненты с поддержкой Unicode.Тогда вы сможете просто LoadFromFile() .log файл напрямую в любой компонент Unicode Memo, который вы выбрали.

0 голосов
/ 07 октября 2011

Как упоминалось в моем комментарии к ответу Реми, в WideStrings объявлен TWideStrings / TWideStringList:

uses WidesStrings;
//...
var
  Ws: TWideStrings;
  s: string;
  i: Integer;
begin
  Ws := TWideStringList.Create;
  try
    ws.LoadFromFile('C:\temp\UniTest.txt');
    for i := 0 to ws.Count - 1 do
    begin
      s := ws[i];
      Memo1.Lines.Add(s);
    end;
  finally
    ws.Free;
  end;
end;

Обратите внимание, что это не TStrings потомок, поэтому его нельзя напрямую назначить свойствам TStrings, таким как TMemo.Lines, вы должны добавить их одно за другим.

Похоже, он не обрабатывает спецификацию (вашу ÿþ) или кодировку с прямым порядком байтов

...