Asp classic 用ADO流逐行读取大文件?
我想使用ADO流从本地大文本文件中读取UTF-8编码的行,所以我尝试了Asp classic 用ADO流逐行读取大文件?,asp-classic,vbscript,ado,Asp Classic,Vbscript,Ado,我想使用ADO流从本地大文本文件中读取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 = objStrea
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。那么,有没有办法告诉脚本不要将所有文件内容加载到内存中,只需打开它并读取,直到遇到任何行分隔符?当您使用
流
对象时,我认为很明显,.LoadFromFile
用整个文件内容填充当前流,并且没有任何cutomize选项从文件中加载部分数据
至于阅读1行,您已经用.ReadText(-2)
,(-2=adradline)完成了
[编辑]好吧,因为您可以只使用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
函数和Exit Do
一起使用,然后找到自定义分隔符
Const cSeparator = "_" 'your custom separator
Dim strLine, strTotal, index
Do Until objStream.EOS
strLine = objStream.ReadText(-2)
index = InStr(1, strLine, cSeparator)
If index <> 0 Then
strTotal = strTotal & Left(strLine, index-1)
Exit Do
Else
strTotal = strTotal & strLine
End If
Loop
Const csepator=“\u””您的自定义分隔符
Dim strLine,strTotal,索引
直到objStream.EOS为止
strLine=objStream.ReadText(-2)
索引=仪表(1,斯特林,C分离器)
如果索引为0,则
STROTOTAL=STROTOTAL和Left(strLine,索引-1)
退出Do
其他的
STROTOTAL=STROTOTAL和strLine
如果结束
环
简而言之,这就是您可以进行的全部优化(或者至少据我所知)。如果您仔细观察,您会发现理论上您可以逐行读取文件(无需将其完全加载到内存中)。我尝试在源参数中使用file: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
查看一些背景信息。如果您想从第一行分隔符开始,在EOS(流结束)之前不应循环,我也不确定您是否应该像您那样将您的行分隔符从默认的CrLf更改为Lf。感谢您的更正,但是我需要的是循环文件的每一行,而不仅仅是第一行,我想优化代码,这样就不会占用大量内存。好吧,可能我误解了你的问题,我会更新我的答案。非常有趣,但似乎我无法正确测试,因为我得到了“找不到提供程序”。您能用“C:\lib\linesutf8.txt”中的示例文件详细说明吗?我尝试了sTDir的所有可能的变体,“C:/lib/linesutf8.txt”、“C:/lib”、“C:/lib/”、“C:\lib\linesutf8.txt”、“C:\lib”、“C:\lib\”和所有这些变体都失败了。Thanks@PanayotKarabakalov-如果出现“未找到提供程序”错误,则“提供程序=…”属性或ADO安装有问题。sTDir是.txt文件(和schema.ini文件)所在的文件夹。@Ekkehard.Horner我的文本文件路径是c:\test.txt,这是我的尝试。我打开命令提示符并运行脚本,但我得到的只是第10行“WScript.Stdin.Readline”上的“没有足够的存储空间来处理此命令”(80078008)。你知道这个错误吗?@PanayotKarabakalov-使用“\”作为路径分隔符;第10行是“.Open”语句;它对一个小文件“起作用”吗?@Ekkehard.Horner-我想你最后的评论是给用户433531,对吗?;-)
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