| |
VB.NET - Ein- und UmsteigerDatei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 25.02.17 10:40 |
| Hallo Community,
ich habe eine sehr große txt Datei ( 1,7 Mio Zeilen), und dadurch auch ein sehr großes Problem.
Die Datensicherung hat alle meine Daten in eine txt Datei gespeichert.
Die txt sieht folgendermaßen aus.
http://pastebin.com/XrF17NRK
Die Datei soll nach jedem [HAUPTPROGRAMM]=234567 getrennt werden mit den Dateinamen von
PG_BEZEICHNUNG=PpD 93
Hat hier vielleicht jemand eine Ahnung wo sowas funktioniert ?
Tschö | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 25.02.17 18:46 |
| Hallo!
Du willst NACH jedem [HAUPTPROGRAMM] trennen?
Die Zahl hinter Hauptprogramm scheint - Deinen Angaben gemäß - zu variieren?
Du verwendest einen "IO.StreamReader" zum Lesen der Zeilen per "Readline"-Methode.
Operationen für jede Zeile (While-Schleife bis EndOfStream):
Die gelesenen Zeilen speicherst Du per Add-Methode in einer List(of String).
- Falls die zuletzt gelesene Zeile die Zeichenfolge PG_Bezeichnung enthält,
merkst Du Dir den dort angegebenen Datei-Namen (String.Split).
- Falls die zuletzt gelesene Zeile die Zeichenfolge HauptProgramm enthält,
schreibst du per "WriteAllLines"-Methode die Zeilen in der List(of String)
in eine Datei, die den oben ermittelten Namen (+ Pfadangabe) erhält.
Die List(of String) wird nach dem Schreiben jeweils geleert (Clear).
Nach dem Lesen aller Zeilen (EndOfStream) müssen die eventuell noch in der
List(of String) vorhandenen Zeilen gespeichert werden.
Beitrag wurde zuletzt am 25.02.17 um 18:59:50 editiert. | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 25.02.17 19:10 |
| Hi,
stimmt die Zahl hinter Hauptprogramm variiert.
Und der Name hinter PG_BEZEICHNUNG ist auch jedes mal anders.
Das mit dem IO.StreamReader habe ich jetzt schon mehrmals gelesen.
Leider habe ich es nach 3 Std. heute immer noch nich hinbekomen.
Bin mittlerweile am manuellen aufteilen. 1 Prozent fertig
Vielleicht kann mir jemand das ganze noch an ein paar Zeilen verdeutlichen.
Ich bekomme es leider nicht hin.
Mach dann mal weiter mit Strg C und Strg V
Bis dann .... | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 25.02.17 19:41 |
| So oder ähnlich ...
Private Sub SplitFile()
Dim lines As New List(Of String), line As String = ""
Dim outpath As String = "C:\daten", outfile As String = "" 'Zielpfad
Using sr As New IO.StreamReader("C:\Daten\splitfile.txt") 'Datendatei
While Not sr.EndOfStream
line = sr.ReadLine
lines.Add(line)
If line.StartsWith("PG_Bezeichnung".ToUpper) Then
Dim filename As String = _
line.Substring(line.IndexOf("=") + 1) & ".txt"
outfile = IO.Path.Combine(outpath, filename)
End If
If Not outfile = "" Then
If line.StartsWith("[Hauptprogramm]".ToUpper) Then
IO.File.WriteAllLines(outfile, lines)
lines.Clear()
outfile = ""
End If
End If
End While
End Using
If Not lines.Count = 0 And Not outfile = "" Then
IO.File.WriteAllLines(outfile, lines)
End If
End Sub Man könnte noch Sicherheitsabfragen einfügen
- Ist eine Ausgabedatei bereits vorhanden?
- Fehlt die Angabe PG_Bezeichnung im Block?
- Werden zu viele Lines pro Block gespeichert?
- u.a.
Beitrag wurde zuletzt am 25.02.17 um 19:44:38 editiert. | |
Re: Datei aufteilen und umbenennen | | | Autor: eierlein | Datum: 25.02.17 20:09 |
| Hier noch ein vbs Beispiel.
Z. B. Splitdatei.vbs
Dim t, Datei, DateiNeu, Pfad, b, d
Datei = "original.txt" '<--- anpassen
Pfad = "d:\#1\" '<--- dein Pfad "\" am Ende!
b = False
b1 = True
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.OpenTextFile(Pfad & datei, 1)
Do Until File.AtEndOfStream
t = File.ReadLine
If Left(t, 15) = "[HAUPTPROGRAMM]" And b1 Then
b1 = False
tmp = ""
End If
If Not b Then
tmp = tmp & t & vbCrLf
If Left(t, 14) = "PG_BEZEICHNUNG" Then
d = Mid(t,InStrRev(t,"=")+1)
b = True
Set FileNeu = FSO.OpenTextFile(Pfad & d & ".txt", 2, True)
fileneu.Write tmp
End If
ElseIf Left(t, 15) = "[HAUPTPROGRAMM]" And b Then
b = False
fileNeu.close
tmp = ""
tmp = tmp & t & vbcrlf
Else
fileneu.WriteLine t
End If
Loop
MsgBox "Fertig"
fileNeu.Close
file.close | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 26.02.17 08:29 |
| Hallo,
die Lösung von Manfred funktioniert super.
Habe nur noch
filename = filename.Replace(".", "_")
filename = filename.Replace("/", "&")
filename = filename & ".txt" hinzugefügt
Danke für deine Hilfe Manfred. Ich habe meine Daten wieder
Mir ist nur noch aufgefallen das die ä,ü,ö durch Fragezeichen ersetzt werden. Das ist nicht schlimm, aber mich würde interessieren warum das so ist.
Und gibt es eine Möglichkeit einen Punkt und einen Schrägstrich in einem Dateinamen zu verwenden ?
Gruß | |
Re: Datei aufteilen und umbenennen | | | Autor: eierlein | Datum: 26.02.17 13:12 |
| Die Probleme mit den Umlauten hättest du bei meinem Code nicht.
Aber mit der Encoding Angabe klappt's auch bei Manfreds Code:
...
Using sr As New IO.StreamReader("d:\#1\test.txt", System.Text.Encoding.Default) _
'Datendatei
...
IO.File.WriteAllLines(outfile, lines, System.Text.Encoding.Default)
...
IO.File.WriteAllLines(outfile, lines, System.Text.Encoding.Default) Ohne Encoding-Angabe verwendet .net UTF-8.
Übrigens: Bei meinem Programm steht [HAUPTPROGRAMM]=234xxx immer in der ersten Zeile. | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 26.02.17 15:03 |
| Hi eierlein,
danke für deine Hilfe, jetzt klappt das auch mit den ä,ü und ö´s
Da jetzt meine Wochenendaufgabe geschafft ist, kann ich noch a bisschen damit rumspielen.
Hab mir jetzt noch ausn Web ein Stück Code gesucht damit ich die Zeilenanzahl bestimmen kann gesucht.
Würde noch gerne eine Progressbar einbauen, damit man sieht wie Weit das Programm mit dem Schreiben ist.
Hier mal das ganze:
Public Class Form1
Dim pfad
Dim Lines As String
Dim LineCount As Integer
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles _
Button2.Click
OpenFileDialog1.Filter = "txt Dateien (*.txt)| *.txt"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
TextBox1.Text = OpenFileDialog1.FileName
pfad = System.IO.Path.GetDirectoryName(OpenFileDialog1.FileName) & _
"\Ausgepackt\"
If Not IO.Directory.Exists(pfad) Then
IO.Directory.CreateDirectory(pfad)
TextBox2.Text = pfad
Else
IO.Directory.CreateDirectory(pfad)
TextBox2.Text = pfad
End If
Dim Lines As String() = My.Computer.FileSystem.ReadAllText( _
TextBox1.Text, System.Text.Encoding.Default).Split(vbCr)
Dim LineCount As Integer = Lines.Length
Label3.Text = LineCount & "Zeilen"
End If
End Sub
Private Sub SplitFile()
Dim lines As New List(Of String), line As String = ""
Dim outpath As String = pfad, outfile As String = "" 'Zielpfad
Using sr As New IO.StreamReader(OpenFileDialog1.FileName, _
System.Text.Encoding.Default) 'Datendatei
While Not sr.EndOfStream
line = sr.ReadLine
lines.Add(line)
If line.StartsWith("PG_BEZEICHNUNG".ToUpper) Then
Dim filename As String = line.Substring(line.IndexOf("=") + _
1) '& ".txt"
filename = filename.Replace("..", " ")
filename = filename.Replace("/", "&")
filename = filename & ".txt"
outfile = IO.Path.Combine(outpath, filename)
End If
If Not outfile = "" Then
If line.StartsWith("[HAUPTPROGRAMM]".ToUpper) Then
IO.File.WriteAllLines(outfile, lines)
'lines.Clear()
outfile = ""
End If
End If
End While
End Using
If Not lines.Count = 0 And Not outfile = "" Then
IO.File.WriteAllLines(outfile, lines, System.Text.Encoding.Default)
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles _
Button1.Click
SplitFile()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.SelectedIndex = 0
End Sub
Public Function FileLineCount(ByVal Filename As String) As Integer
Dim Lines As Integer = 0
Using oStream As New IO.FileStream(Filename, IO.FileMode.Open, _
IO.FileAccess.Read)
' Blockgröße
Dim BlockSize As Integer = 16384
Dim Bytes(BlockSize) As Byte
Dim ReadSize As Integer
Dim StartIndex As Integer
' Datei blockweise auslesen, bis Dateiende erreicht
Do
ReadSize = oStream.Read(Bytes, 0, BlockSize)
' Anzahl Zeilenumbruchzeichen ermitteln
StartIndex = -1
Do
StartIndex = Array.IndexOf(Bytes, CByte(13), StartIndex + _
1, ReadSize - StartIndex)
If StartIndex >= 0 Then Lines += 1
Loop Until StartIndex < 0
Loop Until ReadSize = 0
oStream.Close()
End Using
Return Lines
End Function
End Class Wie bzw wo müsste ich bei der Progressbar erhöhen damit er mitzählt ?
Könnte ich LineCount verwendun um die 100 Prozent zu bestimmen ?
Leider ist in youtube nur ein Beispiel der mit einen Timer arbeitet, das ist für mich wohl unbrauchbar.
Morgen werden Bücher gekauft ....
Gruß | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 26.02.17 16:02 |
| Hallo!
Um den Fortschritt anzeigen zu können, müßtest Du zunächst die
gesamte Datei einmal durchlesen, um die Zahl der Zeilen zu ermitteln.
Schneller geht es durch eine Abschätzung:
Geschätzte Zeilenzahl = Gesamt-Länge der Datei in Bytes / mittlere Länge einer Zeile in Bytes
Schau dir mal die Backgroundworker-Klasse an.
Damit ist es möglich, die Split-Operation im Hintergrund auszuführen
und per Invoke den Fortschritt (bereits gelesene Zeilen / Gesmtzahl-Zeilen)
in einer Progressbar anzuzeigen. Beispiele findest Du in den VbArchiv-Tipps & Tricks. | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 27.02.17 21:25 |
| Hallo,
leider habe ich mich zu früh gefreut
Beim genaueren hinschauen habe ich jetzt bemerkt, das es ganz wichtig ist das in der ersten Zeile
[HAUPTPROGRAMM]= mit der dazugehörigen Nummer steht.
Bei der jetzigen Lösung lässt er diese Zeile weg, und fängt mit PG-ID_Inc an,
und hängt am ende der Datei [HAUPTPROGRAMM]= von der nächsten Datei an.
Weis bitte noch jemand man das hinbekommt ?
und Helau | |
Re: Datei aufteilen und umbenennen | | | Autor: eierlein | Datum: 27.02.17 22:26 |
| Weis bitte noch jemand man das hinbekommt ?
Siehe meinen Beitrag vom 26.5. 13:12 letzte Zeile.
Beitrag wurde zuletzt am 27.02.17 um 22:27:57 editiert. | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 28.02.17 00:44 |
| Du hattest ausdrücklich angefordert, daß NACH [Hauptprogramm] ....
getrennt werden soll und meine diesbezügliche Nachfrage ignoriert !!!
Füge zwei Zeilen in den Code ein:
If Not outfile = "" Then
If line.StartsWith("[Hauptprogramm]".ToUpper) Then
lines.RemoveAt(lines.Count - 1) 'Zeile am Ende entfernen
IO.File.WriteAllLines(outfile, lines)
lines.Clear()
lines.Add(line) 'Zeile an den Anfang der neuen Liste
outfile = ""
End If
End If | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 28.02.17 08:44 |
| Hi,
danke für eure Hilfe. Ich finde das vbs Script von eierlein auch klasse, leider kann ich mit vbs rein garnichts anfangen.
Hallo Manfred. Ich habe dich nicht bewusst ignoriert. Ich bin heilfroh das du mir hilfst. Leider bin ich ein richtiger Anfänger, und weis teilweise nicht einmal wie ich mich richtig ausdrücken muss
Das Grundlagenbuch ich auch schon bestellt. Aber die gute alte Schneckenpost ....
Ich weis das es Manfred schon erklärt hat mit der Progressbar. Leider scheitert es noch der Umsetzung.
Mich würde es nur noch mal interessieren wie sowas funktioniert, und leider ist aller Anfang schwer ....
Nochmals besten Dank, und schöne Grüße | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 28.02.17 13:14 |
| Wie erwähnt, setzt die Verwendung einer Progressbar voraus,
daß zu Beginn einer längeren Operation bereits bekannt ist,
welche Info-Menge zu bearbeiten ist (z.B. Gesamtzahl der Zeilen
oder Anzahl der zu erstellenden Teil-Dateien).
In Deinem Fall wäre es eventuell zweckmäßig, eine entsprechende Schätzung
vorzunehmen (siehe oben).
Als eine einfache Alternative für das Sichtbarmachen des Fortschritts,
könnte - bei jeder Ausgabe in einer Datei - ein Zähler hochgesetzt und
in einem Label die Zahl der bereits erstellten Teil-Dateien angezeigt
werden. | |
Re: Datei aufteilen und umbenennen | | | Autor: Pokevib | Datum: 28.02.17 14:27 |
| Hallo,
die Gesamtzal der Zeilen ermittle ich ja hiermit:
Public Function FileLineCount(ByVal Filename As String) As Integer
Dim Lines As Integer = 0
Using oStream As New IO.FileStream(Filename, IO.FileMode.Open, _
IO.FileAccess.Read)
' Blockgröße
Dim BlockSize As Integer = 16384
Dim Bytes(BlockSize) As Byte
Dim ReadSize As Integer
Dim StartIndex As Integer
' Datei blockweise auslesen, bis Dateiende erreicht
Do
ReadSize = oStream.Read(Bytes, 0, BlockSize)
' Anzahl Zeilenumbruchzeichen ermitteln
StartIndex = -1
Do
StartIndex = Array.IndexOf(Bytes, CByte(13), StartIndex + _
1, ReadSize - StartIndex)
If StartIndex >= 0 Then Lines += 1
Loop Until StartIndex < 0
Loop Until ReadSize = 0
oStream.Close()
End Using
Return Lines
End Function Aber ich kapiere nicht, wie ich hochzählen kann. | |
Re: Datei aufteilen und umbenennen | | | Autor: Manfred X | Datum: 28.02.17 15:01 |
| Das brauchst Du für die Fortschrittsanzeige nicht.
Hier eine triviale Lösung (Byte-Zählung):
'Eine Progressbar für Prozentzählung auf die Form setzen
Dim probar As New ProgressBar With _
{.Parent = Me, .Minimum = 1, .Maximum = 100}
Private Sub SplitFile()
Dim basefile As String = "C:\daten\split.txt" 'zu splittendes File
Dim totallength As Long = New IO.FileInfo(basefile).Length 'Gesamtlänge
Dim readlength As Long = 0
Dim linecount As Long = 0, percent As Integer = 0
Dim lines As New List(Of String), line As String = ""
Dim outpath As String = "C:\daten", outfile As String = ""
Using sr As New IO.StreamReader(basefile)
While Not sr.EndOfStream
line = sr.ReadLine
lines.Add(line)
readlength += line.Length + 2 'CRLF
linecount += 1
If linecount Mod 100 = 0 Then
'Progressbar aktualisieren
percent = CInt(readlength * 100 / totallength)
probar.Value = percent
probar.Refresh()
End If
If line.StartsWith("PG_Bezeichnung".ToUpper) Then
Dim filename As String = _
line.Substring(line.IndexOf("=") + 1) & ".txt"
outfile = IO.Path.Combine(outpath, filename)
End If
If Not outfile = "" Then
If line.StartsWith("[Hauptprogramm]".ToUpper) Then
lines.RemoveAt(lines.Count - 1)
IO.File.WriteAllLines(outfile, lines)
lines.Clear()
lines.Add(line)
outfile = ""
End If
End If
End While
End Using
If Not lines.Count = 0 And Not outfile = "" Then
IO.File.WriteAllLines(outfile, lines)
End If
End Sub Bei mehr als 1 Million Datensätzen in der Datei, solle man als
Modulo-Teiler statt 100 besser 10000 einsetzen:
If linecount Mod 10000 = 0 then ...
Beitrag wurde zuletzt am 28.02.17 um 15:15:06 editiert. | |
Re: Datei aufteilen und umbenennen | | | Autor: Franki | Datum: 01.03.17 02:24 |
| Hallo,
Zitat: | |
Leider bin ich ein richtiger Anfänger, und weis teilweise nicht einmal wie ich mich richtig ausdrücken muss | |
Na ja das wird schon, man wächst mit seinen Aufgaben. Aber andererseits frage ich mich immer warum sich Anfänger an Aufgaben heran wagen die nicht für Anfänger geeignet sind.
Das wäre ja so als wenn sich ein Grundschüler an die Integralrechnung macht. Klar damit kann man viel machen aber wenn man liest was man damit machen kann hilft das nicht weiter wenn die Grundlagen fehlen.
Zitat: | |
Das Grundlagenbuch ich auch schon bestellt.
Leider scheitert es noch der Umsetzung.
leider ist aller Anfang schwer ....
| |
Ja natürlich ist (leider) der Anfang schwer, das mit dem Grundlagenbuch ist schon ok, aber es ist einfacher die Grundlagen Schritt für Schritt zu lernen und damit auch Erfolgserlebnisse zu haben als sich am Anfang an zu schwere Aufgaben zu wagen woran man dann evtl. scheitert.
Selbst wenn du hier Programmcode gepostet bekommst der dir hilft bringt dir das beim Lernerfolg rein gar nichts wenn du den nur verwendest aber nicht wirklich verstehst. Dann hast du zwar dein Ergebnis erreicht aber nichts gelernt.
Gruß
Frank | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
vb@rchiv CD Vol.6 vb@rchiv Vol.6
Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
Online-Update-Funktion Entwickler-Vollversionen u.v.m.Jetzt zugreifen Tipp des Monats sevGraph (VB/VBA)
Grafische Auswertungen
Präsentieren Sie Ihre Daten mit wenig Aufwand in grafischer Form. sevGraph unterstützt hierbei Balken-, Linien- und Stapel-Diagramme (Stacked Bars), sowie 2D- und 3D-Tortendiagramme und arbeitet vollständig datenbankunabhängig! Weitere Infos
|