IsIniFile
user_6919294
pascal
7 months ago
4.2 kB
7
Indexable
{**
POMOGĘ, Iruś xD
Opis funkcji
* Sprawdza czy plik jest w formacie INI analizując jego zawartość.
* Plik jest uznawany za INI, jeśli zawiera sekcję w formacie [nazwa_sekcji].
* Funkcja analizuje tylko pierwsze 1KB pliku dla optymalizacji wydajności.
*
* @param FileName Pełna ścieżka do pliku, który ma być sprawdzony
* @return True jeśli plik jest w formacie INI, False w przeciwnym przypadku
*}
function IsIniFile(const FileName: string): Boolean;
var
FileStream: TFileStream; // Strumień do odczytu pliku
Buffer: array[0..1023] of Byte; // Bufor 1KB do przechowywania pierwszego fragmentu pliku
BytesRead: Integer; // Liczba odczytanych bajtów
I, BufferLen: Integer; // Indeks iteracji i rozmiar bufora
InComment: Boolean; // Flaga oznaczająca, czy jesteśmy wewnątrz komentarza
Line: string; // Bieżąca analizowana linia
begin
Result := False; // Domyślnie zakładamy, że plik nie jest INI
// Sprawdzenie czy plik istnieje
if not FileExists(FileName) then
Exit; // Jeśli plik nie istnieje, zwracamy False
// Analiza zawartości pliku
try
// Otwieramy plik z uprawnieniami do odczytu, umożliwiając jednocześnie dostęp innym procesom
FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
// Odczytujemy pierwszy fragment pliku (do 1KB)
BytesRead := FileStream.Read(Buffer, SizeOf(Buffer));
if BytesRead > 0 then
begin
BufferLen := BytesRead;
SetLength(Line, 0); // Inicjalizacja pustej linii
InComment := False; // Początkowo nie jesteśmy w komentarzu
// Analizujemy każdy bajt z bufora
for I := 0 to BufferLen - 1 do
begin
case Chr(Buffer[I]) of
#13, #10: // Znak końca linii (CR lub LF)
begin
if (Length(Line) > 0) then
begin
Line := Trim(Line); // Usuwamy białe znaki z początku i końca linii
// Kluczowy test: sprawdzamy czy linia ma format [nazwa_sekcji]
// i nie jest komentarzem
if (Line <> '') and (not InComment) and
(Line[1] = '[') and (Line[Length(Line)] = ']') then
begin
Result := True; // Znaleziono sekcję INI!
Exit; // Kończymy przetwarzanie - mamy już odpowiedź
end;
// Wykrywanie linii komentarza (zaczynającej się od ; lub #)
if (Line.StartsWith(';')) or (Line.StartsWith('#')) then
InComment := True;
// Jeśli napotkaliśmy znak LF, resetujemy linię i flagę komentarza
// (przygotowanie do analizy nowej linii)
if (Chr(Buffer[I]) = #10) then
begin
SetLength(Line, 0);
InComment := False;
end;
end;
end;
else
// Dodajemy bieżący znak do aktualnie konstruowanej linii
Line := Line + Chr(Buffer[I]);
end;
end;
// Obsługa ostatniej linii, jeśli plik nie kończy się znakiem nowej linii
if (Length(Line) > 0) then
begin
Line := Trim(Line);
// Ten sam test co wcześniej, ale dla ostatniej linii
if (Line <> '') and (not InComment) and
(Line[1] = '[') and (Line[Length(Line)] = ']') then
begin
Result := True; // Znaleziono sekcję INI w ostatniej linii!
end;
end;
end;
finally
// Zawsze zamykamy strumień pliku, niezależnie od wyniku
FileStream.Free;
end;
except
// Bezpieczne przechwycenie i ignorowanie wszelkich błędów odczytu
// np. brak uprawnień, uszkodzony plik, itp.
Result := False;
end;
end;Editor is loading...
Leave a Comment