使用ADO Stream逐行读取大文件?

时间:2013-03-01 05:27:19

标签: asp-classic vbscript ado

我想使用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使用。那么有没有办法告诉脚本不要将所有文件内容加载到内存中,只是打开它并读取,直到它遇到任何行分隔符?

2 个答案:

答案 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