[gelöst]LoadFromFile vom netzlaufwerk

Alle Fragen zur Netzwerkkommunikation

[gelöst]LoadFromFile vom netzlaufwerk

Beitragvon gladio » 25. Aug 2017, 00:40 [gelöst]LoadFromFile vom netzlaufwerk

Ich habe ein Problem beim Öffnen von Dateien von Netzlaufwerken deshalb stelle ich das mal hier ein.

Windows 7 und 10, Lazarus 1.6x und 1.8RC3

Über eine FileListBox wird eine Datei ausgewählt, geöffnet und in einem Memo angezeigt.

Code: Alles auswählen
var 
    str2: TStringList;
begin
  ..
  Arbeitsverzeichnis := INIDat.ReadString('Arbeitspfad','Pfad','C:\ ');
  FileListBox1.Directory := Arbeitsverzeichnis;
  Datei := extractFilename(FileListBox1.FileName);
  ...
  Str2 := TStringList.Create;
  try
    Str2.LoadFromFile(Datei)//bricht hier ab und springt zu ..free
    Memo1.Text := STr2.Text;
  ...
  finally
    Str2.Free;
  end;
....
 


Funktioniert auch wunderbar, solange sich die Datei nicht in einem Netzlaufwerk auf dem Datenserver oder eines NAS oder in einem Cloude-Verzeichnis befinden.
Dann wird mit dieser allseits bekannten Fehlermeldung abgebrochen:
Code: Alles auswählen
 
Unable to open file ...
Press OK to ignore...
Press cancel to kill ...

Bei OK passiert nichts, bei Cancel wird das Programm beendet.

Die zu öffnenden Dateien stammen aus einem Auslesegerät.
Sie werden vom gleichen Benutzer (Admin-Rechte) mit dem ich das Programm ausführe, abgelegt.
Es gibt keine Zugriffsbeschränkungen bei den Dateien, werden ja auch nur gelesen.
Das Programm selbst mit höchsten Rechten zu compilieren oder als Admin auszuführen bringt nichts.
Kopiere ich die Dateien vom Netzlaufwerk auf ein lokales Verzeichnis, lassen sie sich problemlos öffnen/lesen.

Prakmatisch könnte ich das lösen, indem ich die zu öffnende Datei einfach temporär ins lokale Programmverzeichnis mit CopyFile kopiere,
lese und dann wieder lösche.

Aber warum geht das nicht direkt auf dem Netzlaufwerk?
Zuletzt geändert von gladio am 27. Aug 2017, 09:06, insgesamt 1-mal geändert.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon wp_xyz » 25. Aug 2017, 08:12 Re: LoadFromFile vom netzlaufwerk

Hast du das Netzlaufwerk so ins System eingebunden, dass es einen Laufwerksbuchstaben hat ("Netzlaufwerk verbinden")? Wenn ja, dann sollte es funktionieren. Ich habe es eben mit meinem NAS getestet.
wp_xyz
 
Beiträge: 2896
Registriert: 8. Apr 2011, 08:01

Beitragvon af0815 » 25. Aug 2017, 10:08 Re: LoadFromFile vom netzlaufwerk

wp_xyz hat geschrieben:Hast du das Netzlaufwerk so ins System eingebunden, dass es einen Laufwerksbuchstaben hat ("Netzlaufwerk verbinden")? Wenn ja, dann sollte es funktionieren. Ich habe es eben mit meinem NAS getestet.

Ich habe festgestellt, das NAS (meist samba) nicht gleich Microsoft Server sind. Die beste Erfahrung habe ich damit gemacht, wenn das Share als Laufwerk gemountet ist UND aktiv ist. Es passiert öfters, wenn die Verbindung nicht aktiv ist, das der Explorer sich zwar verbinden kann, du aber von der programmierseite keine (einfache + automatische) Möglichkeit hast das Laufwerk zu aktivieren.

Beim testen würde ich parallel den Explorer offen halten und kontrollieren ob die Verbindung/Share noch wirklich aktiv ist.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3632
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon braunbär » 25. Aug 2017, 10:41 Re: LoadFromFile vom netzlaufwerk

Ja, das kann ich bestätigen. Das Problem tritt aber auch bei freigegebenen Windows Netzlaufwerken sporadisch auf (bei einem Windows Server ist es mir noch nicht passiert).
Die Verbindung zwischen Windows und einem Netzlaufwerk reißt manchmal unmotiviert ab, oder wird beim Start gar nicht erst hergestellt. Erst wenn man mit dem Explorer (oder einem anderen brauchbaren Dateimanager) das Laufwerk anwählt, funktioniert es. Ich habe auch noch nicht herausgefunden, was man vom Programm aus machen kann, um in so einem Fall das Laufwerk wieder zu aktivieren. Ich habe mich aber noch nicht ernsthaft bemüht, wahrscheinlich würde schon ein Shell-Aufruf des Windows Explorer mit einem Netzverzeichnis als Parameter als Workaround funktionieren.
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 17:21

Beitragvon gladio » 25. Aug 2017, 15:46 Re: LoadFromFile vom netzlaufwerk

Die betreffenden Laufwerke sind eingebunden und haben Laufwerksbuchstaben.
Die zu öffnenden Dateien lassen sich auch problemlos mit dem Windows Editor oder WordPad oder LibreOffice öffnen.

Ich habe auch mal das kopieren erfolgreich ausprobiert:
Code: Alles auswählen
CopyFile(Arbeitsverzeichnis+'\ '+Datei, 'c:\test'+Datei);

Wahrscheinlich werde ich das dann auch so umsetzen, daß ich die Datei erst lokal kopiere und dann mit der Kopie arbeite.

Daß sich freigegebene Netzlaufwerke unter Windows nach einer gewissen/unbestimmten Zeit bei Nichtnutzung 'schlafen legen'
habe ich auch schon beobachtet.
Ist aber nicht relevant, weil ich den Exploren meistens offen hatte.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon Mathias » 25. Aug 2017, 16:03 Re: LoadFromFile vom netzlaufwerk

oder wird beim Start gar nicht erst hergestellt. Erst wenn man mit dem Explorer (oder einem anderen brauchbaren Dateimanager) das Laufwerk anwählt, funktioniert es. Ich habe auch noch nicht herausgefunden,

Als ich noch mit Windows arbeitete ist mir dies auch schon mehrmals aufgefallen. :roll:

Ich habe auch mal das kopieren erfolgreich ausprobiert:
Code: Alles auswählen
CopyFile(Arbeitsverzeichnis+'\ '+Datei, 'c:\test'+Datei);

Da staune ich, das dies geklappt hat, da du hinter dem '\' ein Leerzeichen hast.

Die betreffenden Laufwerke sind eingebunden und haben Laufwerksbuchstaben.
Die zu öffnenden Dateien lassen sich auch problemlos mit dem Windows Editor oder WordPad oder LibreOffice öffnen.

Ich kann es mir schlecht vorstellen, aber evtl. liegt es an gross und klein-Schreibung.
Sind evtl. Umlaute im Dateinamen ?

Code: Alles auswählen
 Str2.LoadFromFile(Datei)//bricht hier ab und springt zu ..free

Was kommt bei Showmessage(Datei); ?

Code: Alles auswählen
Datei := extractFilename(FileListBox1.FileName);

Was passiert, wen du das extractFileName weglässt ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4343
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon gladio » 25. Aug 2017, 16:47 Re: LoadFromFile vom netzlaufwerk

[quote="Mathias"]Da staune ich, das dies geklappt hat, da du hinter dem '\' ein Leerzeichen hast.[quote]

Das Leezeichen habe ich hier nur zusätzlich in den Code eingefügt. Du hast sicher schon bemerkt das bei der Code-hervorhebung ...'\'... der Backslash nicht angezeigt wird.
Code: Alles auswählen
''


Groß-/Kleinschreibung und Umlaute spielen keine Rolle, da Pfad und Daieiname ausgewählt und nicht eingegebne werden.

ShowMessage(Datei) zeigt den Dateinamen der ausgewählten Datei, so wie es sein soll.
Aber auch nur, wenn ExtractFileName nicht weggelassen wird.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon wp_xyz » 25. Aug 2017, 17:12 Re: LoadFromFile vom netzlaufwerk

gladio hat geschrieben:Ich habe auch mal das kopieren erfolgreich ausprobiert:
Code: Alles auswählen
CopyFile(Arbeitsverzeichnis+'\ '+Datei, 'c:\test'+Datei);

Wahrscheinlich werde ich das dann auch so umsetzen, daß ich die Datei erst lokal kopiere und dann mit der Kopie arbeite.

Seltsam, eigentlich wird da doch auch nur die Datei geöffnet und gelesen, so wie in der TStringList. Vielleicht kommt der FileStream, der von TStringList geöffnet wird, nicht damit zurecht, dass die Datei nicht sofort offen ist? Könntest du mal direkt mit einem Filestream arbeiten und nach dem Öffnen eine kleine Verzögerung einbauen?

Code: Alles auswählen
var
  fs: TFileStream;
 
  Arbeitsverzeichnis := INIDat.ReadString('Arbeitspfad','Pfad','C:\ ');
  FileListBox1.Directory := Arbeitsverzeichnis;
  Datei := extractFilename(FileListBox1.FileName);
  ...
  Str2 := TStringList.Create;
  try
    fs := TFileStream.Create(Datei, fmOpenRead + fmShareDenyNone);
    try
      Sleep(1000)// ganz brutal 1 Sekunde warten - nur zum Test...
      Str2.LoadfromStream(fs);
    finally
      fs.Free;
    end;
    Memo1.Text := STr2.Text;
  ...
  finally
    Str2.Free;
  end;

Wenn es geht, könntest du schrittweise die Verzögerung in Sleep() verringern.
wp_xyz
 
Beiträge: 2896
Registriert: 8. Apr 2011, 08:01

Beitragvon gladio » 25. Aug 2017, 18:11 Re: LoadFromFile vom netzlaufwerk

hm, schade.
jetzt spingt es von
Code: Alles auswählen
fs := TFileStream.Create(Datei, fmOpenRead + fmShareDenyNone);

zum äußeren
Code: Alles auswählen
  finally
       Str2.Free;

und bricht ab.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon wp_xyz » 25. Aug 2017, 18:21 Re: LoadFromFile vom netzlaufwerk

Dann probier mal ein FileExists vor dem Öffnen des Streams oder vor StringList.LoadFromFile - irgendwas muss bei Copy anders sein, damit es dort funktioniert:

Code: Alles auswählen
  Str2 := TStringList.Create;
  try
    if not FileExists(Datei) then Sleep(1000)// <------- neu
    Str2.LoadFromFile(Datei);
    Memo1.Text := STr2.Text;
  ...
  finally
    Str2.Free;
  end;
wp_xyz
 
Beiträge: 2896
Registriert: 8. Apr 2011, 08:01

Beitragvon MacWomble » 25. Aug 2017, 18:30 Re: LoadFromFile vom netzlaufwerk

gladio hat geschrieben:Das Leezeichen habe ich hier nur zusätzlich in den Code eingefügt. Du hast sicher schon bemerkt das bei der Code-hervorhebung ...'\'... der Backslash nicht angezeigt wird.


Es wäre auch besser, grundsätzlich die folgende Schreibweise zu wählen:

Code: Alles auswählen
CopyFile(Arbeitsverzeichnis + PathDelim + Datei);
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 787
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.80 / FP 3.3.1 SVN Rev 41791 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon gladio » 25. Aug 2017, 18:44 Re: LoadFromFile vom netzlaufwerk

Jetzt wird Sleep(1000) ausgeführt, also existiert 'Datei' an dieser Stelle für das Programm unverständlicherweise nicht.

Datei und Arbeitsverzeichnis sind als normaler String definiert.

Aber ein
Code: Alles auswählen
ShowMessage(Arbeitsverzeichnis+[Backslash]+Datei);

zeigt alles korrekt an.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon wp_xyz » 25. Aug 2017, 19:02 Re: LoadFromFile vom netzlaufwerk

Es muss mit einem Delay zu tun haben. In CopyFile passiert z.B. folgendes

Code: Alles auswählen
  TryCount := 0;
  While TryCount <> 3 Do Begin
    SrcHandle := LazFileUtils.FileOpenUTF8(SrcFilename, fmOpenRead or fmShareDenyWrite);
    if (THandle(SrcHandle)=feInvalidHandle) then Begin
      Inc(TryCount);
      Sleep(10);
    End
    Else Begin
      TryCount := 0;
      Break;
    End;
  End;
  If TryCount > 0 Then
  begin
    if ExceptionOnError then
      raise EFOpenError.CreateFmt({SFOpenError}'Unable to open file "%s"', [SrcFilename])
    else
      exit;
  end;

Das heißt: Es gibt drei Versuche, die Datei zu öffnen. Schlägt einer fehl, wird 10 ms gewartet und dann neu vesucht.

Andererseits macht der Constructor des TFileStream nur 1 Versuch:

Code: Alles auswählen
constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
 
begin
  FFileName:=AFileName;
  If (Mode and fmCreate) > 0 then
    FHandle:=FileCreate(AFileName,Mode,Rights)
  else
    FHAndle:=FileOpen(AFileName,Mode);
 
  If (THandle(FHandle)=feInvalidHandle) then
    If Mode=fmcreate then
      raise EFCreateError.createfmt(SFCreateError,[AFileName])
    else
      raise EFOpenError.Createfmt(SFOpenError,[AFilename]);
end;

Wenn du dir nun einen neuen Stream von TFileStream ableitest, bei dem diese drei Versuche und die kurze Verzögerung der Prozedur Copy in den Constructor eingebaut sind, müsste es doch gehen!
Zuletzt geändert von wp_xyz am 25. Aug 2017, 20:48, insgesamt 1-mal geändert.
wp_xyz
 
Beiträge: 2896
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 25. Aug 2017, 19:39 Re: LoadFromFile vom netzlaufwerk

Code: Alles auswählen
Datei := extractFilename(FileListBox1.FileName);

Was für ein Zweck erfüllt das "extractFileName" im ersten Post?

Wie sollte das LoadFromFile funktionieren, wen man die Pfad-Angabe weglöscht ?
Ausgenommen das Programm wurde im gleichen Ordner gestartet, bei welchem sich auch "Datei" befindet.
Oder man wechselt den Ordner mit "chdir".
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4343
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon gladio » 25. Aug 2017, 23:04 Re: LoadFromFile vom netzlaufwerk

Der Code aus dem ersten Post ist etwas zusammengestückelt.
Datei := extractFilename(FileListBox1.FileName);
steht eigentlich im OnClick von FileListBox.
Damit weise ich der String-Variablen 'Datei' den Dateinamen der aus der FileListe ausgewählten Datei zu.

Der Pfad dazu steht in der String-Variablen 'Arbeitsverzeichnis'.
Das Arbeitsverzeichnis wird aus einer Ini-datei ausgelesen und an die FileListBox übergeben.

Das passt so.
Ich arbeite gern mit aussagekräftigen Variablen. Das hält den Code leichter lesbar.
gladio
 
Beiträge: 100
Registriert: 21. Jun 2014, 05:15
Wohnort: Insel Rügen
OS, Lazarus, FPC: Win7/10-32/64 - Laz 1.8 Standard-Edition | 
CPU-Target: 32/64Bit
Nach oben

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Netzwerk



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron
porpoises-institution
accuracy-worried