Textdatein nach Schlagwort am Zeilenanfang durchsuchen
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 84 Antworten in diesem Thema. Der letzte Beitrag () ist von Dksksm.
-
-
Dan sucht er mir die Dateien nicht raus und schreibt sie nicht in die Listbox.
Ich verzweifle fast, Arghhhh....:-)
Wäre einfacher ich könnte den Code den ich jetzt habe reinstellen, also über meinen Rechner.
Ich mach das auch so, später wenn ich zuhause bin poste ich mal das ganze ding und dann hat auch jeder nen Überblick.
Aber danke, eben hat es ja so funktioniert. auch viel schneller als den Code den ich zuvor hatte und mit der Progressbar gefällt mir auch sehr gut.
Hoffe kann den so anpassen dass es klappt.
vielen vielen Danke bis hier her schonmal
Wie gesagt, bin von der Nachtschicht zuhause und hier ist mein Code den ich bis jetzt habe:
VB.NET-Quellcode
- Private Sub Scanfiles(targetPath As DirectoryInfo, searchPattern As String)
- Dim fiALLFiles As FileInfo() = targetPath.GetFiles("*.dat", IO.SearchOption.AllDirectories)
- Dim containingFiles As New List(Of String)()
- ProgressBar1.Invoke(New MethodInvoker(Sub() ProgressBar1.Maximum = fiALLFiles.Length))
- For Each fi As FileInfo In fiALLFiles
- For Each line As String In File.ReadAllLines(fi.FullName)
- If line <> "" AndAlso line.TrimStart().StartsWith(searchPattern) Then
- containingFiles.Add(Path.GetFileNameWithoutExtension(fi.FullName))
- End If
- Next
- ProgressBar1.Invoke(New MethodInvoker(Sub() ProgressBar1.Increment(1)))
- Next
- ListBox21.Invoke(New MethodInvoker(Sub() ListBox21.Items.AddRange(containingFiles.ToArray())))
- End Sub
- Private Sub btnsuchenVS_Click(sender As Object, e As EventArgs) Handles btnsuchenVS.Click
- ListBox21.Items.Clear()
- Dim searchPattern As String = "75 " & txtsuchenVS.Text
- Dim scanThread As New System.Threading.Thread(Sub() Scanfiles(New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), Pfadprg21)), searchPattern))
- scanThread.Start()
- MsgBox(searchPattern)
- End Sub
Es funktioniert fast perfekt. Nur sollte er im String die Leerzeichen auch ignorieren. also das in searchPattern auch 7 Leerzeichen stehen könnten anstatt nur eins.
und wenn ich die anderen Listboxen fülle über andere Pfade ist die Progressbar ja schon fertig bis die Letzte Listbox gefüllt ist. Wie knüpfe ich denn die anderen da dabei?
Aber das ist eher nebensache, ist nicht wichtig, nur unschön.
Aber dass er mir die Leerzeichen im String auch verschieden setzt bzw. ignoriert ist unabdinglich.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gottric“ ()
-
Du musst das Progressbar.Value dort wo das Maximum der Progressbar gesetzt wird auf 0 stellen. Mit varablen Leerzeichen meinst du das zwischen 75 und dem Rest beliebig viele Leerzeichen stehen können?
Spoiler anzeigen
VB.NET-Quellcode
- Dim lineStartPattern As String = "75"
- Dim lineSearchPattern As String = textBox1.Text
- Dim fileSearchPattern As String = "*.txt"
- Dim scanThread As New System.Threading.Thread(Sub() ScanFiles(New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "testDir")), lineStartPattern, lineSearchPattern, fileSearchPattern))
- scanThread.Start()
VB.NET-Quellcode
- ''' <summary>
- ''' Sucht in allen Dateien mit der Dateiendung .dat nach Zeilen die mit den angegebenen Suchkreterien übereinstimmen
- ''' </summary>
- ''' <param name="targetPath">DirectoryInfo -Objekt das dass Verzeichniss repräsentiert in dem die Dateien durchsucht werden sollen</param>
- ''' <param name="lineStartPattern">Suchbegriff mit dem die Zeile beginnen muss</param>
- ''' <param name="lineSearchPattern">Suchbegriff der in der Zeile vorkommen muss</param>
- ''' <param name="fileSearchPattern">Suchbegriff für die Dateien die durchsucht werden sollen (DirectroyInfo.GetFiels searchPattern)</param>
- Private Sub ScanFiles(targetPath As DirectoryInfo, lineStartPattern As String, lineSearchPattern As String, fileSearchPattern As String)
- Dim fiAllFiles As FileInfo() = targetPath.GetFiles(fileSearchPattern, SearchOption.AllDirectories)
- Dim containingFiles As New List(Of String)()
- progressBar1.Invoke(New MethodInvoker(Function()
- progressBar1.Maximum = fiAllFiles.Length
- progressBar1.Value = 0
- End Function))
- For Each fi As FileInfo In fiAllFiles
- For Each line As String In File.ReadLines(fi.FullName)
- If line <> "" AndAlso line.TrimStart().StartsWith(lineStartPattern) Then
- If CheckLine(line, lineStartPattern, lineSearchPattern) Then
- containingFiles.Add(Path.GetFileNameWithoutExtension(fi.Name))
- End If
- End If
- Next
- progressBar1.Invoke(New MethodInvoker(Function() progressBar1.Increment(1)))
- Next
- listBox1.Invoke(New MethodInvoker(Function() listBox1.Items.AddRange(containingFiles.ToArray())))
- End Sub
- ''' <summary>
- ''' Prüft ob ein String mit dem enstprechenden Suchkretrium beginnt
- ''' </summary>
- ''' <param name="line">Zu prüfender String</param>
- ''' <param name="lineStartPattern">Suchbegriff mit dem die Zeile beginnen muss</param>
- ''' <param name="lineSearchPattern">Der Suchbegriff mit dem der String beginnen muss</param>
- ''' <returns>True wenn der String mit dem Suchbegriff beginnt, andernfalls false</returns>
- Private Function CheckLine(line As String, lineStartPattern As String, lineSearchPattern As String) As Boolean
- ' Entfernt alle Buchstaben am Anfang der Zeile von 0-LineStartPattern -Länge (In diesem Beispiel beträgt die Länge 2 da lineStartPattern 75 ist)
- line = line.Remove(0, lineStartPattern.Length)
- ' Nun wird wieder mit TrimStart jedes Leerzeichen am Anfang des strings entfernt und geprüft ob der string mit lineSearchPattern (== TextBox1.Text) beginnt ist dem so wird True zurück gegeben
- Return line.TrimStart().StartsWith(lineSearchPattern)
- End Function
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Fakiz“ ()
-
Danke dir.
aber jetzt entfernt er aus dem String nicht die Leerzeichen am Anfang der Zeile, obwohl .Trimstart angewendet wird. Alles andere passt von der Suche her.
und er zeigt er mir an dass was mit dem Aufruf der Funktion nciht stimmt. Ich müsste eine AS-Klausel
hinzufügen.
VB.NET-Quellcode
- Private Sub ScanFiles(targetPath As DirectoryInfo, lineStartPattern As String, lineSearchPattern As String, fileSearchPattern As String)
- Dim fiAllFiles As FileInfo() = targetPath.GetFiles(fileSearchPattern, SearchOption.AllDirectories)
- Dim containingFiles As New List(Of String)()
- ProgressBar1.Invoke(New MethodInvoker(Function()
- ProgressBar1.Maximum = fiAllFiles.Length
- ProgressBar1.Value = 0
- End Function))
- For Each fi As FileInfo In fiAllFiles
- For Each line As String In File.ReadAllLines(fi.FullName)
- line=line.replace(" ","")
- If line <> "" AndAlso line.TrimStart().StartsWith(lineStartPattern) Then
- If CheckLine(line, lineStartPattern, lineSearchPattern) Then
- containingFiles.Add(Path.GetFileNameWithoutExtension(fi.Name))
- End If
- End If
- Next
- ProgressBar1.Invoke(New MethodInvoker(Function() ProgressBar1.Increment(1)))
- Next
- ListBox21.Invoke(New MethodInvoker(Sub() ListBox21.Items.AddRange(containingFiles.ToArray())))
- End Sub
wenn ich in dem Code Funktion durch Sub ersetzt macht er es.
edit:
habe ich auch versucht, aber das ändert nichts an der Situatuion dass er mir nciht die Leerzeichen vor lineStartPattern entfernt.
jemand ne idee?
Edit 2:
Ich hatte das nur falsch gesetztz, hab es oben im Code auch angepasst.
so funktioniert es bestens. bis auf die Progressbar halt. Die läuft zwar aber endet nicht wenn das Prg. fertig ist sondern vorher schon.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gottric“ ()
-
Hallo Leute,
zum Abschluss noch einmal den fertigen Code, habe alle Probleme gelöst und eure Vorschläge umsetzten können auf meine Anwendung.
VB.NET-Quellcode
- Private Sub btnsuchen_Click(sender As Object, e As EventArgs) Handles btnsuchen.Click
- System.Threading.Thread.Sleep(100)
- If txtsuchen.TextLength = 4 Then
- If rbtn21.Checked = True Then
- ListBox21.Items.Clear()
- ProgressBar1.Value = 0
- Dim fInfo21 = New IO.DirectoryInfo(Pfadprg21).GetFiles("*.dat", IO.SearchOption.AllDirectories)
- ProgressBar1.Invoke(New MethodInvoker(Sub() ProgressBar1.Maximum = fInfo21.Length))
- For Each fi21 In fInfo21
- For Each line In IO.File.ReadAllLines(fi21.FullName)
- Dim parts = line.Split(New Char() {}, StringSplitOptions.RemoveEmptyEntries)
- line = line.Replace(" ", "")
- If line.StartsWith("75" & txtsuchen.Text) Then
- ListBox21.Items.Add(fi21.Name.Replace(fi21.Extension, ""))
- Exit For
- End If
- Next
- ProgressBar1.Invoke(New MethodInvoker(Sub() ProgressBar1.Increment(1)))
- Next
- End If
Thema kann geschlossen werden. -
Die Benennung solltest du nochmal überarbeiten.
Ich habe einen interessanten Link dazu in Beitrag 24 gepostet.
Das Thema kannst du selbst erledigt markieren, doppelklicke das kleine rote Viereck, rechts neben dem Threadtitle.
-
-
Ich habe deine code mal überarbeitet und kommentiert:
Spoiler anzeigen VB.NET-Quellcode
- ' Das ganze im Button.Click Event zu erledigen ist unflexibel ! Daher das ganze als eigenständige Methode.
- Private Sub SearchText(ByVal text As String)
- ' System.Threading.Thread.Sleep(100)
- ' Mehr als redundant. ^^
- ' If txtsuchen.TextLength = 4 Then
- ' If rbtn21.Checked = True Then
- ' "= True" ist redundant, "If RadioButton1.Checked" bedeutet schon Ist Gecheckt", für die Abfrage ungecheckt, dann "If Not RadioButton1.Checked" nutzen.
- If TextBoxSearchPattern.TextLength = 4 AndAlso RadioButton1.Checked Then
- ' Beide If Blöcke können zusammengefast werden.
- ListBoxSearchTextResult.Items.Clear()
- ProgressBarSearchText.Value = 0
- Dim files = New IO.DirectoryInfo(text).GetFiles("*.dat", IO.SearchOption.AllDirectories)
- ProgressBarSearchText.Invoke(New MethodInvoker(Sub() ProgressBarSearchText.Maximum = files.Length))
- For Each fi In files
- ' For Each "Datatype FileInfo", sollte auch sofort erkennbar sein, daher "fi" als Variablenname.
- For Each line In IO.File.ReadAllLines(fi.FullName)
- ' Hier ist es ähnlich, da hier die Methode .ReadAllLines verwendet wird, sollte auch das sofort erkennbar sein.
- 'Dim parts = line.Split(New Char() {}, StringSplitOptions.RemoveEmptyEntries)
- ' Redundant.
- line = line.Replace(" ", "")
- If line.StartsWith("75" & text) Then
- ListBoxSearchTextResult.Items.Add(fi.Name.Replace(fi.Extension, ""))
- Exit For
- End If
- Next
- ProgressBarSearchText.Invoke(New MethodInvoker(Sub() ProgressBarSearchText.Increment(1)))
- Next
- End If
- End Sub
- Private Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
- SearchText(TextBoxSearchPattern.Text)
- End Sub
Was das benennen betrifft, wirst du deine eigenen Stil entwickeln.
Ich z.B. schreibe alles aus (z.B.ButtonClose
), man kann aber auch abkürzen (z.B.btnClose
), wird in den offiziellen Richtlinien sogar empfohlen.
PS: Ist dir der Vorschau Button, noch nicht aufgefallen, du hast schon wieder einEnd Sub
verschluckt !? -
Gottric schrieb:
Thema kann geschlossen werden.
Du liest alle Zeilen der Datei sofort einReadAllLines
- da wäre es schon besser, du liest sie einzeln hintereinander einReadLines
.
Wenn du da bei einer Zeile fündig geworden bist, kannst du sofort aus der Schleife springen - das bringt dir sicher Performance...
Wie schon gesagt: richtige Benennung der Controls etc. -
Hallo, ich wollte dieses Thema wieder aufgreifen um meine Anwendung schneller zu machen.
Vom logischen her macht es ja sinn nicht die komplette Textdatei immer einzulesen.
wie bewerkstellige ich es denn dass die suche abgebrochen wird nach dem er in einer Datei den gesuchten Begriff gefunden hat?
Wenn ich es in ändere sagt er mir ReadLines wäre kein Member von File.
das ist der feritge Code der auch wie gewünscht funktioniert. nur halt sehr langsam für meine Begriffe.
VB.NET-Quellcode
- If rbtn21.Checked = True Then
- ListBox21.Items.Clear()
- ProgressBar1.Value = 0
- Dim fInfo21 = New IO.DirectoryInfo(Pfadprg21).GetFiles("*.dat", IO.SearchOption.AllDirectories)
- ProgressBar1.Maximum = fInfo21.Length
- For Each fi21 In fInfo21
- For Each line In IO.File.ReadAllLines(fi21.FullName)
- line = line.Replace(" ", "")
- If line.StartsWith("75" & txtsuchen.Text) Then
- ListBox21.Items.Add(fi21.Name.Replace(fi21.Extension, ""))
- Exit For
- End If
- Next
- ProgressBar1.Increment(1)
- Next
- If ListBox21.Items.Count() = 0 Then
- ListBox21.Items.Add("Prg. nicht verwendet!")
- End If
- End If
Vielleicht hat ja jemand ne Idee?
Danke -
Geschwindigkeit ist immer relativ. Wieviel Dateien in welcher Zeit werden verarbeitet?
Multithreading könnte hier noch was an Zeit raus holen. Hab mal was ähnliches gemacht. Mit Multithreading wars 50% schneller (hab's gemessen)."Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."
Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
Wie man VisualStudio nutzt? => VisualStudio richtig nutzen -
Auf meinem Rechner zuhause brauche ich für einen Suchlauf durch ca. 3000 Textdatein mit je 5- manchmal auch 200 Zeilen(ist von Datei zu Datei unteschiedlich) ungefähr 10sec. auf der Arbeit, wo ich das Tool eigentlich brauche, dauert es über das Netzwerk wo es zugreift schonmal bis zu 40sec. kann natürlich auch am Netzwerk liegen. ist nicht das schnellste
-
Gottric schrieb:
(...)bis zu 40sec. kann natürlich auch am Netzwerk liegen(...)
Naja, ~10 sec lokal find ich jetzt nicht sonderlich tragisch. Immerhin müssen 3000 Dateien geöffnet und geprüft werden. Übers Netzwerk ist halt langsamer da weißte ja woher das kommt.
Wie gesagt, Multithreading hat bei mir bei ähnlichem Vorhaben eine Zeitersparnis gebracht von 15 auf 7 Minuten runter"Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."
Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
Wie man VisualStudio nutzt? => VisualStudio richtig nutzen -
Gottric schrieb:
machst DuFalls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
@RodFromGermany
wie ich in post 70 schon geschrieben habe sagt er mir ReadLines ist kein Member von File. Das hatt ich natürlich schon versucht.
aber wenn @mrMo sagt das der zeitaufwand gerechtfertigt, bzw. I.O. ist für das was er zu leisten hat. hat sich das ganze Thema ja geklärt. es funktioniert ja alles wie es soll. dachte nur mein Code wäre was falsch weil es halt 10sec. dauert.
trotzdem danke für eure hilfe -
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
Gottric schrieb:
Bei mir nicht. hab auch ein Foto gemacht wie du, aber kann es irgendwie nicht hochladen.
Sollte kein Problem sein wenn Du aufErweiterte Antwort
klickst.
Schau Dir das mal an: msdn.microsoft.com/en-us/libra…em.io.file(v=vs.110).aspx und spiele die Framework-Versionen durch. -
-
Benutzer online 1
1 Besucher
-
Ähnliche Themen
-
Stream nach bestimmter bytekette durchsuchen
Gelöschter Benutzer - - Sonstige Problemstellungen -
Liste von Textdatein erstellen
AintLarry - - Sonstige Problemstellungen