Hallo zusammen,
wenn ich Bilder (jpg) von einem anderen Laufwerk (Festplatte, KEIN Netzwerk Laufwerk) in meine SQLITE Tabelle speichern will, bekomme ich ab dem zweiten Bild immer einen Stream read error.
Lade ich mehrere Bilder vom aktuellen Laufwerk, läuft das Programm fehlerfrei durch. Greife ich doch auf mehrere Bilder von einem anderen Laufwerk zu, bekomme ich immer die o.a. Exception.
Warum kann er das erste Bild aus einem anderen Laufwerk in die Tabelle speichern und danach alle folgenden nicht mehr.
Wie gesagt vom aktuellen Laufwerk ist das kein Ding. Da läuft alles wunderbar.
Ich verstehe das nicht. Kann jemand sagen was ich falsch mache?
Gruß
Lorca
Coding:
VAR FName : String; FileList : TStringList; myStream : TFileStream; MyDataSet : TZTable {Zeos}
BEGIN
FOR i := 0 TO FileList.Count - 1 DO BEGIN
FName := FileList.Strings[ i ];
MyDataSet.Insert;
myStream := TFileStream.Create( FName, fmOpenRead );
TBlobField( myDataSet.FieldByName( 'Bild') ).LoadFromStream( myStream ); <<-- Hier passiert der Fehler (laut Debugger)
FreeAndNil( myStream );
MYDataSet.Post;
END;
END;
TFileStream und laden von einem anderen Laufwerk
Re: TFileStream und laden von einem anderen Laufwerk
Code: Alles auswählen
var
FName: String;
FileList: TStringList;
myStream: TFileStream;
MyDataSet : TZTable {Zeos}
i: Integer;
begin
FileList := TStringList.Create;
try
// kA wie und wo du diese FileList gefüllt hast
for i := 0 to Pred(FileList.Count) do
begin
FName := FileList.Strings[i];
if FileExists(FName) then // ein simpler check ob die datei überhaupt existiert kann nicht schaden
begin
MyDataSet.Insert;
myStream := TFileStream.Create(FName, fmOpenRead or fmShareDenyWrite); // es sollte verhindert werden das die datei beschrieben werden kann während dieser operation
try
TBlobField(myDataSet.FieldByName('Bild')).LoadFromStream(myStream);
finally
myStream.Free;
end;
MyDataSet.Post;
end
else
ShowMessage(FName + ' existiert nicht.');
end;
finally
FileList.Free;
end;
end;
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.
Re: TFileStream und laden von einem anderen Laufwerk
Hallo zusammen, hallo KodeZwerg
zunächst herzlichen Dank für Deine Antwort.
Mit OpenDialog lade ich die Daten ein. Somit ist eine Existenzprüfung nicht erforderlich.
Deine Idee mit "or fmShareDenyWrite" finde ich gut und habe es auch direkt übernommen.
Dennoch hat es zunächst immer noch nicht gefunzt.
Dann habe ich erkannt, da ich mein "MyDataSet" aus DataSource.DataSet ermittelt habe.
Definition: MyDataSet : TDataSet;
Und das war wohl mein Fehler Nummer 1.
Mein Fehler Nummer 2 war, das ich die DataSource vom Aufrufer über eine Methode: LNK_DataSource( io_DataSource : TDataSource)
übergeben habe. Jedoch war mit dieser DataSource keine TZTable sondern eine TZQuery verbunden.
Das hatte ich auch nicht als unbedingt problematisch angeschaut, da ich festgestellt habe, das ich auch eine TZQuery mit Insert und Post verwenden kann. Diese Vorgehensweise scheint jedoch bei Blobfeldern in Verbindung mit einer TZQuery eine Grätsche zu machen.
Auf die Idee, mit TZQuery.Insert und TZQuery.Post bin ich gekommen weil ich nicht weiß, wie ich sonst Blobfelder in gewohnter Art und Weise mit Insert INTO xxx... in die Query bekomme. Ich habe dazu bei meiner Recherche auch nichts im Internet gefunden.
Sollte jemand hierzu einen Vorschlag habe, wie ich in gewohnter Query Manier dieses Problem lösen kann, würde ich mich sehr freuen
Viele Grüße
Lorca
zunächst herzlichen Dank für Deine Antwort.
Mit OpenDialog lade ich die Daten ein. Somit ist eine Existenzprüfung nicht erforderlich.
Deine Idee mit "or fmShareDenyWrite" finde ich gut und habe es auch direkt übernommen.
Dennoch hat es zunächst immer noch nicht gefunzt.
Dann habe ich erkannt, da ich mein "MyDataSet" aus DataSource.DataSet ermittelt habe.
Definition: MyDataSet : TDataSet;
Und das war wohl mein Fehler Nummer 1.
Mein Fehler Nummer 2 war, das ich die DataSource vom Aufrufer über eine Methode: LNK_DataSource( io_DataSource : TDataSource)
übergeben habe. Jedoch war mit dieser DataSource keine TZTable sondern eine TZQuery verbunden.
Das hatte ich auch nicht als unbedingt problematisch angeschaut, da ich festgestellt habe, das ich auch eine TZQuery mit Insert und Post verwenden kann. Diese Vorgehensweise scheint jedoch bei Blobfeldern in Verbindung mit einer TZQuery eine Grätsche zu machen.
Auf die Idee, mit TZQuery.Insert und TZQuery.Post bin ich gekommen weil ich nicht weiß, wie ich sonst Blobfelder in gewohnter Art und Weise mit Insert INTO xxx... in die Query bekomme. Ich habe dazu bei meiner Recherche auch nichts im Internet gefunden.
Sollte jemand hierzu einen Vorschlag habe, wie ich in gewohnter Query Manier dieses Problem lösen kann, würde ich mich sehr freuen
Viele Grüße
Lorca
-
- Beiträge: 845
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: TFileStream und laden von einem anderen Laufwerk
Um solche Probleme zu vermeiden nutze ich nur EIN Objekt im Programm das mir die Verbindung zur Datenbank herstellt. In der Regel ist das dann auch ein Singleton Objekt das sicherstellt dass es dieses Objekt nur einmal im Programm gibt. Das ist ähnlich aufgebaut wie ein Datenmodul aber ohne die grafischen Elemente.
In diesem Zugriffsobjekt werden alle nötigen Komponenten zur Laufzeit erzeugt, was es ermöglicht es auch zu vererben ohne die Probleme zu bekommen die ein Datenmodul bei Vererbung gelegentlich macht.
Die TZQuery Elemente und die nötigen Datasources liegen bei mir meistens direkt auf dem Formular und werden beim Form.Create mit der Connection aus dem SingletonObjekt verbunden.
Nur wenn sehr viele Queries nötig sind erzeuge ich dafür ein extra Datenmodul.
Das vermeide ich aber tunlichst im Design.
Code: Alles auswählen
TSQLConnectGrandParent = class(TObject)
ZConnection1: TZConnection;
ZSQLMonitor1: TZSQLMonitor;
ZSQLProcessor1:TZSQLProcessor;
Die TZQuery Elemente und die nötigen Datasources liegen bei mir meistens direkt auf dem Formular und werden beim Form.Create mit der Connection aus dem SingletonObjekt verbunden.
Nur wenn sehr viele Queries nötig sind erzeuge ich dafür ein extra Datenmodul.
Das vermeide ich aber tunlichst im Design.