我想使用ADO Stream从UTF-8编码的本地大文本文件中读取行,所以我试试
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "utf-8"
objStream.Type = 2
objStream.Open
objStream.LoadFromFile = strFile
objStream.LineSeparator = 10
Do Until objStream.EOS
strLine = objStream.ReadText(-2)
Loop
然而结果是该脚本需要大量的RAM和CPU使用。那么有没有办法告诉脚本不要将所有文件内容加载到内存中,只是打开它并读取,直到它遇到任何行分隔符?
答案 0 :(得分:8)
当您使用Stream
对象时,我认为显而易见的是,.LoadFromFile
使用整个文件内容填充当前流,并且没有任何cutomize选项从文件加载parial数据。
至于阅读1行,您已使用.ReadText(-2)
,( - 2 = adReadLine)完成此操作。
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "utf-8"
objStream.Type = 2
objStream.Open
'objStream.LoadFromFile = strFile ''I see a typo here
objStream.LoadFromFile strFile
objStream.LineSeparator = 10 ''that's Ok
'Do Until objStream.EOS ''no need this
strLine = objStream.ReadText(-2)
'Loop
objStream.Close ''add this though!
[编辑]好吧,对于.LineSeparator,您只能使用3个常量:
Constant Value Description
adCRLF -1 Default. Carriage return line feed
adLF 10 Line feed only
adCR 13 Carriage return only
如果您需要在其他字母上打破Do..Loop
,因为.ReadText
是阅读文字流的唯一选择,您可以将其与InStr
函数和{{1然后你找到你的自定义分隔符。
Exit Do
很快,这是你可以做的整个优化(至少据我所知)。
答案 1 :(得分:2)
如果查看this snippet from J. T. Roff's ADO book,您会发现理论上您可以逐行读取文件(不将其完全加载到内存中)。我尝试在source参数中使用文件:protocoll,但没有成功。
所以让我们尝试另一种方法:要将.txt文件视为UTF8编码的普通(一列)ADO数据库表,您需要在源目录中有一个schema.ini文件:
[linesutf8.txt]
ColNameHeader=False
CharacterSet=65001
Format=TabDelimited
Col1=SampleText CHAR WIDTH 100
然后你可以这样做:
Dim sTDir : sTDir = "M:/lib/kurs0705/testdata"
Dim sFName : sFName = "[linesutf8.txt]"
Dim oDb : Set oDb = CreateObject("ADODB.Connection")
Dim sCs : sCs = Join(Array( _
"Provider=MSDASQL" _
, "Driver={Microsoft Text Driver (*.txt; *.csv)}" _
, "DBQ=" + sTDir _
), ";")
oDb.open sCs
WScript.Stdin.Readline
Dim oRs : Set oRs = oDb.Execute("SELECT * FROM " & sFName)
WScript.Stdin.Readline
Do Until oRS.EOF
WScript.Echo oRS.Fields(0).Value
oRs.MoveNext
Loop
oRs.Close
oDb.Close
对于某些背景外观here。