10

我正在尝试这段代码:

filename = "test.txt"
listFile  = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
For Each line In listLines
   WScript.Echo line 
   'My Stuff
Next

或者这个:

filename = "test.txt"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(filename, ForReading)
    Do Until f.AtEndOfStream
      myLine = f.ReadLine
      WScript.Echo myLine
      'My Stuff
    Loop

为什么在这两种情况下它会同时回显所有行,当然我无法逐行工作?任何的想法?

4

2 回答 2

12

您的文件有有趣的 EndOfLine 标记。假设这些行由 vbLf 终止:

>> fn = "lf.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbLf)
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
a
b
c

如您所见,.ReadLine 可以处理 vbLf (unix)。但是,您在 .ReadAll() 上的 Split() 将失败:

>> t = goFS.OpenTextFile(fn).ReadAll()
>> a = Split(t, vbCrLf)
>> WScript.Echo UBound(a)
>> WScript.Echo a(0)
>>
0
a
b
c

t 不包含单个 vbCrLf,因此Split()返回一个 UBound() == 0 的数组,其中包含 t 作为其单个元素。.Echoing 至少看起来像 3 (4) 行。如果你真的需要一个行数组,你可以在 vbLf 上使用 Split()。

但是如果您的文件包含 vbLf 结尾,那么 .ReadLine 循环应该可以正常工作。

.ReadLine() 无法处理 vbCr (mac):

>> fn = "cr.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbCr)
>>
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
c

b+cr“覆盖”a+cr,然后被c+cr“覆盖”。.ReadAll() 方法也会失败,除非您使用 vbCr 作为分隔符。

但是,如果您的文件包含 vbCr 结尾,那么您的任何片段都不能“一次回显所有行”。

你的文件是从外太空来的吗?

更新 wrt 评论:

您无法使用 Filesystemobject 读取 UTF-8。将文件转换为 UTF-16 并在 .OpenTextFile 时使用格式参数的 Unicode 选项,或者使用 ADODB 流。

知道使用什么 EOL 标记仍然很有趣。

于 2014-05-12T23:00:43.750 回答
3

您的代码似乎工作正常。我稍微改变了一下,以表明这些行实际上是逐行读取的:

Set fso=CreateObject("Scripting.FileSystemObject")

filename = "test.txt"
listFile = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
i = 0

For Each line In listLines
   WScript.Echo CStr(i) + " : " + line 
   i = i + 1

   'My Stuff
Next

我假设fso在您的脚本中设置了某处,但我添加了额外的行只是为了完整性。

您应该验证您的输入文件确实有多行由vbCrLf. 计数器i有助于调试每一行,因为它在读取行期间显示行索引。

于 2014-05-12T22:26:22.233 回答