Einzelnen Beitrag anzeigen

bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#1

DELPHI & TInifiles ASCII und UTF16

  Alt 4. Jul 2024, 11:46
Delphi und TIni file kann ja nur ASCII und UTF 16 ohne BOM ( https://www.delphipraxis.net/208415-...-vs-ascii.html ) . Wir nutzen noch oft *.ini files. Wenn unsere Kunden mit anderen Editoren die *.ini file bearbeiten kommt es vor , daß das encoding verändert wird.
Aktuell habe ich diese 2 Funktionen angedacht :

checken or im Richtigen format, falls nein die DAtei im richtigen encosing neu schreiben.
Gibt es hierfür bessere Lösungsansätze ?



Delphi-Quellcode:

Detection ASCII UTF-16:

function IsAsciiOrUtf16WithoutBOM(const FileName: string): Boolean;
var
  FileStream: TFileStream;
  Buffer: TBytes;
  i: Integer;
  NumRead: Integer;
begin
  Result := True; // Assume the file is ASCII or UTF-16 without BOM

  FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
  try
    SetLength(Buffer, FileStream.Size);
    NumRead := FileStream.Read(Buffer[0], FileStream.Size);

    // Check the first few bytes for BOMs
    if NumRead >= 2 then
    begin
      if (Buffer[0] = $FF) and (Buffer[1] = $FE) then
        Exit(False); // UTF-16 Little Endian BOM
      if (Buffer[0] = $FE) and (Buffer[1] = $FF) then
        Exit(False); // UTF-16 Big Endian BOM
    end;

    // Check for non-ASCII characters, which could disqualify the file as ASCII
    for i := 0 to High(Buffer) do
    begin
      if Buffer[i] > 127 then
      begin
        Exit(False); // Non-ASCII character found
      end;
    end;
  finally
    FileStream.Free;
  end;
end;

Conversion to UTF-16:

function Convert2UTF16(const FileName: string): Boolean;
var
  FileContent: TBytes;
  Encoding: TEncoding;
begin
  Result := False; // Default to False

  try
    // Read the file content into a byte array
    FileContent := TFile.ReadAllBytes(FileName);

    // Check if the file begins with the UTF-16 Byte-Order Mark (BOM)
    if (Length(FileContent) >= 2) then
    begin
      if (FileContent[0] = $FF) and (FileContent[1] = $FE) or
         (FileContent[0] = $FE) and (FileContent[1] = $FF) then
      begin
        Result := True; // It's UTF-16
        Exit; // No need to convert
      end;
    end;

    // Convert to UTF-16
    Encoding := TEncoding.Unicode; // Default to little endian UTF-16
    FileContent := TEncoding.Convert(TEncoding.Default, Encoding, FileContent);

    // Save the UTF-16 content back to the file, including BOM
    TFile.WriteAllBytes(FileName, Encoding.GetPreamble + FileContent);

    Result := True; // Successfully converted to UTF-16
  except
    // Handle exceptions (e.g., file not found, access denied)
    // You can customize the error handling as needed
  end;
end;

Geändert von bernhard_LA ( 4. Jul 2024 um 12:00 Uhr)
  Mit Zitat antworten Zitat