Làm thế nào để tăng tốc độ đọc File txt (>100Mb) bị Encoding

Liên hệ QC MyVTV Add-ins

ganbarou

Thành viên mới
Tham gia ngày
18 Tháng năm 2021
Bài viết
25
Được thích
3
Giới tính
Nam
File của bạn ngăn cách bằng ký tự LF (mã 10), không phải CRLF. Mình sử dụng FSO thì vẫn thấy đọc được, không biết máy bạn lỗi ở đâu. Máy mình cũng không có font jav.
Mã:
Sub FSO1()
    Dim fso As FileSystemObject, txtFile As Object, arr
    Dim Str As String
    Set fso = New FileSystemObject
    Set txtFile = fso.OpenTextFile(ThisWorkbook.Path & "\PEC_20210603.log")
    Str = txtFile.ReadAll
    txtFile.Close
    arr = Split(Str, vbLf)
    Sheet1.Range("A1") = arr(14)
End Sub
Nếu chỉ là những câu tiếng Anh thì ổn, nhưng không thể dùng tiếng Nhật để tìm kiếm thông tin được ạ.
Bài đã được tự động gộp:

Sau khi tìm hiểu thì mình thấy FSO opentextfile chỉ hỗ trợ Unicode dạng UTF 16 LE. Dùng word có thể mở file dạng EUC JP rồi saveas dạng này nhưng lưu lượng file sẽ tăng dẫn đến tốc độ load file giảm, nhất là khi dùng HDD. Vì vậy nếu bạn có SSD, thường xuyên sử dụng các file trên thì có thể thử rồi so sánh tốc độ xử lý giữa Stream và FSO.
em cũng đang tìm hướng để chuyển đổi file sang dạng có thể dùng FSO, vì em thấy FSO cho tốc độ đọc file tốt hơn ^^
 

Hau151978

Thành viên tích cực
Tham gia ngày
19 Tháng mười 2011
Bài viết
1,451
Được thích
1,397
Bạn có thể dùng vba word để open rồi saveas hàng loạt file dạng unicode utf16 LE. Trong Excel fso.opentext với tham số Tristate bằng true, tuy thời gian đọc file chậm hơn nhưng không mất thời gian chuyển đổi.
 

ganbarou

Thành viên mới
Tham gia ngày
18 Tháng năm 2021
Bài viết
25
Được thích
3
Giới tính
Nam
Dành cho ai muốn dùng ADODB.Stream để đọc từng dòng trong file cho nhanh.

Thay vì dùng câu lênh:
Mã:
ObjStream.ReadText(adReadLine)
Thì dùng câu lệnh sau:
Mã:
Dim str As String
Dim strTmp() As String
Dim lastStrTmp As String

str = ObjStream.ReadText(8192) 'Doc 8192 byte
strTmp = Split(str, vbLf)
strTmp(0) = lastStrTmp + strTmp(0)
lastStrTmp = strTmp(UBound(strTmp))
For i = 0 to UBound(strTmp) - 1
    Debug.Print strTmp(0)
Next
Thời gian đọc file 100Mb từ 2 phút sẽ có thể giảm xuống còn 10 giây.

Theo lời của tác giả thì nếu sử dụng ..(adReadLine) sẽ xảy ra hiện tượng tích lũy gì đó dẫn đến tình trạng các câu về sau càng mất nhiều thời gian để đọc. Vì vậy hãy chỉ định cho ReadText đọc một số Byte cụ thể rồi tách ra thành từng câu.

Tiện thể cảm ơn mọi người đã giúp em trong vấn đề này ^^
 

Pi-Pikachu

Thành viên chính thức
Tham gia ngày
22 Tháng hai 2021
Bài viết
54
Được thích
9
Dành cho ai muốn dùng ADODB.Stream để đọc từng dòng trong file cho nhanh.

Thay vì dùng câu lênh:
Mã:
ObjStream.ReadText(adReadLine)
Thì dùng câu lệnh sau:
Mã:
Dim str As String
Dim strTmp() As String
Dim lastStrTmp As String

str = ObjStream.ReadText(8192) 'Doc 8192 byte
strTmp = Split(str, vbLf)
strTmp(0) = lastStrTmp + strTmp(0)
lastStrTmp = strTmp(UBound(strTmp))
For i = 0 to UBound(strTmp) - 1
    Debug.Print strTmp(0)
Next
Bạn có thể up đầy đủ code được không? (có thêm file kèm thì tốt) , up thế này phải đọc lại từ đầu quá.
 

ongke0711

Thành viên tích cực
Tham gia ngày
7 Tháng chín 2006
Bài viết
891
Được thích
1,040
Giới tính
Nam
str = ObjStream.ReadText(8192) 'Doc 8192 byte
strTmp = Split(str, vbLf)
strTmp(0) = lastStrTmp + strTmp(0)
lastStrTmp = strTmp(UBound(strTmp))
For i = 0 to UBound(strTmp) - 1
Debug.Print strTmp(0)
Next[/CODE]
Thời gian đọc file 100Mb từ 2 phút sẽ có thể giảm xuống còn 10 giây.

Bạn kiểm tra lại kết quả xem có đúng không nhé. Tham số đó chỉ là để giới hạn lại số ký tự cần lấy trong một chuỗi dài thôi. File text của bạn nó sẽ ngắt ra từng 8129 ký tự thành 1 dòng (line). Muốn tham số này bao nhiêu thì bạn phải xác định độ dài chuỗi cần lấy rồi đưa vô thôi.
 

Hau151978

Thành viên tích cực
Tham gia ngày
19 Tháng mười 2011
Bài viết
1,451
Được thích
1,397
Nếu vẫn theo hướng của mình ở trên (sử dụng Word để mở file đúng định dạng rồi saveas dạng Unicode, encode UTF16 LE) thì nội dung dạng binary của file (không tính BOM) giống như chuỗi lưu trong bộ nhớ, do VB không phải decode chuỗi nên tốc độ xử lý nhanh hơn, tuy nhiên thời gian load file lại tăng do tăng dung lượng file. Hai cách lấy nội dung file vào string dưới đây cho cùng kết quả:
Mã:
Sub FSO()
    Dim fs As FileSystemObject, TxtStr As TextStream
    Dim str As String
    Set fs = New FileSystemObject
    Set TxtStr = fs.OpenTextFile(ThisWorkbook.Path & "\U16.txt", ForReading, False, TristateTrue)
    str = TxtStr.ReadAll
    TxtStr.Close
End Sub
Sub Binary()
    Dim FileNum As Integer, x() As Byte, str As String
    FileNum = FreeFile
    Open ThisWorkbook.Path & "\U16.txt" For Binary Access Read As FileNum
    ReDim x(1 To LOF(FileNum))
    Get FileNum, , x
    Close FileNum
    str = x
End Sub
 

ganbarou

Thành viên mới
Tham gia ngày
18 Tháng năm 2021
Bài viết
25
Được thích
3
Giới tính
Nam
Bạn có thể up đầy đủ code được không? (có thêm file kèm thì tốt) , up thế này phải đọc lại từ đầu quá.
bạn không cần đọc hết đâu, lấy code bài 63 sửa vào bài 1 là được, các bài khác là nhiều phương án khác nhau bạn thích thì đọc để biết thêm kiến thức ^^
Bài đã được tự động gộp:

Bạn kiểm tra lại kết quả xem có đúng không nhé. Tham số đó chỉ là để giới hạn lại số ký tự cần lấy trong một chuỗi dài thôi. File text của bạn nó sẽ ngắt ra từng 8129 ký tự thành 1 dòng (line). Muốn tham số này bao nhiêu thì bạn phải xác định độ dài chuỗi cần lấy rồi đưa vô thôi.
Đúng là nó sẽ cắt thành từng dòng như vậy, nhưng mục đích cuối là tách ra thành từng dòng như file text thì vài dòng tiếp theo sẽ xử lý. Còn về con số 8192 thì không nhất thiết phải chính xác cũng ko cần biết độ dài chuỗi cần lấy, e test qua thì thấy 8192 là tạm ổn với chương trình của e thôi.
 
Lần chỉnh sửa cuối:

ganbarou

Thành viên mới
Tham gia ngày
18 Tháng năm 2021
Bài viết
25
Được thích
3
Giới tính
Nam
Nếu vẫn theo hướng của mình ở trên (sử dụng Word để mở file đúng định dạng rồi saveas dạng Unicode, encode UTF16 LE) thì nội dung dạng binary của file (không tính BOM) giống như chuỗi lưu trong bộ nhớ, do VB không phải decode chuỗi nên tốc độ xử lý nhanh hơn, tuy nhiên thời gian load file lại tăng do tăng dung lượng file. Hai cách lấy nội dung file vào string dưới đây cho cùng kết quả:
Mã:
Sub FSO()
    Dim fs As FileSystemObject, TxtStr As TextStream
    Dim str As String
    Set fs = New FileSystemObject
    Set TxtStr = fs.OpenTextFile(ThisWorkbook.Path & "\U16.txt", ForReading, False, TristateTrue)
    str = TxtStr.ReadAll
    TxtStr.Close
End Sub
Sub Binary()
    Dim FileNum As Integer, x() As Byte, str As String
    FileNum = FreeFile
    Open ThisWorkbook.Path & "\U16.txt" For Binary Access Read As FileNum
    ReDim x(1 To LOF(FileNum))
    Get FileNum, , x
    Close FileNum
    str = x
End Sub
tiếc là cách này phải xử lý qua word :)
 

ganbarou

Thành viên mới
Tham gia ngày
18 Tháng năm 2021
Bài viết
25
Được thích
3
Giới tính
Nam
Các file cỡ trăm MB thì không thể liên tục tạo ra mà là dữ liệu hàng ngày chẳng hạn, bạn dùng word vba để tự động mở tất cả rồi save định dạng mới thôi.
cũng có vẻ hợp lý nhỉ, để tuần sau em test xem sao
 
Top Bottom