Zeichen ersetzen

29/03/2009 - 22:47 von Lothar Geyer | Report spam
Normalerweise ja kein Problem. Wenn ich aber alle einfachen LF (also
nicht jene, die in einem CRLF stecken) durch CRLF ersetzen will, wird es
schon etwas komplizierter. Ich habe natürlich eine Lösung - aber mit der
Performance bin ich gar nicht zufrieden. Hat jemand einen "schnellen"
Vorschlag, so dass die Bearbeitung eines 20MB-String mit
80-Zeichen-Zeilen vom Benutzer (fast) nicht bemerkt wird?

Lothar Geyer
 

Lesen sie die antworten

#1 Schmidt
30/03/2009 - 00:40 | Warnen spam
"Lothar Geyer" schrieb im Newsbeitrag
news:
Normalerweise ja kein Problem. Wenn ich aber alle einfachen LF (also
nicht jene, die in einem CRLF stecken) durch CRLF ersetzen will, wird es
schon etwas komplizierter. Ich habe natürlich eine Lösung - aber mit der
Performance bin ich gar nicht zufrieden. Hat jemand einen "schnellen"
Vorschlag, so dass die Bearbeitung eines 20MB-String mit
80-Zeichen-Zeilen vom Benutzer (fast) nicht bemerkt wird?



Ich geh jetzt einfach mal von FileContent in 8Bit-ANSI aus...
Hierfür alles zunàchst mal direkt in ein ByteArray einlesen
(per Open Binary und Get ... alles in einem Rutsch).

Danach ReplaceLF() aufrufen...

...und das BDst-ByteArray dann einfach binàr zurück-
schreiben (als Block ... sollte bei ca. 20MB und den
heutigen Speichergrößen eigentlich keine Probleme
machen)...

...viel schneller geht eigentlich nicht (wenn native compiled
müsste das eigentlich "blink" machen - der Rest wàre File-IO,
also bei ca. 20MB so ca. 0.3sec für's Einlesen, ca. 0.1sec für das
Ersetzen und nochmal ca. 0.3sec dann für's Zurückschreiben).


'*** In eine Form
Option Explicit

Private Declare Sub RtlMoveMemory Lib "kernel32" _
(Dst As Any, Src As Any, ByVal Bytes As Long)

Private Sub Form_Load()
Dim B() As Byte, BDst() As Byte

B = StrConv("a" & vbLf & "b" & vbLf & "c", vbFromUnicode)

ReplaceLF B, BDst

Debug.Print Replace(StrConv(BDst, vbUnicode), vbCrLf, "<CRLF>")
End Sub

Private Sub ReplaceLF(B() As Byte, BDst() As Byte)
Dim i As Long, f_cc As Long, PosArr() As Long, PosArrUB As Long

'check for a valid B() here (if not done before)...

'first some preparations
PosArrUB = 300000 'start with a reasonable size
ReDim PosArr(PosArrUB)

If B(0) = 10 Then 'check the first Byte (our loop will start with 1)
PosArr(f_cc) = 0 'save the found position
f_cc = f_cc + 1 'increase the "found-count"
End If

'first pass, only to determine the positions
For i = 1 To UBound(B)
If B(i) = 10 Then
If B(i - 1) <> 13 Then
If f_cc >= PosArrUB Then 'check for realloc
PosArrUB = 1.5 * PosArrUB
ReDim Preserve PosArr(PosArrUB)
End If
PosArr(f_cc) = i 'save the found position
f_cc = f_cc + 1 'increase the "found-count"
End If
End If
Next i

'prepare for the second pass
ReDim BDst(UBound(B) + f_cc)
PosArr(f_cc) = UBound(B) + 1 'to make the following loop easier

If PosArr(0) > 0 Then 'copy the first block (before first LF)
RtlMoveMemory BDst(0), B(0), PosArr(0)
End If

'now the loop over the positions and Replace into BDst
For i = 0 To f_cc - 1
BDst(PosArr(i) + i) = 13

RtlMoveMemory BDst(PosArr(i) + i + 1), B(PosArr(i)), _
PosArr(i + 1) - PosArr(i)
Next i
End Sub


Olaf

Ähnliche fragen