首页 > 解决方案 > 值不能为 Null。参数名称:streamreader期间输入错误

问题描述

如果我只是在读取一个文件,为什么它不知道如果什么都没有或者它是否为空就结束?我相信当它试图匹配'line'并且没有更多的行时会引发错误。以下是它读取文件时的代码:

    Dim Directory1 As String = "C:\Perl_Scripts\"
    Dim Ext2Find As String = "850_*.txt"

    If System.IO.Directory.GetFiles(Directory1, Ext2Find, IO.SearchOption.AllDirectories).Length > 0 Then
        Dim Return_Val() As String = System.IO.Directory.GetFiles(Directory1, Ext2Find, IO.SearchOption.AllDirectories)
        Dim i As Integer
        For i = 0 To System.IO.Directory.GetFiles(Directory1, Ext2Find, IO.SearchOption.AllDirectories).Length - 1
            'MsgBox(Ext2Find & " was found! " & Return_Val(i))

            Using sr As StreamReader = New StreamReader("C:\\Perl_scripts\\850_7703844115CH_54550937_20190218_062619.txt")
                Dim line As String
                ' Read and display lines from the file until the end of  
                ' the file is reached. 
                line = sr.ReadLine()
                While (line <> Nothing)
                    line = sr.ReadLine()
                    If Regex.IsMatch(line, "\b40\S*") Then  
                        MsgBox(line)
                    Else
                        MsgBox("THERES NO MATCH")
                    End If
                End While
            End Using

        Next i
    Else
        MsgBox(Ext2Find & " was not found!")
    End If

如果您需要查看整个潜艇,请告诉我。提前致谢!

标签: regexvb.netstreamreader

解决方案


想想你的代码在这里实际做了什么:

line = sr.ReadLine()
While (line <> Nothing)
    line = sr.ReadLine()
    If Regex.IsMatch(line, "\b40\S*") Then  'Looks for Menard files
        MsgBox(line)
    Else
        MsgBox("THERES NO MATCH")
    End If
End While

你读了一行,检查它是否存在Nothing,如果不是,你立即丢弃该行并阅读另一行并使用它。然后,您测试您阅读的第二行是否为Nothing,然后阅读另一行,然后使用它。这有什么意义?您从不使用第一行,然后在测试它是否为Nothing.

当你没有一个算法来比较你的代码时,就会发生这种情况。如果您有这样的算法,那么很明显您正在以错误的顺序做事。该代码应该是这样的:

line = sr.ReadLine()

While (line <> Nothing)
    If Regex.IsMatch(line, "\b40\S*") Then  'Looks for Menard files
        MsgBox(line)
    Else
        MsgBox("THERES NO MATCH")
    End If

    line = sr.ReadLine()
End While

现在事件序列是读取该行,检查它是否是Nothing,使用该行,重复。

当然,这一切都没有实际意义,因为无论如何您都不应该那样阅读文件。你应该做这个:

For Each line In File.ReadLines("C:\Perl_scripts\850_7703844115CH_54550937_20190218_062619.txt")
    If Regex.IsMatch(line, "\b40\S*") Then  'Looks for Menard files
        MsgBox(line)
    Else
        MsgBox("THERES NO MATCH")
    End If
Next

请注意,我也没有使用双斜杠,因为这是 VB,这是错误的。

编辑:

请注意,最后一个代码片段调用ReadLines而不是ReadAllLines. 两者都可以工作,并且在许多(大多数?)情况下没有实际区别。不同之处在于,ReadAllLines它将首先将整个文件读入一个数组,然后您将循环遍历该数组,而ReadLines循环完成后将一次返回一行。这对于大文件特别有利,因为这意味着您不需要一直将整个文件存储在内存中。

这也意味着,如果合适,您可以在不读取文件其余部分的情况下跳出循环。想象一下,您有一个包含一百万行的文件,并且您正在搜索出现在第一行的内容。ReadAllLines将首先创建一个包含一百万个元素的数组,然后开始循环并在第一行中找到匹配项。另一方面,ReadLines将读取第一行并将其返回,将找到匹配项,并且永远不会读取文件的其余部分。这大大节省了内存和时间。


推荐阅读