2012-11-28 2 views
2

크기 230MB의 텍스트 파일이 있습니다. 그 파일의 라인 수를 계산하고 싶습니다.읽기 대용량 파일 VB6의 줄 수

"Scripting.FileSystemOblect"을 시도했지만 메모리가 부족합니다.

도와주세요.

감사합니다.

+2

적어도 [QBasic] (http://www.freewebs.com/computerghost/QBasic/Commands.htm#U) – SeanC

답변

5

일반 윈도우 줄 바꿈 은 CRLF이다 파일의 마지막 줄에는 그 다음 줄이 없습니다.

VB에서 (예 : VB5, VB6 등) 많은 작업을 빠르게하기 위해 바이트 지향 String 작업을 사용할 수 있습니다. 우리는 텍스트 파일은 ANSI를 포함 추측 할 수 있다면이 꽤 빠르다 :

Option Explicit 

Private Sub Main() 
    Const BUFSIZE As Long = 100000 
    Dim T0 As Single 
    Dim LfAnsi As String 
    Dim F As Integer 
    Dim FileBytes As Long 
    Dim BytesLeft As Long 
    Dim Buffer() As Byte 
    Dim strBuffer As String 
    Dim BufPos As Long 
    Dim LineCount As Long 

    T0 = Timer() 
    LfAnsi = StrConv(vbLf, vbFromUnicode) 
    F = FreeFile(0) 
    Open "big.txt" For Binary Access Read As #F 
    FileBytes = LOF(F) 
    ReDim Buffer(BUFSIZE - 1) 
    BytesLeft = FileBytes 
    Do Until BytesLeft = 0 
     If BufPos = 0 Then 
      If BytesLeft < BUFSIZE Then ReDim Buffer(BytesLeft - 1) 
      Get #F, , Buffer 
      strBuffer = Buffer 'Binary copy of bytes. 
      BytesLeft = BytesLeft - LenB(strBuffer) 
      BufPos = 1 
     End If 
     Do Until BufPos = 0 
      BufPos = InStrB(BufPos, strBuffer, LfAnsi) 
      If BufPos > 0 Then 
       LineCount = LineCount + 1 
       BufPos = BufPos + 1 
      End If 
     Loop 
    Loop 
    Close #F 
    'Add 1 to LineCount if last line of your files do not 
    'have a trailing CrLf. 
    MsgBox "Counted " & Format$(LineCount, "#,##0") & " lines in" & vbNewLine _ 
     & Format$(FileBytes, "#,##0") & " bytes of text." & vbNewLine _ 
     & Format$(Timer() - T0, "0.0#") & " seconds." 
End Sub 

는 단지 여기에 0.7 초 밖에 걸리지 293메가바이트의 7,000,000 라인 파일을 감안할 때. 그러나 필자는 테스트를 실행할 때 파일이 캐시되지 않았는지 확인하기 위해 재부팅하지 않았습니다. 캐싱이 없다면 (즉, 재부팅 후) 5 배나 오래 걸릴 것으로 예상됩니다.

유니 코드 텍스트 파일을 처리하는 변환은 매우 간단합니다. B 함수를 B가 아닌 값으로 바꾸고, BUFSIZE를 2의 배수로 설정하고 ANSI LF 바이트 대신 vbLf을 검색하십시오.

+0

감사합니다. 정말 빠르게 작업을 다른 사람과 비교하십시오. –

+0

음, 음, 음, UBound()가 작동하기 시작했다고 생각합니다. 천만에요. – Bob77

+0

1.640 파일 (11004037) ~ 20 초 안에 줄 수 – bjan

2

각 변수를 동일한 변수로 읽으면됩니다. 이 모든 라인을 저장 할 필요 없다 :이 테스트되지 않았습니다

dim s as string 
dim n as integer 

open "filename.txt" for input as 1 

n = 0 
do while not eof(1) 
    line input #1, s 
    n = n + 1 
    loop 

이, 그리고 내가 어떤 VB6를 수행 한 이후 오랜만이야,하지만 가까이해야합니다.

+1

이후 큰 파일로 반복하기 때문에 "UBound"가 지원되었습니다. –

+0

사실입니다. 더 빠른 방법은 FileSystemObject를 사용하여 전체 파일을 바이트 배열로 읽어 들이고 (LOF를 사용하여 몇 개가 있는지 확인한 다음) 배열에서 chr (13) 및/또는 chr (10)의 발생 횟수를 세는 것입니다 . – xpda

+0

+1 FileSystemObject도 전체 파일을 읽으므로 속도가 느립니다. 만약 당신이 * 정말로 * 속도를 원한다면 [메모리 매핑 된 파일] (http://vb.mvps.org/articles/ap199910.asp)을 사용할 수 있지만 그 많은 작업과 꽤 발전했습니다. – MarkJ

2

이것은 1mil + 0xD (vbcr)와 4백80메가바이트 이진 파일에 저를 위해 약 6 초 정도 걸립니다

Dim buff() As Byte 
Dim hF As Integer 
Dim i As Long, n As Long 

hF = FreeFile(0) 

Open "c:\windows\Installer\2f91fd.msp" For Binary Access Read As #hF 
ReDim buff(LOF(hF) - 1) 
Get #hF, , buff() 
Close #hF 

For i = 0 To UBound(buff) 
    If buff(i) = 13 Then n = n + 1 
Next 

MsgBox n 
당신이 LFS를 계산하고 경우에 카운트 하나를 추가 할 수 있도록
+0

답장을 보내 주셔서 감사합니다하지만 Ubound은 VB6에서 지원되지 않습니다. –

+4

UBound는 VB6의 모든 버전에서 지원됩니다. 무엇을 사용하고 있습니까? –

+1

1.6GB 파일로 시도했지만 ReDim 버프 (LOF (hF) - 1)에서 실패했습니다 (메모리 부족) – bjan