Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp classic 用ADO流逐行读取大文件?_Asp Classic_Vbscript_Ado - Fatal编程技术网

Asp classic 用ADO流逐行读取大文件?

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

我想使用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 = 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