【问题标题】:Very slow networked file Read speed?网络文件读取速度很慢?
【发布时间】:2019-07-30 05:38:25
【问题描述】:

我有一个文件大小为 345 KB 的二进制文件。 我正在尝试将 VB6 中的文件逐行读取到长度为 26 的字符串数组中(用于加载到我的数据表中)。 示例代码如下:

Dim fn1 As Integer
Dim FileStringArray(26) As String
fn1 = FreeFile
Open filepath For Binary As #fn1
    Do While EOF(fn1) = False
        Get fn1, , FileStringArray
        For i = 0 To 25
            'Do something with FileStringArray(i)
        Next                
    Loop
Close fn1

这在本地 PC 上完美运行。 345 KB 的文件可以在 1 秒内读取。在 1 Gbps 网络的情况下,预计也有相同的速度。当我测试通过网络打开的文件时,文件打开速度与本地路径相同。

但是,在某些计算机中,即使网络速度为 1Gbps(通过复制 102MB 和 1GB 文件测试时的实际速度为 850 Mbps),读取文件大约需要 20 秒。对于数组大小为 26 的每个 GET 行,大约需要 0.015 秒(即每秒 66 行)。正常速度下,1507行的整个文件只需要0.125秒。

当我在我的网络中使用不同的计算机进行测试时,我发现对于某些计算机,第一次需要将近 20 秒,而下一次则正常。但是,某些计算机不显示此行为。即使它的网络是 1 Gbps,即使没有其他数据传输,一台计算机也会持续花费 22 秒。在我的一些客户的计算机中发现了这个问题。

我试图通过将数组大小设置为文件长度来一次读取文件,这也显示了相同的结果。另外,我尝试使用 Line 输入法打开文件,它比二进制 GET 更快。但是,与其他计算机相比,它的速度较慢,与二进制文件的差异相同。

文本文件源计算机规格是 Intel core i7,具有 8 GB RAM,Windows 10 Pro 64 位连接到 1Gbps 网络。我有其他配置相同但配置较低的计算机,并且文件读取速度在所有其他计算机上都正常。

如果我在本地打开该 PC 中的文本文件,它是正确的。如果我通过 UNC 在同一台 PC 中打开文件,大约需要 1.9 秒。 在 VB.Net 中,读取上面相同的代码,普通电脑需要 0.031 秒,问题电脑需要 1.51 秒。

【问题讨论】:

  • 我怀疑问题不在于文件通过网络传输缓慢,而是每次阅读一行时都会发生其他一些冗长的过程
  • 病毒扫描程序?代理延迟?子网路由?

标签: windows file networking vb6


【解决方案1】:

如果文件不是真的很大,您可以通过抓取一个大 blob 中的内容,然后将其拆分为内存中的组成行来加快读取速度。比如:

Private Sub Command1_Click()
' Read an entire text file into memory in one shot, for speed (requires LOF * 2 available memory)

  Dim FileName As String, Handle As Integer, Blob As String, Lines() As String

  FileName = InputBox("Enter file name")    ' prompt the user for the file name
  If FileName = vbNullString Then Exit Sub  ' Cancel

  If Len(Dir(FileName)) = 0 Then    ' first check for existance of file, because "Open For Binary" will create it
    MsgBox "Unable to open file '" & FileName & "' - file does not exist", vbCritical
    Exit Sub
  End If

  On Error Resume Next              ' OK, it exists, so try to open the file
  Handle = FreeFile
  Open FileName For Binary As #Handle
  If Err.Number <> 0 Then
    MsgBox "Unable to open file '" & FileName & "' - " & Err.Description, vbCritical
    Exit Sub
  End If
  On Error GoTo 0

  Blob = Space(LOF(Handle))         ' pre-allocate the string to the correct size
  Get #Handle, , Blob               ' read the whole file in one shot
  Close #Handle

  Lines = Split(Blob, vbCrLf)
  If UBound(Lines) < 0 Then
    MsgBox "The file is empty."
  Else
    MsgBox "The file contains " & CStr(UBound(Lines) + 1) & " lines of text."
  End If

' Perform other processing here

End Sub

我在 WiFi 网络上尝试使用“福尔摩斯历险记”全文(约 576k),阅读时间不到两秒钟。

对于 OP 的应用程序,Split() 调用将替换为一个简单的循环,该循环将Blob 字符串的部分复制到一个(预先确定的)字符串数组中,可能使用Mid() 函数。

~~ 标记成型

【讨论】:

    猜你喜欢
    • 2013-10-03
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多