AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

"binäre" Dateien

Ein Thema von bigg · begonnen am 1. Mai 2005 · letzter Beitrag vom 1. Mai 2005
Antwort Antwort
Seite 1 von 2  1 2      
bigg
(Gast)

n/a Beiträge
 
#1

"binäre" Dateien

  Alt 1. Mai 2005, 03:43


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;
Angehängte Dateien
Dateityp: zip isbinfast_204.zip (3,2 KB, 30x aufgerufen)
  Mit Zitat antworten Zitat
Nicodius

Registriert seit: 25. Apr 2003
Ort: Graz
2.234 Beiträge
 
Delphi 2006 Architect
 
#2

Re: "binäre" Dateien

  Alt 1. Mai 2005, 07:34
würde ich hierher geben "Neuen Beitrag zur Code-Library hinzufügen" ist ja wichtig
Nico Müller
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#3

Re: "binäre" Dateien

  Alt 1. Mai 2005, 13:38
Ich habe mich mal drangesetzt, den Code zu optimieren, und habe eine Verbesserung um den Faktor 4-5 geschafft (etwa 6,4 MB/sec zu etwa 28,7 MB/sec). Code ist im Anhang, die Testdatei (80 MB, nicht binär, nicht zufällig erstellt) gibt es auf Anfrage.

/edit: Enthält noch nicht Result:=-2
Angehängte Dateien
Dateityp: zip isbin_133.zip (4,8 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#4

Re: "binäre" Dateien

  Alt 1. Mai 2005, 13:40
Zitat von Nicodius:
würde ich hierher geben "Neuen Beitrag zur Code-Library hinzufügen" ist ja wichtig
Ich habe noch eine Kleinigkeit abgeändert.
PS: Wenn die Mods nichts dagegen haben, kann der Thread verschoben werden.^^
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#5

Re: "binäre" Dateien

  Alt 1. Mai 2005, 13:48
Zitat von Phistev:
Ich habe mich mal drangesetzt, den Code zu optimieren, und habe eine Verbesserung um den Faktor 4-5 geschafft (etwa 6,4 MB/sec zu etwa 28,7 MB/sec). Code ist im Anhang, die Testdatei (80 MB, nicht binär, nicht zufällig erstellt) gibt es auf Anfrage.

/edit: Enthält noch nicht Result:=-2
Das kann dann aber nur am Set liegen
Danke für diesen Hinweis
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#6

Re: "binäre" Dateien

  Alt 1. Mai 2005, 15:40
So, die neue Version ist nun deutlich schneller geworden,
sofern man große Textdateien damit überprüfen möchte.

Im Schnitt 40% schneller als Phistev modifizierte Version.
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#7

Re: "binäre" Dateien

  Alt 1. Mai 2005, 16:50
Wenn man das Set durch eine Abfrage wie if (Buffer[f] < 32) and (Buffer[f] <> 9) and (Buffer[f] <> 10) and (Buffer[f] <> 13) then ersetzt, kann man nochmal etwa 65-70 % rausholen ; inzwischen sind wir bei Geschwindigkeiten von ca. 150-160 MB/sec . Ich teste mal, wie schnell eine file of byte wäre, nur aus akademischem Interesse...

/edit: Das mit file of byte habe ich wieder begraben. Einfach zu langsam.
Angehängte Dateien
Dateityp: zip isbinfast2_822.zip (4,9 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#8

Re: "binäre" Dateien

  Alt 1. Mai 2005, 17:25
Bei mir ist deine Routine langsamer.
Hast du nur Zeilenumbrüche in deiner Test-Datei?
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#9

Re: "binäre" Dateien

  Alt 1. Mai 2005, 17:33
Nein, (http://Phistev.united-systems.org/combined.cab, 10 MB) aber ich musste auch feststellen, dass die Performance schwankt. Ich erstelle gerade eine zweite Testdatei (2GB), um zu sehen, wie sehr Vor- und Nachbereitung (TFileStream.Create etc.) auf die Performance wirken.
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#10

Re: "binäre" Dateien

  Alt 1. Mai 2005, 18:12
Ich denke eine Funktion mit AssignFile, BlockRead, ResetFile und CloseFile sollte noch schneller sein
Außerdem könnte man sie vielseitger verwenden.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz