Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Ich bastel gerade an einem Suchprogramm, das auch Netzwerk-Freigaben durchsuchen soll, die z.B. mit Caja eingebunden wurden. Dazu werden die Verzeichnisse mit opendir(), readdir() und closedir() abgearbeitet. Aber leider wird für alles was sich unterhalb von
/run/user/1000/gvfs/
befindet, als Typ DT_UNKNOWN erkannt. Die Programme ls und mc haben damit aber keine Probleme. Hat jemand eine Ahnung, warum readdir() hier den Spielverderber gibt?
|
ChickenLipsRfun2eat
Supporter
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12070
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Nein ☺
Schade. Aber der Link liefert Hinweise, die mein altes Buch: "Linux-UNIX-Programmierung" nicht liefert.
This is mainly done for performance reasons, because with some filesystems the file type is not stored in the directory itself.
und So, if you really need the d_type on a filesystem, which does not fill it properly, you will have to call (l)stat() explicitly.
Das ist recht umständlich, da stat() den vollen Pfadnamen haben will. Den muss ich dann jedesmal mühsam zusammenbauen. Aber ich werde das mal testen. Jetzt sieht es so aus, als wenn gvfs der Spielverderber ist.
|
ChickenLipsRfun2eat
Supporter
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12070
|
Habe ich auch so gelesen, ja. Vielleicht gibt es eine Alternative - oder muss es gvfs sein? Die ganzen Linuxformate scheinen ja gut unterstützt zu sein. Ich habe hier nur ext4 und aufm Handy btrfs, daher kann ich da auch nicht wirklich klagen. Was ich einbinde funktioniert wie lokal.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Vielleicht gibt es eine Alternative - oder muss es gvfs sein?
Es muss nicht unbedingt gvfs sein. Aber ich habe inzwischen etwas weiter gelesen. Das Problem ist wohl, wie die verschiedenen Systeme Netzwerk Dateisysteme in das Dateisystem einblenden. Dabei wird wohl vieles weg gelassen.
Ich habe hier nur ext4 und aufm Handy btrfs, ...
Mein Fileserver hat auch ext4, aber gvfs scheint dies nicht weiter geben zu wollen. Ich bin ja nicht auf ein bestimmtes System fixiert, aber ich will das meine Programme das nutzen können, was bereits da ist. Ich habe da jetzt mal, quasi als Hack, eine Sonderbehandlung eingebaut, die auch erstmal zu funktionieren scheint. Ist aber sehr umständlich, da für jedes erfolglose readdir() Ergebnis zusätzlich der absolute Pfad für die zusätzliche stat() zusammengebaut werden muss.
|
ChickenLipsRfun2eat
Supporter
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12070
|
Dakuan schrieb: Ich habe da jetzt mal, quasi als Hack, eine Sonderbehandlung eingebaut, die auch erstmal zu funktionieren scheint. Ist aber sehr umständlich, da für jedes erfolglose readdir() Ergebnis zusätzlich der absolute Pfad für die zusätzliche stat() zusammengebaut werden muss.
Da hast du Recht. Allerdings musst du ja sowieso eine Funktion für DT_UNKNOWN bereithalten. Hast du somit schon erledigt. Hast du mal in den Sourcecode von Frameworks reingeschnuppert, wie die das handhaben? Für mich ist das ein wenig zu "low", da kenne ich mich nicht mit aus. Ich nutze da die fertigen Lösungen aus der Tüte, wie bspw. unter Qt:QDir/QStandardPaths Ich weiß allerdings nicht, ob die auch mit gfvs umgehen können.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Wie andere das machen habe ich mir bisher noch nicht angesehen. Für mich ist das ein wenig zu "low", ...
So "low" ist das eigentlich gar nicht. Mit geht es hier um Geschwindigkeit, also auch darum, die Anzahl der Kopiervorgänge für die Strings zu minimieren. Auf einer externen USB-Platte hatte ich beim letzten Test 400822 Dateien. Auch wenn USB mich da etwas ausbremst, kommen da Zeiten zusammen, die man ohne Stoppuhr messen kann.
Ich weiß allerdings nicht, ob die auch mit gfvs umgehen können.
Eigentlich sollte es egal sein, wer da was wie (SMB,FTP,?) einbindet, solange die Dateien irgendwie im lokalen Dateisystem "abgebildet" werden. Ich muss dann nur noch wissen, wo das im Dateisystem auftaucht. Dazu wollte ich dann so etwas wie ein Alias (konfigurierbar) einbauen, damit der Benutzer nicht immer den kompletten Pfad eingeben muss. Der längste bisher gefundene Pfad ist:
/run/user/1000/gvfs/smb-share:server=lager1.local,share=homes/manfred/noten/aorg/6_Coney_Island_Cakewalk.mp3
Daraus sieht man dann auch, das die Nachbehandlung mit stat() funktioniert. An der Textaufbereitung muss ich aber noch arbeiten. Kannst Du mir vielleicht sagen, ob Qt die Freigaben auch so oder so ähnlich einbindet?
|
ChickenLipsRfun2eat
Supporter
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12070
|
Dakuan schrieb: Kannst Du mir vielleicht sagen, ob Qt die Freigaben auch so oder so ähnlich einbindet?
Offenbar gab es da auch schon Probleme mit → QTBUG-62096 Dort ist auch ein Beispielcode angehängt. Wie der Status ist kann ich aktuell nicht nachvollziehen. Falls du ein System mit installiertem qt hast, kannst du ja mal damit rumspielen. Ggf. findest du da den Unterschied zum aktuellen. Um Strings schneller zu kopieren, könntest du da nicht eine Kompression verwenden, ähnlich wie rsync das anbietet? Falls die Anwendung mobil laufen soll, wäre das auch fürs Datenvolumen interessant.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Der Beispielcode sieht irgendwie chaotisch aus - da werden C- und Qt- Dateifunktionen gemischt. Das würde ich mich nicht trauen, liegt aber vielleicht auch daran, das ich die Möglichkeiten der Qt Funktionen nicht kenne. Die interessante Information ist aber, das hier auch CIFS genutzt wird. Das sollte eigentlich problemlos gehen. Ich habe das gerade zuvor getestet indem ich mein NAS mal mittels CIFS und einem vorbereitetem Eintrag in /etc/fstab in ein Verzeichnis in meinem $HOME eingebunden hatte. In dem Fall kommt kein "unknown". Meine Anwendung sieht keinen Unterschied zu lokalen Dateien.
Um Strings schneller zu kopieren, könntest du da nicht eine Kompression verwenden, ...
Das wäre eine Sache desjenigen, der das Dateisystem einbindet. Ich meinte die Bearbeitung der Daten, wenn sie bereits auf meinem PC sind. Ich vermute mal, das auch komplexere Funktionen auf readdir() zurückgreifen. Diese Funktion liefert aber nur die Namen innerhalb des Verzeichnisses. Für den kompletten Pfad braucht man auch den Pfad zum Verzeichnis. Die beiden Strings kann man jedesmal zusammen kopieren. Ich habe das jetzt so zusammengefasst, dass in einem großen Puffer zum Prefix (Verzeichnis) nur noch der Dateiname angehängt wird. Was das bringt, kann ich momentan aber nicht messen, da die vielen debug Ausgaben zu viel Zeit benötigen. BTW. Messungen in so einem Umfeld sind auch nicht immer aussagekräftig. Wenn ich die ca. 400000 Dateien auf dem USB-Laufwerk erstmalig erfasse, dauert das ca. 16 Sekunden. Ein zweiter Lauf dauert ca. 1.5 sec. Wahrscheinlich hat dieser PC zu viel Speicher für solche Experimente. Ein anderer (älterer) PC braucht dafür 6 Minuten.
|
ChickenLipsRfun2eat
Supporter
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12070
|
Dakuan schrieb: Der Beispielcode sieht irgendwie chaotisch aus - da werden C- und Qt- Dateifunktionen gemischt. Das würde ich mich nicht trauen, liegt aber vielleicht auch daran, das ich die Möglichkeiten der Qt Funktionen nicht kenne.
Eigentlich sollte das kein Problem sein, man kann mit dem Qt-Framework in C und C++ arbeiten (und Python, Lua, Lisp,…). "Nativ" ist natürlich C++.
Die interessante Information ist aber, das hier auch CIFS genutzt wird. Das sollte eigentlich problemlos gehen. Ich habe das gerade zuvor getestet indem ich mein NAS mal mittels CIFS und einem vorbereitetem Eintrag in /etc/fstab in ein Verzeichnis in meinem $HOME eingebunden hatte. In dem Fall kommt kein "unknown". Meine Anwendung sieht keinen Unterschied zu lokalen Dateien.
Hilft dir das denn beim eigentlichen Problem irgendwie weiter? Du musst ja trotzdem das DT_UNKNOWN des gvfs abfangen. BTW. Messungen in so einem Umfeld sind auch nicht immer aussagekräftig. Wenn ich die ca. 400000 Dateien auf dem USB-Laufwerk erstmalig erfasse, dauert das ca. 16 Sekunden. Ein zweiter Lauf dauert ca. 1.5 sec. Wahrscheinlich hat dieser PC zu viel Speicher für solche Experimente. Ein anderer (älterer) PC braucht dafür 6 Minuten.
Ja, Messungen sind auch durch caching immer ungenau. Wenn ich was mit Dateisuche mache, lasse ich immer erst find laufen, um ne Zeitorientierung zu haben. Bin aber meist deutlich langsamer unterwegs, was bei meinen kleinen Tools aber egal ist.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6234
|
Hilft dir das denn beim eigentlichen Problem irgendwie weiter? Du musst ja trotzdem das DT_UNKNOWN des gvfs abfangen.
Ja schon, indem es meinen Blickwinkel erweitert hat. Und das DT_UNKNOWN Ergebnis von readdir() hatte ich ja durch
switch ...
...
default:
continue;
schon immer mit drin, nur das da nichts weiter gemacht wurde. Ich war einfach nicht darauf vorbereitet, das readdir() nicht immer funktioniert. Ich dachte das geht auf einem System immer komplett oder nie. Das es da Unterschiede gibt, ist mir in den letzten 10 Jahren nicht aufgefallen.
Ja, Messungen sind auch durch caching immer ungenau.
Und hängen auch von der Speicherausstattung ab. Mein alter PC kann da nicht viel cachen, weswegen ich den gerne als "worst case scenario" einsetze.
Bin aber meist deutlich langsamer unterwegs, was bei meinen kleinen Tools aber egal ist.
Ob Tools klein sind oder nicht, ist nicht entscheidend, sondern was sie machen und wie sie es machen. Wenn eine Script-Lösung für die Bearbeitung von 30.000 Dateien 30 Minuten benötigt, macht man sich Gedanken. Wenn eine alternative Lösung mit optimierten Programmen dann 400000 Dateien in 6 Minuten schafft, kann man nicht weit vom rechten Weg ab sein. Da es jetzt erstmal funktioniert, bin ich kurz davor, das Thema als gelöst zu markieren. Aber vielleicht meldet sich noch jemand, der mich darauf hinweist, das andere Freigaben noch wider anders eingebunden werden.
|