nun ja, da mir Mabuse einen sehr guten Tipp für die Integration einer
Hex-Ansicht für meinen Editor gegeben hat, habe ich mir nun einige kleine
Routinen geschrieben, die mir dies ermöglichen werden.
Diese Funktion überprüft, ob eine Datei von einem Texteditor gelesen
werden kann oder nicht. Es wäre schön, wenn ihr diesen Ablauf einmal
bei euch testen könntet und mir mögliche Fehlerquellen zukommen läßt.
Optimierungen sind selbstverständlich, willkommen.
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Methode 1: TFileStream
// Prüft, ob sich in einer Datei binäre Zeichen befinden
////////////////////////////////////////////////////////////////////////////////
function TForm1.IsBinaryFile(FileName: String): Integer;
const MAX_Buffer = 2048; // Puffer in Byte pro Block
Forbidden: Set of Byte = [0..8, 11, 14..31]; // typische Binärzeichen
var FileStream: TFileStream;
Buffer: Array[1..MAX_Buffer] of Byte; // Datenpuffer
FileSize: Int64;
Blocks, Last, i, f, BufferSize, ActSize: Integer;
begin
Result := 0;
ActSize := 0;
if FileExists(FileName) then
begin // die Datei existiert, also lesen wir sie ein
try
FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
except
Result := -2; // Datei wird von einem anderen Prozess verwendet
Exit;
end;
try
FileSize := FileStream.Size; // Dateigröße in Byte
Blocks := (FileSize div MAX_Buffer); // Anzahl max. Blöcke
Last := (FileSize mod MAX_Buffer); // Größe des Rest-Puffer
if Last <> 0 then
inc(Blocks); // sofern, unser Restpuffer ungleich 0 Byte groß ist, wird unsere Blockvariable um 1 erhöht
for i := 0 to Blocks -1 do // Blöcke einlesen
begin
if Result = 1 then
Break; // spring aus der Schleife, wenn ein binäres Zeichen gefunden wurde
FileStream.Position := ActSize; // Start-Position in Byte (wird von Block zu Block angepasst)
inc(ActSize, MAX_Buffer);
if ActSize <= FileSize then
BufferSize := MAX_Buffer else
BufferSize := Last;
FileStream.ReadBuffer(Buffer[1], BufferSize);
for f := 1 to BufferSize do
begin // den eingelesenen Puffer durchsuchen
if Result = 1 then
Break; // spring aus der Schleife, wenn ein binäres Zeichen gefunden wurde
if Buffer[f] < 32 then
begin if Buffer[f] in Forbidden then
begin
Result := 1; // ein binäres Zeichen wurde gefunden
Break;
end;
end;
end;
end;
finally FileStream.Free;
end;
end else
Result := -1; // Datei existiert nicht
end;
////////////////////////////////////////////////////////////////////////////////
// Methode 2: BlockRead
// Prüft, ob sich in einer Datei binäre Zeichen befinden
////////////////////////////////////////////////////////////////////////////////
function TForm1.IsBinaryFile2(FileName: String): Integer;
const MAX_Buffer = 2048; // Puffer in Byte pro Block
Forbidden: Set of Byte = [0..8, 11, 14..31]; // typische Binärzeichen
var AFile: File;
Buffer: Array[1..MAX_Buffer] of Byte; // Datenpuffer
FSize: Int64;
Blocks, Last, i, f, BufferSize, ActSize: Integer;
begin
Result := 0;
ActSize := 0;
if FileExists(FileName) then
begin // die Datei existiert, also lesen wir sie ein
AssignFile(AFile, FileName);
{$i-}
Reset(AFile, 1);
{$i+}
if IOResult = 0 then // Datei ist geöffnet...
begin
try
FileMode := fmOpenRead or fmShareDenyNone;
FSize := FileSize(AFile); // Dateigröße in Byte
Blocks := (FSize div MAX_Buffer); // Anzahl max. Blöcke
Last := (FSize mod MAX_Buffer); // Größe des Rest-Puffer
if Last <> 0 then
inc(Blocks); // sofern, unser Restpuffer ungleich 0 Byte groß ist, wird unsere Blockvariable um 1 erhöht
for i := 0 to Blocks -1 do // Blöcke einlesen
begin
if Result = 1 then
Break; // spring aus der Schleife, wenn ein binäres Zeichen gefunden wurde
Seek(AFile, ActSize); // Start-Position in Byte (wird von Block zu Block angepasst)
inc(ActSize, MAX_Buffer);
if ActSize <= FSize then
BufferSize := MAX_Buffer else
BufferSize := Last;
BlockRead(AFile, Buffer[1], BufferSize);
for f := 1 to BufferSize do
begin // den eingelesenen Puffer durchsuchen
if Result = 1 then
Break; // spring aus der Schleife, wenn ein binäres Zeichen gefunden wurde
if Buffer[f] < 32 then
begin if Buffer[f] in Forbidden then
begin
Result := 1; // ein binäres Zeichen wurde gefunden
Break;
end;
end;
end;
end;
finally CloseFile(AFile);
end;
end else Result := -2; // Datei wird von einem fremden Prozess verwendet
end else Result := -1; // Datei existiert nicht
end;