| |
VB.NET - FortgeschritteneEinlesen einer großen Datei aus einem Fremdsystem beschleunigen | | | Autor: Schudi | Datum: 22.07.20 16:36 |
| Vorgeschichte:
Ich muss Daten aus einer mit einem Fremdsystem erzeugten Datei importieren. Es handelt sich um eine mit COBOL erzeugte ISAM-Datendatei. Die Datensätze haben zwar eine feste Länge, können aber nicht zeilenweise eingelesen werden, da alle Sätze ohne Trenner direkt nacheinander kommen. Der Aufbau der Datenfelder innerhalb eines Datensatzes ist mir bekannt.
Ich lese diese Datei aktuell "häppchenweise" mit einem Binaryreader, um die unterschiedlich formatierten Werte einzeln auslesen/verarbeiten zu können. Einige Felder sind in Klartext, andere Felder sind nummerisch gepackt.
Insgesamt hat ein Datensatz eine Länge von 3070 Byte und darin enthalten ca. 400 Datenfelder, von denen ich aktuell nur etwa 10 benötige.
Mein aktueller Code benötigt ca. 50 Sekunden, um alle 20.000 Datensätze zu verarbeiten. Er funktioniert, aber ich frage mich, ob das nicht auch schneller (und eleganter) geht...
... z.B. indem man den ganzen Datensatz von 3070 Byte auf einmal statt in 18 Teil-Lesevorgängen liest und erst nachträglich aufteilt.
Allerdings lese ich bewusst manche Stellen mit ReadBytes() und andere (alle Klartexte) mit ReadChars() und alle in Cobol als "Comp-5" definierten Werte mit ReadInt32.
Für "Comp-6" gibt es in VB leider keine Entsprechung. Beispiel: Die Artikelnummer 001003 ist als Comp-6 in der Datei gespeichert. Das sind 3 Byte mit den hex-Werten: 00 01 03
... oder z.B. indem man die ganze Datei am Stück in den Speicher einliest und dann die vorhandene Leseroutine nicht auf die Datei sondern auf deren Inhalt im Speicher anwendet.
Ich bin für jeden Vorschlag dankbar...
Private s As FileStream
Private r As BinaryReader
Private ReadBuffer As Byte()
Structure Artikel
Dim ArGrp As Integer '9(2) Comp-6 1 Byte
Dim ArNr As Integer '9(6) Comp-6 3 Byte
Dim ArVpe As Single '9(4)v9(3) Comp-5 4 Byte
Dim ArBest As Single 's9(6)v9(3) Comp-5 4 Byte
Dim ArNlKz As Char '9 1 Byte
Dim ArNlDatum As String '9(8) Comp-6 4 Byte
Dim ArNlText As String 'x(50) 50 Byte
Dim ArVbTyp As Integer '9(2) comp-6 1 Byte
Dim ArErNr As Integer '9(6) comp-6 3 Byte
Dim ArLoeDatum As String '9(8) comp-6 4 Byte
End Structure
' Zunächst wird die Datei per Function OpenDatei geöffnet
Public Function OpenDatei(Dateiname As String) As Boolean
Erfolg = False
Try
s = New FileStream(Dateiname, FileMode.Open, FileAccess.Read, _
FileShare.ReadWrite)
r = New BinaryReader(s, System.Text.Encoding.GetEncoding(850))
ReadVorspann()
Erfolg = True
Catch ex As FileNotFoundException
Erfolg = False
Catch ex As Exception
MessageBox.Show(ex.ToString)
Erfolg = False
End Try
Return Erfolg
End Function
' Dann werden die einzelnen Sätze / Artikel gelesen
Public Function ReadNext(ByRef myArtikel As Artikel) As Boolean
Erfolg = False
myArtikel = Nothing 'Übergabebereich Initialisieren
Try
If r.PeekChar <> -1 Then
ReadBuffer = r.ReadBytes(1)
myArtikel.ArGrp = CType(Comp6toString(ReadBuffer), Integer)
ReadBuffer = r.ReadBytes(3) 'Dummy
ReadBuffer = r.ReadBytes(3)
myArtikel.ArNr = CType(Comp6toString(ReadBuffer), Integer)
ReadBuffer = r.ReadBytes(298) 'Dummy
myArtikel.ArVpe = r.ReadInt32
myArtikel.ArVpe = myArtikel.ArVpe / 1000 '3 NK Stellen
ReadBuffer = r.ReadBytes(85) 'Dummy
myArtikel.ArBest = r.ReadInt32
myArtikel.ArBest = myArtikel.ArBest / 1000 '3 NK Stellen
ReadBuffer = r.ReadBytes(5) 'Dummy
myArtikel.ArNlKz = r.ReadChar
ReadBuffer = r.ReadBytes(4)
myArtikel.ArNlDatum = Comp6toString(ReadBuffer)
myArtikel.ArNlText = r.ReadChars(50)
ReadBuffer = r.ReadBytes(808) 'Dummy
ReadBuffer = r.ReadBytes(1)
myArtikel.ArVbTyp = CType(Comp6toString(ReadBuffer), Integer)
ReadBuffer = r.ReadBytes(43) 'Dummy
ReadBuffer = r.ReadBytes(3)
myArtikel.ArErNr = CType(Comp6toString(ReadBuffer), Integer)
ReadBuffer = r.ReadBytes(1753) 'Dummy
ReadBuffer = r.ReadBytes(4)
myArtikel.ArLoeDatum = Comp6toString(ReadBuffer)
ReadBuffer = r.ReadBytes(2) 'Satzlängenbyte nächster Datensatz
Erfolg = True
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
Erfolg = False
End Try
Return Erfolg
End Function
Public Function Comp6toString(b() As Byte) As String
Dim x As String = ""
For i = 0 To b.Length - 1 'Arrays sind 0-basiert
x &= b(i).ToString("x2")
Next
Return x
End Function | |
| 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 |
|
|
sevWizard für VB5/6
Professionelle Assistenten im Handumdrehen
Erstellen Sie eigene Assistenten (Wizards) im Look & Feel von Windows 2000/XP - mit allem Komfort und zwar in Windeseile :-) Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|
|
|
Copyright ©2000-2024 vb@rchiv Dieter Otter Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.
Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel
|
|