TFileStream und laden von einem anderen Laufwerk

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

TFileStream und laden von einem anderen Laufwerk

Beitrag von Lorca »

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;

Benutzeravatar
KodeZwerg
Beiträge: 103
Registriert: Mo 6. Feb 2023, 11:04

Re: TFileStream und laden von einem anderen Laufwerk

Beitrag von KodeZwerg »

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.

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: TFileStream und laden von einem anderen Laufwerk

Beitrag von Lorca »

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 :)

charlytango
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

Beitrag von charlytango »

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.

Code: Alles auswählen

 TSQLConnectGrandParent = class(TObject)
    ZConnection1: TZConnection;
    ZSQLMonitor1: TZSQLMonitor;
    ZSQLProcessor1:TZSQLProcessor; 
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.

Antworten