Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Datei als array of byte einlesen (https://www.delphipraxis.net/194220-datei-als-array-byte-einlesen.html)

tofse 30. Okt 2017 13:42

Datei als array of byte einlesen
 
Hallo,

ich muss Dateien byte-weise einlesen, und verwende folgenden Code

Code:
var buffer : array of byte;
    afile: file of byte;
    i:Integer;
begin
    AssignFile(afile, FPdf);
    Reset(afile);
    SetLength(buffer, FileSize(afile));
    For i := 1 to FileSize(afile) do
       Read(afile, buffer[i]);
    CloseFile(afile);
end;
Das Problem ist, wenn ich das durchlaufen lasse, klappt es zu 80%, manchmal kommt dann ein E/A - Fehler 32. Das ist meistens der Fall, wenn im Win Explorer die Datei noch fokusiert ist.
Während der Entwicklung habe ich hier immer das gleiche PDF, es kann also nicht an der Datei selber liegen. Denn auch wenn ich den Explorer dann schließe, und es nochmal durchlaufen lasse, klappt es dann.

Gibt es eine zuverlässigere Routine, um die Datei als array of byte einzulesen oder geht das generell nicht, wenn die Datei noch fokusiert ist?

Danke
Christof

Neutral General 30. Okt 2017 13:57

AW: Datei als array of byte einlesen
 
Immer diese uralten Turbo Pascal Datei-Funktionen :roll:
Delphi-Quellcode:
var buffer: array of byte;
    i:Integer;
    datei: TFileStream;
begin
  datei := TFileStream.Create(FPdf, fmOpenRead);
  try
    SetLength(buffer, datei.Size);
    datei.Read(buffer[0], datei.Size);
  finally
    datei.Free;
  end;
end;
Falls das Problem trotzdem auftritt könnte das Problem eine Shell Extension sein, die eine Vorschau der PDF im Explorer anzeigt und die PDF dafür exklusiv öffnet.
Dann kannst du da nicht wirklich was machen.

tofse 30. Okt 2017 14:26

AW: Datei als array of byte einlesen
 
Hallo,
danke für die schnelle Antwort.
Leider funktioniert das nicht, wie gewünscht. Es läuft alles ohne Fehler durch, aber ich muss das array of byte ja an eine Funktion übergeben, die nicht von mir ist.
Die Verarbeitung läuft auch durch, aber das, was am Ende rauskommt, lässt sich nicht mehr öffnen. Das ist jetzt schwer im Detail zu erklären, aber die Funktion packt das PDF in einen DICOM container, nachdem es als array of byte eingelesen wurde und schickt es an einen Server. Dort lässt sich das DICOM dann nicht weiterverarbeiten. Mit der anderen Routine von mir klappt das.

Gruß
Christof

nahpets 30. Okt 2017 14:43

AW: Datei als array of byte einlesen
 
Es gibt die globale Variabel FileMode, über die gesteuert wird, wie eine Datei geöffnet wird und was andere gleichzeitig mit der Datei machen dürfen.

Der Standard ist fmOpenReadWrite, das dürfte für dich aber nicht relevant sein. Versuch es mal mit:

fmShareDenyNone. Andere haben uneingeschränkten Zugriff.

Oder eventuell:

fmOpenRead. Nur Lesezugriff.

Ansonsten hier mal nachschauen: http://docwiki.embarcadero.com/Libra...ystem.FileMode

Neutral General 30. Okt 2017 15:04

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von tofse (Beitrag 1384575)
Hallo,
danke für die schnelle Antwort.
Leider funktioniert das nicht, wie gewünscht. Es läuft alles ohne Fehler durch, aber ich muss das array of byte ja an eine Funktion übergeben, die nicht von mir ist.
Die Verarbeitung läuft auch durch, aber das, was am Ende rauskommt, lässt sich nicht mehr öffnen. Das ist jetzt schwer im Detail zu erklären, aber die Funktion packt das PDF in einen DICOM container, nachdem es als array of byte eingelesen wurde und schickt es an einen Server. Dort lässt sich das DICOM dann nicht weiterverarbeiten. Mit der anderen Routine von mir klappt das.

Ich behaupte einfach mal ganz dreist dass, das nicht an meiner Methode liegt.
In dem buffer-Array sollte am Ende von deiner und meiner Methode exakt das gleiche drin stehen.

Und wenn dus schon mit den uralt-Funktionen machst, dann lies bitte nicht jedes Byte einzeln aus der Datei :/

p80286 30. Okt 2017 15:43

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von tofse (Beitrag 1384575)
..aber ich muss das array of byte ja an eine Funktion übergeben, die nicht von mir ist.

Ja und?
Array of Byte ist Array of Byte! oder soll es statt "dynamisch" "statisch" sein?
dann könnte u.U das filesize etwas groß sein?!
Zitat:

Zitat von tofse (Beitrag 1384575)
Die Verarbeitung läuft auch durch, aber das, was am Ende rauskommt, lässt sich nicht mehr öffnen.

Beschreib doch mal "was am Ende rauskommt"
Das klingt als sei es eine Datei.

Gruß
K-H

P.S.
Ich stimme mit Neutral General überein, an seiner Methode liegt es nicht.

brechi 30. Okt 2017 16:45

AW: Datei als array of byte einlesen
 
In s3iner Methode ist alles um 1 byte nach hinten verschoben, weil die Zählvariable bei eins los geht. Dqher wuch der Fehler, weil der buffer zu klein ist.

Redeemer 30. Okt 2017 19:38

AW: Datei als array of byte einlesen
 
Ich werfe noch Delphi-Referenz durchsuchenTBytesStream in die Runde.

Zitat:

Zitat von nahpets (Beitrag 1384579)
Es gibt die globale Variabel FileMode, über die gesteuert wird, wie eine Datei geöffnet wird und was andere gleichzeitig mit der Datei machen dürfen.

Der Standard ist fmOpenReadWrite, das dürfte für dich aber nicht relevant sein. Versuch es mal mit:

fmShareDenyNone. Andere haben uneingeschränkten Zugriff.

Oder eventuell:

fmOpenRead. Nur Lesezugriff.

Ansonsten hier mal nachschauen: http://docwiki.embarcadero.com/Libra...ystem.FileMode

Mich irritiert der Satz in der Doku: "Hinweis: Unter Windows wird der Parameter Rights ignoriert."
Ist das wirklich so? Also zumindest bei fmCreate kann man Rights nicht angeben (ist immer fmShareExclusive), aber beim Rest ging das glaube ich...

Uwe Raabe 31. Okt 2017 09:52

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von Redeemer (Beitrag 1384615)
Mich irritiert der Satz in der Doku: "Hinweis: Unter Windows wird der Parameter Rights ignoriert."
Ist das wirklich so?

Da hat die Doku durchaus Recht! Die fmShareXXX Attribute müssen mit dem Mode-Parameter (fmCreate/fmOpenXXX) per OR verknüpft werden. Der Parameter Rights wird unter Windows nicht ausgewertet.

Zitat:

Zitat von Redeemer (Beitrag 1384615)
Also zumindest bei fmCreate kann man Rights nicht angeben (ist immer fmShareExclusive), aber beim Rest ging das glaube ich...

Das stimmt nicht so ganz. Bei
Delphi-Quellcode:
fmCreate
wird nur dann
Delphi-Quellcode:
fmShareExclusive
verwendet, wenn als Mode
Delphi-Quellcode:
$FFFF
bzw.
Delphi-Quellcode:
fmCreate OR $FF
übergeben wird. Dabei wird aber auch das
Delphi-Quellcode:
fmCreate
quasi herausgenommen und eben nur
Delphi-Quellcode:
fmShareExclusive
übergeben.

Der Rights-Parameter wird sogar ausschließlich beim
Delphi-Quellcode:
fmCreate
ausgewertet und das auch nur unter POSIX. Dabei wird die Datei mit den angegebenen Zugriffsrechten angelegt. Beim Öffnen einer existierenden Datei würde das Ändern der Zugriffsrechte ja auch keinen Sinn ergeben.

Redeemer 31. Okt 2017 10:28

AW: Datei als array of byte einlesen
 
Wie kann ich denn bei TFileStream eine Datei nicht-exklusiv erstellen und öffnen?

Uwe Raabe 31. Okt 2017 10:53

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von Redeemer (Beitrag 1384630)
Wie kann ich denn bei TFileStream eine Datei nicht-exklusiv erstellen und öffnen?

Z.B. so:
Delphi-Quellcode:
TFileStream.Create(<filename>, fmCreate or fmShareDenyWrite);


Sobald die Datei dann existiert kannst du über
Delphi-Quellcode:
TFileStream.Create(<filename>, fmOpenRead or fmShareDenyNone);
von anderer Stelle lesend darauf zugreifen.

Redeemer 31. Okt 2017 12:23

AW: Datei als array of byte einlesen
 
In Delphi 2009 ist fmCreate als $FFFF definiert...
Ich möchte die Datei nur schreiben, nicht lesen.

Uwe Raabe 31. Okt 2017 13:36

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von Redeemer (Beitrag 1384638)
In Delphi 2009 ist fmCreate als $FFFF definiert...
Ich möchte die Datei nur schreiben, nicht lesen.

Soweit ich weiß, ist in D2009 bei fmCreate der Share-Mode immer 0.

himitsu 31. Okt 2017 16:59

AW: Datei als array of byte einlesen
 
Man kann auch problemlos einen eigenen Constructor für TFileStream schreiben
oder nutzt THandleStream mit MSDN-Library durchsuchenCreateFile
und kann da dann machen was man will.

PS: Delphi-Referenz durchsuchenTFile.ReadAllBytes

tofse 6. Nov 2017 13:25

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von Neutral General (Beitrag 1384581)

Ich behaupte einfach mal ganz dreist dass, das nicht an meiner Methode liegt.
In dem buffer-Array sollte am Ende von deiner und meiner Methode exakt das gleiche drin stehen.

Und wenn dus schon mit den uralt-Funktionen machst, dann lies bitte nicht jedes Byte einzeln aus der Datei :/

Hallo,
so hat es funktioniert
Delphi-Quellcode:
 datei := TFileStream.Create(FPdf, fmOpenRead);
 try

     SetLength(buffer, datei.Size);
     datei.Read(buffer[1], datei.Size);
 finally
     datei.Free;
 end;

Neutral General 6. Nov 2017 13:50

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von tofse (Beitrag 1385373)
Hallo,
so hat es funktioniert

Du hast 2 Möglichkeiten:

1) NICHT ZU EMPFEHLEN
Delphi-Quellcode:
datei := TFileStream.Create(FPdf, fmOpenRead);
try
   SetLength(buffer, datei.Size+1); // +1 !
   datei.Read(buffer[1], datei.Size);
finally
   datei.Free;
end;
wenn du schon ab Index 1 einliest, dann muss das Array 1 Byte größer sein oder das letzte Byte steht in der Pampa was böse in die Hose gehen kann.

2) Besser:
Delphi-Quellcode:
datei := TFileStream.Create(FPdf, fmOpenRead);
try
   SetLength(buffer, datei.Size);
   datei.Read(buffer[0], datei.Size);
finally
   datei.Free;
end;
Und du passt deine anderen Methoden zum verarbeiten der PDF an, sodass diese ab buffer[0] anfangen zu lesen und nicht ab buffer[1]!
Das ist nämlich dein wahres Problem :!:

tofse 6. Nov 2017 14:09

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von Neutral General (Beitrag 1385380)

Und du passt deine anderen Methoden zum verarbeiten der PDF an, sodass diese ab buffer[0] anfangen zu lesen und nicht ab buffer[1]!
Das ist nämlich dein wahres Problem :!:

Ok, habe ich verstanden, geht aber nicht, da nicht von mir.
Deshalb verwende ich die Variante 1

Dennoch danke!

Neutral General 6. Nov 2017 14:18

AW: Datei als array of byte einlesen
 
Aber der Code ist doch vorhanden oder nicht?
Bzw. einer deiner Kollegen o.ä. hat den Code doch geschrieben oder nicht?

Also wenn der Code vorhanden ist dann beheb den Fehler selbst oder sag dem Bescheid der das verbrochen hat.

tofse 6. Nov 2017 14:22

AW: Datei als array of byte einlesen
 
Hm, ne.
Das ist eine kommerzielle COM/ActiveX API, ich teste die gerade, bevor wir kaufen.
Ich habe da mal angefragt, wieso das so ist.

Gruß

himitsu 6. Nov 2017 14:32

AW: Datei als array of byte einlesen
 
0 oder 1 ....

Es sei denn Buffer ist ein String/AnsiString :stupid:



Nja, das "eine" Problem in Post #1 hätte er leicht finden können, indem einfach mal die Bereichsprüfung aktiviert wird.

tofse 6. Nov 2017 14:37

AW: Datei als array of byte einlesen
 
Abschließend die Antwort vom Anbieter, wusste ich auch nicht, war ja eigentlich auch nicht die ursp. Frage. Das mit der Exception ist jetzt in jeden Fall weg :-)

Zitat:

That’s because our COM version of DicomObjects uses/expects 1-based array. This is very common in COM programming.
In our .NET version everything is 0-based.

tofse 6. Nov 2017 14:39

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von himitsu (Beitrag 1385386)
Nja, das "eine" Problem in Post #1 hätte er leicht finden können, indem einfach mal die Bereichsprüfung aktiviert wird.

Ne, das war nicht das Problem, die Exception kam immer hier,wenn auf der Datei noch irgendwie ein Zugriff war
Delphi-Quellcode:
               AssignFile(afile, Self.FPdf);
               Reset(afile);

himitsu 6. Nov 2017 14:41

AW: Datei als array of byte einlesen
 
Du hast da mehr als nur ein Problem.

Buffer Overflow durch falsche Indizierung.

p80286 6. Nov 2017 14:58

AW: Datei als array of byte einlesen
 
Zitat:

Zitat von tofse (Beitrag 1385389)
Zitat:

Zitat von himitsu (Beitrag 1385386)
Nja, das "eine" Problem in Post #1 hätte er leicht finden können, indem einfach mal die Bereichsprüfung aktiviert wird.

Ne, das war nicht das Problem, die Exception kam immer hier,wenn auf der Datei noch irgendwie ein Zugriff war
Delphi-Quellcode:
               AssignFile(afile, Self.FPdf);
               Reset(afile);

Dann wäre es interessant zu wissen, welchen Wert Filemode hat.
(Und vielleicht ist es bisher unter gegangen, die "modernen" Routinen (TFileStream) sind auf jeden Fall zu bevorzugen. Und ein
Delphi-Quellcode:
File of Byte
war schon zu Turbo Pascal Zeiten längst überholt.)

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 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