【发布时间】:2020-10-26 18:18:13
【问题描述】:
我编写了一个简单的程序,它逐行读取文本文件,如果当前读取的行有字母 (a-z A-Z),它将将该行写入另一个 txt 文件。
如果当前读取的行没有字母,它不会将该行写入新的文本文件。
我创建这个的目的是为了让会员在我的网站上注册,其中一些会员只使用数字作为用户名。我会将它们过滤掉,只保存字母名称。 (请专注于这个项目,我知道我可以只使用 php 的东西)
这已经很好用了,但是逐行读取并写入另一个文本文件需要一段时间(1 分钟内写入速度 150kb - 这不是我的驱动器,我有一个快速的 ssd)。
所以我想知道是否有更快的方法。我可以先“readalllines”,但在大文件上它只会冻结我的程序,所以我不知道这是否也有效(我想专注于大 +1gb 文件)
这是我目前的代码:
If System.IO.File.Exists(FILE_NAME) = True Then
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
Dim myFile As New FileInfo(output)
Dim sizeInBytes As Long = myFile.Length
If sizeInBytes > splitvalue Then
outcount += 1
output = outputold + outcount.ToString + ".txt"
File.Create(output).Dispose()
End If
count += 1
TextLine = objReader.ReadLine() & vbNewLine
Console.WriteLine(TextLine)
If CheckForAlphaCharacters(TextLine) Then
File.AppendAllText(output, TextLine)
Else
found += 1
Label2.Text = "Removed: " + found.ToString
TextBox1.Text = TextLine
End If
Label1.Text = "Checked: " + count.ToString
Loop
MessageBox.Show("Finish!")
End If
【问题讨论】:
-
不是询问文件 I/O,而是要研究线程模型,在后台线程上执行所有文件 I/O。 (也许async/await 足够简单。)此外,您的程序“冻结”是因为您将业务逻辑与 UI 操作混合在一起(例如
Label2.Text =)。通过在 UI 线程上运行这个长时间的操作,您会使 UI 无响应。如何实现这种分离有各种各样的模型(MVVM 就是其中之一)。 -
好吧,只是为了测试目的,我还删除了所有的 ui 部分,只留下了文本编写部分。看起来速度从 1 分钟的 150kb 上升到 1 分钟的 200kb,这仍然很慢。逐行阅读并将其粘贴到另一个文本文件中似乎就是问题所在。不知道有没有更快的方法?
-
好吧,文件 I/O 需要时间。这是同一主题的another question,那里的答案表明您不会获得比
StreamReader.ReadLine()更好的性能。我建议仔细查看的答案是关于使用单独的线程进行阅读和写作。 (想想生产者/消费者模型。)这样你的限速器(可能ReadLine())就不会被任何东西挡住。 -
另一个考虑因素,CheckForAlphaCharacters(TextLine) 引入了多少延迟?该方法的实现方式有什么可以优化的吗?
-
splitvalue的大小是多少?您可以将数据累积到 StringBuilder 中,然后一次性将其写入其中一个输出文件。
标签: vb.net