Прочитать текстовый файл с нулевым байтом

У меня есть текстовый файл с элементами dos - например, hex (00). Мне нужно это прочитать и преобразовать. Я пробовал использовать utf8toansi, но это удаляет всю строку с шестнадцатеричным (00). Есть ли способ преобразовать в текст весь файл? Я использую win32, RadStudio2007, Delphi.

Краткое содержание вопроса и текст вводят в заблуждение. Все, что хочет сделать OP, - это удалить / заменить некоторые символы из файла и снова записать его. Нет необходимости делать это с Delphi, используйте вместо этого стандартные инструменты командной строки.

mghie 23.12.2008 12:00

Большое спасибо за ответ :) Я попробовал последнее решение (ConvertFileToDos), и, похоже, оно у меня хорошо работает :)

user15138 23.12.2008 11:45

Извините, но я никогда бы не догадался из вопроса, что вы хотите преобразовать текстовый файл в другой формат. Зачем вообще использовать Delphi в таком случае? Как насчет стандартных инструментов, таких как tr, sed, awk?

mghie 23.12.2008 11:57

Он упоминает, что использует win32, поэтому упомянутые инструменты, вероятно, недоступны. Кроме того, я не могу придумать ничего, что могут сделать эти инструменты, чего не может Delphi.

Wouter van Nifterick 25.12.2008 05:52

Доступны инструменты с использованием MSys, Cygwin или GnuWin32. И даже если Delphi может создавать аналогичные инструменты - вы также сами собираете свой молоток и плоскогубцы? Как звучит такая поговорка: «Те, кто не понимает Unix, обречены изобретать его заново, но плохо». (Генри Спенсер)

mghie 28.12.2008 00:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
2 385
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете прочитать его в TMemoryStream, назначить PChar первому адресу и выполнить сканирование с циклом от 0 до Size - 1. Это, конечно, зависит от вас, что вы хотите делать со встроенными символами # 0. Просто проигнорируйте №13 и добавьте строку на каждый №10, с которым вы столкнетесь.

Обновлено:

Что-то вроде:

procedure TForm1.Button1Click(Sender: TObject);
var
  FileStream: TStream;
  MemStream: TMemoryStream;
  P: PChar;
  s: string;
  i: integer;
begin
  FileStream := TFileStream.Create('file.txt', fmOpenRead);
  try
    MemStream := TMemoryStream.Create;
    try
      MemStream.LoadFromStream(FileStream);
      P := PChar(MemStream.Memory);
      s := '';
      for i := 0 to MemStream.Size - 1 do begin
        case P[0] of
          #0: {};
          #10: begin
                 // do something with s
                 s := '';
               end;
          #13: {};
        else
          s := s + P[0];
        end;
        Inc(P);
      end;
    finally
      MemStream.Free;
    end;
  finally
    FileStream.Free;
  end;
end;

TMemoryStream имеет метод LoadFromFile, устраняющий промежуточный TFileStream. Также обратите внимание, что создание строки по одному символу за раз - плохая идея. Сохраните начальную позицию и длину, а затем используйте SetString.

Rob Kennedy 22.12.2008 20:15

Я собрал это в Delphi 4, где нет TFileStream.LoadFromFile (), но это, конечно, очень хорошая идея для более поздних версий Delphi. К вопросу 2) - это очень хороший комментарий, и я бы никогда не сделал этого в производственном коде, я бы использовал два PChars. Но я не хотел усложнять пример ...

mghie 22.12.2008 21:15

Я не знаю Delphi, но предполагаю, что вам, вероятно, нужно открыть файл как двоичный файл, а не как текстовый файл. Затем вы можете напрямую читать байты и преобразовывать их во все, что захотите.

Ответ принят как подходящий

Это должно сработать ...

procedure ConvertFileToDos(const aInFile,aOutFile:String);
var
  FileIn,FileOut:TextFile;
  C:AnsiChar;
  LineBreak:String;
begin
  LineBreak := #13#10;

  AssignFile(FileIn,aInFile);
  Reset(FileIn);

  AssignFile(FileOut,aOutFile);
  ReWrite(FileOut);

  while not EOF(FileIn) do
  begin
    Read(FileIn,C);
    if C=#0 then
      Write(FileOut,LineBreak)
    else
      Write(FileOut,C)
  end;

  CloseFile(FileIn);
  CloseFile(FileOut);
end;

Другие вопросы по теме