German "Platzhalter" bei Suche nach einer Datei

JOTHA

Well-Known Member
Licensed User
Longtime User
Hallo Community,

ich habe ein kleines Problemchen und experimentiere schon eine Weile daran herum ... vielleicht kann mir jemand kurz auf die Sprünge helfen:

Ich möchte in einem Verzeichnis nachschauen, ob dort eine XML-Datei liegt. Das hier funktioniert ...
B4X:
If File.Exists(File.DirRootExternal, "70283359.xml") = False Then
... aber nur dann, wenn die Datei auch "70283359.xml" heißt.

Was mache ich aber, wenn die Datei anders heißt und ich das vorher nicht weiß?

Ich habe es mit Platzhaltern (% oder *) probiert, aber nichts klappt bisher.
Weiß jemand weiter?
 

klaus

Expert
Licensed User
Longtime User
Ich denke dass das vom Prizip her nicht möglich ist.
Um zu wissen ob eine Datei existiert muss sie einzig sein.
Die Lösung könnte diese sein:
B4X:
Dim lst As List
lst = File.ListFile(Order)
For i = 0 To lst.Size - 1
    If lst.Get(i).Contains(".xml") Then
        ' Dein Code
    End If
Next
Hab es nicht getestet.

Beste Grüsse.
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Hallo Klaus,
danke für deine Antwort.

Zu deinem Kommentar:
Ich denke dass das vom Prizip her nicht möglich ist.
Um zu wissen ob eine Datei existiert muss sie einzig sein.
Es geht NICHT darum eine einzige "Unique"-Datei zu finden, sondern nur darum zu prüfen, ob sich im Root-Ordner IRGENDEINE XML-Datei befindet oder nicht.

Deinen Code habe ich getestet.
Dabei hatte ich prompt schon eine erste Fehlermeldung:
Error description: Undeclared variable 'order' is used before it was assigned any value.
lst = File.ListFile(Order)
Ich habe das "Order" durch "" ersetzt, dabei ist mir aufgefallen, dass
File.ListFile
eigentlich

File.ListFiles

heißen müsste, oder?

Dann kam als nächstes beim Compilen wieder die nächste Fehlermeldung:
Error description: Unknown member: contains
If lst.Get(i).Contains(".xml") Then
Word: contains
... also müsste ich jetzt das "Contains" ... ???

Meinst Du nicht, dass ich bei meinen ursprünglichen Zeilen so etwas wie
B4X:
If File.Exists(File.DirRootExternal, "%.xml") = False Then
einsetzen könnte, eben nur als "Platzhalter" ?
 

klaus

Expert
Licensed User
Longtime User
Es geht NICHT darum eine einzige "Unique"-Datei zu finden, sondern nur darum zu prüfen, ob sich im Root-Ordner IRGENDEINE XML-Datei befindet oder nicht.
So hatte Ich es auch verstanden. Ich habe mich leider nicht richtig ausgedrückt.
Was Ich meinte ist dass man mit File.Exists nur eine einzige bestimmte Date abfragen kann.

Diese Routine funktioniert, hab sie getestet.
B4X:
'Checks if files with the given Extension exist in the given Folder.
'Returns the number of files
Sub FileTypeExists(Folder As String, Extension As String) As Int
   Dim n = 0 As Int
   Dim lst As List
   Dim fl As String
   lst = File.ListFiles(Folder)
   For i = 0 To lst.Size - 1
     fl = lst.Get(i)
     If fl.ToLowerCase.Contains(Extension) Then
       n = n + 1
     End If
   Next
   Return n
End Sub
Mit dieser Routine kann man nach einem bestimmten Inhalt im Dateinamen suchen.
 
Last edited:

JOTHA

Well-Known Member
Licensed User
Longtime User
Danke Klaus! :)

Im vorigen stand statt "Ordner" das Wort "Order" und da dachte ich eben gleich an was anderes. Ich habe jetzt anstatt "Ordner" natürlich "File.DirRootExternal" eingesetzt und schon funkioniert es ... fast ...

Leider taucht noch ein weiteres Problem auf. Wenn ich jetzt folgendes mache ...
B4X:
Dim n = 0 As Int
Dim lst As List
Dim fl As String
lst = File.ListFiles(File.DirRootExternal)
For i = 0 To lst.Size - 1
  fl = lst.Get(i)
  If fl.Contains(".xml") Then
  n = n + 1
  ToastMessageShow("Es sind folgende "&n&" Dateien vorhanden: "&lst.Get(i)&" ", False)
    End If
Next
Return n
... dann sieht man in der "ToastMessageShow", das ich 3 XML-Dateien habe, die er dann auch 3 mal durchliest und 3 mal anzeigt.
Wenn ich jetzt anstelle der "ToastMessageShow" einen Code einsetze, dann würde dieser auch 3 mal ausgeführt, bei 30 XML-Dateien wäre das dann 30 mal den Code ausführen, oder sehe ich das falsch?

Wie könnte ich also erreichen, das der Code nur 1 x ausgeführt wird?

P.S.: Gibt es denn auch eine Möglichkeit wie ich die gefundenen XML-Dateien durchzählen kann, um dann die "3" irgendwo als Info hinschreiben zu können? ;)
 

klaus

Expert
Licensed User
Longtime User
Im vorigen stand statt "Ordner" das Wort "Order" ...
Das war leider ein Schreibfehler.

Was genau willst Du machen ?
Du kannst eine zweite List benutzen :
B4X:
Dim lst0, lst1 As List
Dim fl As String

lst1.Initialize
lst0 = File.ListFiles("/Removable/MicroSD/MP3")
For i = 0 To lst0.Size - 1
    fl = lst0.Get(i)
    If fl.ToLowerCase.Contains("mp3") Then
        lst1.Add(fl)
    End If
Next
Und mit der machen was Du brauchst.
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Was genau willst Du machen ?

1) Ich speichere mehrere XML-Dateien in den Root-Ordner
2) dann lese ich die XML-Dateien nach und nach per Hand ein
3) irgendwann gibt es keine XML-Dateien mehr ... aber ich weiß das nicht vorher ... deshalb kommt dann eine Fehlermeldung:
"...java.io.FileNotFoundException: ... (no such file or directory)"

Um diese Fehlermeldung zu umgehen, möchte ich einfach vorher in der directory nachschauen lassen, ob sich dort noch irgendeine XML-Datei befindet, oder der Vorgang einfach noch vor der obigen Fehlermeldung abgebrochen werden kann.

Schön wäre es auch, wenn ich vorher die Anzahl der dort befindlichen XML-Dateien ermitteln könnte - als Vorab-Info - denn bei einem "0"-Ergebnis starte ich diese Aktion erst gar nicht.
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Im Code den Ich gepostet habe bekommst Du mit lst1.Size die Anzahl der xml Dateien.

Vielen Dank Klaus!
Jetzt mache ich es einfach anders:
Erst die Anzahl der XML-Dateien ermitteln, und nur wenn eine Zahl höher als "0" drinsteht, die Aktion starten.

So geht es viel einfacher!
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Hallo Klaus,
Problem:
... bekommst Du mit lst1.Size die Anzahl der xml Dateien.
Wenn dort 1 oder mehr Dateien stehen, funktioniert es, aber wenn dort keine Datei (also "0") vorhanden ist, dann gibt mir lst1.size auch keine Zahl zurück.

Ich hätte jetzt den Wert "0" erwartet ...
 

DonManfred

Expert
Licensed User
Longtime User
B4X:
Sub Button_Click
    Log(ScanRoot(".csv")&" Dateien gefunden")
End Sub
Sub ScanRoot(filter As String)
    Dim n = 0 As Int
    Dim lst As List
    Dim fl As String
    lst = File.ListFiles(File.DirRootExternal)
    For i = 0 To lst.Size - 1
      fl = lst.Get(i)
      If fl.Contains(filter) Then
          n = n +1
            Log("Datei gefunden: "&fl)
            'ToastMessageShow("Es sind folgende "&n&" Dateien vorhanden: "&lst.Get(i)&" ", False)
      End If
    Next
    Return n
End Sub
 

JOTHA

Well-Known Member
Licensed User
Longtime User
B4X:
ANZAHL_der_XML_Dateien.Text = lst1.Size
Da müsste doch auch eine "0" stehen, oder liegt es daran, dass es ein "EditText"-Feld ist?
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Hallo Manfred,

sieht auf den ersten Blick sehr interessant aus! Vielen Dank!

Leider muss ich mich aber jetzt ausloggen ... mache gleich morgen früh weiter ... muss noch eine Verabredung einhalten und bin jetzt schon zu spät!
Also nochmals Danke an euch beide, Klaus und Manfred!
 
D

Deleted member 103

Guest
Hallo Jürgen,

wenn explizit nach XML-Dateien suchst dann ändere den Code von Manfred so:
B4X:
Sub Button_Click
    Log(ScanRoot(".csv")&" Dateien gefunden")
End Sub
Sub ScanRoot(filter As String) As Int
    Dim n = 0 As Int
    Dim lst As List
    Dim fl As String
    lst = File.ListFiles(File.DirRootExternal)
    For i = 0 To lst.Size - 1
      fl = lst.Get(i)
      'If fl.Contains(filter) Then
      If fl.EndsWith(filter) Then
          n = n +1
            Log("Datei gefunden: "&fl)
            'ToastMessageShow("Es sind folgende "&n&" Dateien vorhanden: "&lst.Get(i)&" ", False)
      End If
    Next
    Return n
End Sub
 
Last edited by a moderator:

DonManfred

Expert
Licensed User
Longtime User
Hallo Jürgen,

wenn explizit nach XML-Dateien suchst dann ändere den Code von Manfred so:

FALSCH! Ich habe genau für diese möglichkeit einen Filter eingebaut. Wieso sollte man den nun verwerfen? Wenn er das nun so ändern würde dann würde er sich später wundern warum der übergebene Parameter (".zip") von ScanRoot nicht verwendet wird...

B4X:
Sub Button_Click
    Log(ScanRoot(".XML")&" Dateien gefunden") ' HIER muss die andere Extension verwendet werden!
End Sub
Sub ScanRoot(filter As String) As Int
    Dim n = 0 As Int
    Dim lst As List
    Dim fl As String
    lst = File.ListFiles(File.DirRootExternal)
    For i = 0 To lst.Size - 1
      fl = lst.Get(i)
      If fl.Contains(filter) Then
          n = n +1
            Log("Datei gefunden: "&fl)
            'ToastMessageShow("Es sind folgende "&n&" Dateien vorhanden: "&lst.Get(i)&" ", False)
      End If
    Next
    Return n
End Sub

Der Vorteil der Sub ScanRoot ist ja eben, das man die Sub für verschiedene Extensions nutzen kann...

Beispiel:
B4X:
Sub Button_Click
    Log(ScanRoot(".XML")&" XML-Dateien gefunden")
    Log(ScanRoot(".csv")&" CSV-Dateien gefunden")
    Log(ScanRoot(".zip")&" Archive gefunden")
End Sub
 
Last edited:
D

Deleted member 103

Guest
@Manfred
FALSCH! Ich habe genau für diese möglichkeit einen Filter eingebaut. Wieso sollte man den nun verwerfen? Wenn er das nun so ändern würde dann würde er sich später wundern warum der übergebene Parameter (".zip") von ScanRoot nicht verwendet wird...
Es ist nicht Falsch!
Ich wollte nur sagen dass man das fl.Contains mit fl.EndsWith austauschen sollte, und nicht mehr.
Sonst ist deine Procedur für diesen Zweck genau richtig.
 

DonManfred

Expert
Licensed User
Longtime User
Das mit dem austauschen, ok. Ist mir so spontan aber gar nicht aufgefallen.;)

Nur dass Du den Filter eben durch einen festen Code ausgetauscht hast (Filter -> ".xml"). Und das habe ich als "Fehler" angesehen weil ich in der von mir geposteten sub eben genau dieses Feature eingebaut habe damit man beim Aufruf der Sub den Extender übergeben kann. Du hast dieses Feature entfernt indem Du da wieder fest ein ".xml" eingebaut hattest...

Du hättest konsequenterweise den Sinn des Funktionsaufrufes nicht zerstören sondern nutzen können. :)
 
D

Deleted member 103

Guest
So, damit es keine Missverständnisse mehr gibt habe ich meine Änderung korrigiert.
 
Top