Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way of writing to a text file in VB.NET

We have some information that we need to write (about 18 KB) to a .txt file stored on one of our network drives. The file is re-written about once every 15 minutes, but it is read practically at least every second. We are currently using StreamWriter to write the file.

The file server is in a remote location and the round trip ping varies from less than 1 ms to 15 ms.

The problem is, sometimes it takes as long as six seconds to write the contents to the file, which is definitely way too long even after we take consideration of the network speed.

Therefore, I am just wondering if there is any efficient way to write the file using VB.NET to improve the performance? Java has a very good tool named BufferedOutputStream, which unfortunately is not available in VB.NET (or I just have not found it).

like image 792
AZhu Avatar asked Jan 24 '11 19:01

AZhu


2 Answers

The fastest option:

Collect all your text into one large string first and then use System.IO.File.WriteAllText(fileName, text).

like image 156
Henk Holterman Avatar answered Oct 25 '22 22:10

Henk Holterman


This function was written to read from a database and output to a text file. Please feel free to use it as a starting point.

 Sub MakeFile(ByVal Obj As Object)
    Dim CountRow As Integer = 0
    Dim TableName As String = CType(Obj, String())(0)
    Dim CommandText As String = CType(Obj, String())(1)


    Dim csvFileName As String = InitilizationSettings.DirectoryPath & TableName & ".txt"
    If File.Exists(csvFileName) Then
        File.Delete(csvFileName)
    End If
    Dim buffer() As Byte = {255}
    Dim FileObject As New FileStream(csvFileName, FileMode.OpenOrCreate)
    Dim MStream As New MemoryStream()
    Dim StreamWriterObj As New StreamWriter(MStream)
    Dim sb As New System.Text.StringBuilder
    Dim x As Integer = 0

    Dim reader As SqlDataReader
    Dim cmd As New SqlCommand()
    Dim conn As New SqlConnection(IOUtilities.GetConnectionString())


    conn.Open()


    With cmd
        .CommandText = CommandText
        .CommandTimeout = 1200
        .CommandType = CommandType.Text
        .Connection = conn
    End With

    reader = cmd.ExecuteReader()

    Do While reader.Read()
        'System.Console.Write("Loading rows to memory.../" & vbCr)
        sb.Append(Chr(34))
        sb.Append(reader.Item(0))
        'System.Console.Write("Loading rows to memory...|" & vbCr)
        sb.Append(Chr(34))
        For i = 1 To reader.FieldCount - 1
            sb.Append(",")
            sb.Append(Chr(34))
            sb.Append(reader.Item(i))
            sb.Append(Chr(34))
        Next
        'System.Console.Write("Loading rows to memory...\" & vbCr)



        sb.AppendLine()

        'Write every 10000 rows of data to the file from the buffer
        If x = 50000 Then
            StreamWriterObj.Write(sb.ToString().ToCharArray())
            MStream.Seek(0, SeekOrigin.Begin)
            MStream.WriteTo(FileObject)
            sb = New StringBuilder()
            CountRow = CountRow + x
            x = 0
        End If
        'System.Console.Write("Loading rows to memory...-" & vbCr)
        x = x + 1


        'LogEvents("Dumped " & strFileName & " to " & GetFilePath() & " at " & Now.ToString & vbCrLf & vbCrLf)
    Loop

    conn.Close()
    reader.Close()
    'Write any remaining data from the buffer to the file
    StreamWriterObj.Write(sb.ToString().ToCharArray())
    MStream.WriteTo(FileObject)
    FileObject.Close()

    System.Console.WriteLine(String.Format(vbCrLf & "Finished writing data to {1}", CountRow, csvFileName))

End Sub
like image 45
Doug Chamberlain Avatar answered Oct 25 '22 22:10

Doug Chamberlain