vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Brandneu! sevEingabe v3.0 - Das Eingabecontrol der Superlative!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Einlesen 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
alle Nachrichten anzeigenGesamtübersicht  |  Zum Thema  |  Suchen

 ThemaViews  AutorDatum
Einlesen einer großen Datei aus einem Fremdsystem beschleuni...595Schudi22.07.20 16:36
Re: Einlesen einer großen Datei aus einem Fremdsystem beschl...273Schudi27.07.20 09:33

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

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

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