IsIniFile
user_6919294
pascal
a month ago
4.2 kB
6
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