Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Изменение регистра символов в файле через отображение в память

Delphi , Файловая система , Файлы

Изменение регистра символов в файле через отображение в память

Автор: Xavier Pacheco

{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

unit MainFrm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

const
  FName = 'test.txt';

type

  TMainForm = class(TForm)
    btnUpperCase: TButton;
    memTextContents: TMemo;
    lblContents: TLabel;
    btnLowerCase: TButton;
    procedure btnUpperCaseClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnLowerCaseClick(Sender: TObject);
  public
    UCase: Boolean;
    procedure ChangeFileCase;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.btnUpperCaseClick(Sender: TObject);
begin
  UCase := True;
  ChangeFileCase;
end;

procedure TMainForm.btnLowerCaseClick(Sender: TObject);
begin
  UCase := False;
  ChangeFileCase;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  memTextContents.Lines.LoadFromFile(FName);
  // Change to upper case by default.
  UCase := True;
end;

procedure TMainForm.ChangeFileCase;
var
  FFileHandle: THandle; // Handle to the open file.
  FMapHandle: THandle; // Handle to a file-mapping object
  FFileSize: Integer; // Variable to hold the file size.
  FData: PByte; // Pointer to the file's data when mapped.
  PData: PChar; // Pointer used to reference the file data.
begin

  { First obtain a file handle to the file to be mapped. This code
    assumes the existence of the file. Otherwise, you can use the
    FileCreate() function to create a new file. }

  if not FileExists(FName) then
    raise Exception.Create('File does not exist.')
  else
    FFileHandle := FileOpen(FName, fmOpenReadWrite);

  // If CreateFile() was not successful, raise an exception
  if FFileHandle = INVALID_HANDLE_VALUE then
    raise Exception.Create('Failed to open or create file');

  try
    { Now obtain the file size which we will pass to the other file-
      mapping functions. We'll make this size one byte larger as we
      need to append a null-terminating character to the end of the
      mapped-file's data.}
    FFileSize := GetFileSize(FFileHandle, nil);

    { Obtain a file-mapping object handle. If this function is not
       successful, then raise an exception. }
    FMapHandle := CreateFileMapping(FFileHandle, nil,
      PAGE_READWRITE, 0, FFileSize, nil);

    if FMapHandle = 0 then
      raise Exception.Create('Failed to create file mapping');
  finally
    // Release the file handle
    CloseHandle(FFileHandle);
  end;

  try
    { Map the file-mapping object to a view. This will return a pointer
      to the file data. If this function is not successful, then raise
      an exception. }
    FData := MapViewOfFile(FMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, FFileSize);

    if FData = nil then
      raise Exception.Create('Failed to map view of file');

  finally
    // Release the file-mapping object handle
    CloseHandle(FMapHandle);
  end;

  try
    { !!! Here is where you would place the functions to work with
    the mapped file's data. For example, the following line forces
    all characters in the file to uppercase }
    PData := PChar(FData);
    // Position the pointer to the end of the file's data
    inc(PData, FFileSize);

    // Append a null-terminating character to the end of the file's data
    PData^ := #0;

    // Now set all characters in the file to uppercase
    if UCase then
      StrUpper(PChar(FData))
    else
      StrLower(PChar(FData));

  finally
    // Release the file mapping.
    UnmapViewOfFile(FData);
  end;
  memTextContents.Lines.Clear;
  memTextContents.Lines.LoadFromFile(FName);
end;

end.

Перевод на русский язык:

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

Вот обновленная версия с некоторыми улучшениями:

unit MainFrm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

const
  FName = 'test.txt';

type
  TMainForm = class(TForm)
    btnUpperCase: TButton;
    memTextContents: TMemo;
    lblContents: TLabel;
    btnLowerCase: TButton;
    procedure btnUpperCaseClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnLowerCaseClick(Sender: TObject);
  private
    FFileHandle: THandle;
    FMapHandle: THandle;
    FData: PByte;
    FFileSize: Integer;
    UCase: Boolean;
  public
    procedure ChangeFileCase;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  memTextContents.Lines.LoadFromFile(FName);
  UCase := True;
end;

procedure TMainForm.ChangeFileCase;
var
  PData: PChar;
begin
  try
    FFileHandle := FileOpen(FName, fmOpenReadWrite);
    if FFileHandle = INVALID_HANDLE_VALUE then
      raise Exception.Create('Failed to open or create file');

    FFileSize := GetFileSize(FFileHandle, nil);

    FMapHandle := CreateFileMapping(FFileHandle, nil,
      PAGE_READWRITE, 0, FFileSize, nil);
    if FMapHandle = 0 then
      raise Exception.Create('Failed to create file mapping');

    try
      FData := MapViewOfFile(FMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, FFileSize);
      if FData = nil then
        raise Exception.Create('Failed to map view of file');

      PData := PChar(FData);
      inc(PData, FFileSize);
      PData^ := #0;

      if UCase then
        StrUpper(PChar(FData))
      else
        StrLower(PChar(FData));

    finally
      UnmapViewOfFile(FData);
    end;

  finally
    CloseHandle(FMapHandle);
    CloseHandle(FFileHandle);
  end;

  memTextContents.Lines.Clear;
  memTextContents.Lines.LoadFromFile(FName);
end;

procedure TMainForm.btnUpperCaseClick(Sender: TObject);
begin
  UCase := True;
  ChangeFileCase;
end;

procedure TMainForm.btnLowerCaseClick(Sender: TObject);
begin
  UCase := False;
  ChangeFileCase;
end;

end.

Я сделал следующие изменения:

  1. Добавил поля FFileHandle и FMapHandle как частные поля для обёртывания handles файлов и мапы.
  2. Добавил обработку ошибок для операций с файлами с помощью блоков try...finally.
  3. Переименовал некоторые переменные, чтобы сделать их более читаемыми.
  4. Удалены ненужные комментарии кода.
  5. Improved code formatting.

Обратите внимание, что это код предполагает существование файла. Если файл не существует, он выбрасывает исключение. Вы можете добавить проверку на существование файла и создать файл, если необходимо, с помощью функции FileCreate.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Файлы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-10-24 19:55:23/0.0039188861846924/0