我将大约 600 000 行提取到 DataGridView(通过 SQL)中,并按日期将它们全部拆分为文件。
我尝试了几种方法来做到这一点,虽然我找到了一些让它不会崩溃并且安全可靠的方法,但它非常慢。
然而,最快的方法是,我发现只是从日期列中删除日期,例如将 2020/06/01 13:50:43 转换为 0601,并将其用作文件名,然后将文本附加到那个文件。(与在临时对象中创建所有行并一次全部写入等相反)。
它很快,一切都很好,但是在写完之后,也许 30?在大约 150 个文件中,它崩溃了。这是非常随机的,我尝试运行它几次。它可能会在几秒钟或半分钟后崩溃。因此,我相信这是由于它在尝试如此快速地多次写入时跳闸造成的。
我尝试过多次更改写入方法,确保使用使用块,以及尝试文件共享。
这是我的代码:
Private Sub btnExec_Click(sender As Object, e As EventArgs) Handles btnExec.Click
Static start_time As DateTime
Static stop_time As DateTime
Dim elapsed_time As TimeSpan
start_time = Now
If IsNumeric(TextBox1.Text) Then columnNumber = CInt(TextBox1.Text) - 1
Dim dgw = Form1.DataGridView1
Dim curcell As String = ""
Dim ToWrite As String = ""
Dim Written As Integer = 0
Try
ProgressBar1.Maximum = dgw.Rows.Count
For i = 0 To dgw.Rows.Count - 1
'For each row
If IsDBNull(dgw.Rows(i).Cells(columnNumber).Value.ToString()) Then
curcell = "" 'if null replace with a blank value
Else
curcell = CStr(dgw.Rows(i).Cells(columnNumber).Value)
End If
'RB FORMATTING
If RadioButton1.Checked = True Then '2020/01/01 00:00:00
'2020/06/16 19:38:33
curcell = curcell.Remove(0, 5)
curcell = curcell.Remove(curcell.Length - 9, 9)
curcell = curcell.Replace("/", "")
'0616
End If
'Now we have 0616 in a string which is the date of the current row
Dim currow As String = ""
For Each c As DataGridViewCell In dgw.Rows(i).Cells
If IsDBNull(c.Value) Then
currow += Chr(34) + "" + Chr(34) + ","
Else
currow += Chr(34) + CStr(c.Value) + Chr(34) + ","
End If
Next
currow = currow.Remove(currow.Length - 1, 1) 'Remove last comma
'Now we have the full row to print as well as the date in a string
Dim FILENAME As String = TextBox2.Text + "\" + curcell + ".csv"
' Using fs As FileStream = File.OpenWrite(FILENAME)
' AddText(fs, currow + vbCrLf)
' End Using
Dim fs As FileStream = New FileStream(FILENAME, FileMode.OpenOrCreate, FileAccess.Write)
Dim w As StreamWriter = New StreamWriter(fs)
w.BaseStream.Seek(0, SeekOrigin.[End])
w.Write(currow + vbCrLf)
w.Close()
'Using writer As StreamWriter = File.AppendText(FILENAME)
'writer.WriteLine(currow)
' End Using
'My.Computer.FileSystem.WriteAllText(FILENAME, currow + vbCrLf, 1) 'Gets used by its own process error some times
Written += 1
Next 'Next row
stop_time = Now
elapsed_time = stop_time.Subtract(start_time)
Log("Wrote " + CStr(Written) + " lines in " + elapsed_time.TotalSeconds.ToString("0.00" & " seconds."))
Catch ex As Exception
Log(ex.ToString())
End Try
End Sub
(我意识到这是非常混乱的自动取款机,我一直在尝试很多事情还没有清理)
这是错误:
System.IO.IOException: The process cannot access the file 'C:\Users\username\Desktop\TEST2\0416.csv' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at TicketsSQL.frmSplitFiles.btnExec_Click(Object sender, EventArgs e) in C:\Users\username\source\repos\TicketsSQL\TicketsSQL\frmSplitFiles.vb:line 63
除了我在代码中尝试的当前方法之外,我还注释掉了另外两种方法。我尝试了以下三种方法:
Dim fs As FileStream = New FileStream(FILENAME, FileMode.OpenOrCreate, FileAccess.Write)
Dim w As StreamWriter = New StreamWriter(fs)
w.BaseStream.Seek(0, SeekOrigin.[End])
w.Write(currow + vbCrLf)
w.Close()
Using writer As StreamWriter = File.AppendText(FILENAME)
writer.WriteLine(currow)
End Using
My.Computer.FileSystem.WriteAllText(FILENAME, currow + vbCrLf, 1)
似乎无论我以何种方式尝试使用已经打开的文件来阻止它,甚至允许它这样做......它还是会跳闸。
任何人有任何解决方法或方法来解决这个问题?现在已经花了好几个小时了......谢谢!