IsIniFile 2

 avatar
user_6919294
pascal
a month ago
2.7 kB
7
Indexable
{*
 
  #CODE BY IRENEUSZ A.

 * Weryfikuje czy plik ma format INI poprzez analizę jego struktury.
 * @since  2025-03-20
 * @param  FileName Ścieżka do weryfikowanego pliku
 * @return True gdy plik zawiera poprawny nagłówek sekcji INI
 
 *}
function IsIniFile(const FileName: string): Boolean;
var
  FileStream: TFileStream;
  Buffer: array[0..1023] of Byte;
  BytesRead: Integer;
  I, BufferLen: Integer;
  InComment: Boolean;
  Line: string;
begin
  Result := False;
  
  // Walidacja istnienia pliku
  if not FileExists(FileName) then
    Exit;
  
  try
    // Otwarcie pliku w trybie tylko do odczytu z najmniejszymi ograniczeniami dostępu
    FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
    try
      // Odczyt pierwszego fragmentu wystarczającego do identyfikacji formatu
      BytesRead := FileStream.Read(Buffer, SizeOf(Buffer));
      if BytesRead <= 0 then Exit;
      
      BufferLen := BytesRead;
      SetLength(Line, 0);
      InComment := False;
      
      // Skanowanie zawartości bajt po bajcie
      for I := 0 to BufferLen - 1 do
      begin
        case Chr(Buffer[I]) of
          #13, #10: // CR, LF - koniec linii
            begin
              if Length(Line) > 0 then
              begin
                Line := Trim(Line);
                
                // Sprawdzenie znaczników sekcji INI: [sekcja]
                if (Line <> '') and (not InComment) and 
                   (Line[1] = '[') and (Line[Length(Line)] = ']') then
                begin
                  Result := True;
                  Exit;
                end;
                
                // Wykrycie początku komentarza
                if Line.StartsWith(';') or Line.StartsWith('#') then
                  InComment := True;
                
                // Reset przy znaku LF (0x0A)
                if Chr(Buffer[I]) = #10 then
                begin
                  SetLength(Line, 0);
                  InComment := False;
                end;
              end;
            end;
          else
            // Akumulacja znaków bieżącej linii
            Line := Line + Chr(Buffer[I]);
        end;
      end;
      
      // Obsługa ostatniej linii bez terminatora
      if Length(Line) > 0 then
      begin
        Line := Trim(Line);
        if (Line <> '') and (not InComment) and 
           (Line[1] = '[') and (Line[Length(Line)] = ']') then
        begin
          Result := True;
        end;
      end;
    finally
      FileStream.Free;
    end;
  except
    // Cicha obsługa błędów I/O
    Result := False;
  end;
end;
Editor is loading...
Leave a Comment