Domanda

Abbiamo alcune informazioni che abbiamo bisogno di scrivere (circa 18 KB) in un file .txt memorizzati su una delle nostre unità di rete. Il file viene riscritto circa una volta ogni 15 minuti, ma si legge praticamente almeno ogni secondo. Attualmente stiamo utilizzando StreamWriter per scrivere il file.

Il file server è in una posizione remota e il viaggio ping giro varia da meno di 1 ms a 15 ms.

Il problema è, a volte ci vuole fino a sei secondi per scrivere il contenuto del file, che è sicuramente troppo lungo anche dopo che prendiamo considerazione della velocità della rete.

Quindi, mi chiedo solo se non v'è alcun modo efficiente per scrivere il file utilizzando VB.NET per migliorare le prestazioni? Java ha un ottimo strumento chiamato BufferedOutputStream, che purtroppo non è disponibile in VB.NET (o io non l'ho trovato).

È stato utile?

Soluzione

L'opzione più veloce:

raccogliere tutti il ??testo in una stringa di grandi dimensioni e poi usare System.IO.File.WriteAllText(text).

Altri suggerimenti

Questa funzione è stata scritta per leggere da un database e output in un file di testo. Sentitevi liberi di utilizzarlo come punto di partenza.

 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

Si consideri questi a loro volta:

  1. Crea il file in locale
  2. copiarlo nella cartella remota con una proroga temporanea
  3. Rinominare il file remoto al nome del file originale

Fase 2 e 3 è (using System.IO) come segue:

string OriginalExtension = ".ok", TemporaryExtension = ".dat";
string tmpFileRemote = RemoteFile.Replace(TemporaryExtension, OriginalExtension);
File.Copy(fileName, RemoteFile, true);
File.Copy(RemoteFile, tmpFileRemote, true);
File.Delete(RemoteFile);

La prima File.Copy prende il tempo. Ma dato che non blocca il file vero e proprio le persone utilizzano, non ottiene bloccato. Il secondo File.Copy in realtà solo rinomina il file e sostituisce il file vero e proprio con quello appena caricato. File.Delete elimina il file temporaneo caricato.

La speranza che aiuta.

Ci sono un paio di cose che entrano in vigore qui. Ma ho scoperto che utilizzando il IO.File.AppendText la funzione accelera i processi di scrittura immensamente.

Inoltre, utilizzando la classe System.Text.StringBuilder al contrario come una stringa tradizionale (supponendo che si sta concating il testo di scrivere in un file) migliora la velocità ancora di più.

Vedere Accelerare la scrittura del file .

Un vecchio thread, ma penso che ci sia ancora qualcosa da aggiungere:

Scrivi tutto il testo in una sola volta utilizzando:
System.IO.File.WriteAllText (percorso come stringa, il contenuto come stringa).

Tuttavia ci vorrà ancora tempo per scrivere il file se si scrive su una connessione lenta a una postazione remota. Per evitare di avere gli utenti di leggere un file parzialmente scritta si dovrebbe scrivere i dati in un file temporaneo sul server remoto. Una volta che tutti i dati sono stati scritti, copiare il file temporaneo del vecchio file e quindi eliminare il file temporaneo.

Se vuoi essere davvero che nessuno legge un file parzialmente scritta è possibile eliminare il vecchio file e quindi spostare / rinominare il file temporaneo per sostituire il file appena cancellato. In questo caso è necessario assicurarsi che i programmi client con grazia gestiscono file di errori che non si trovano che inevitabilmente accadere di tanto in tanto.

Si consideri la scrittura su un disco locale prima, per poi passare il file sul disco di rete.

Sub writefile()
    Dim file As System.IO.StreamWriter
    file = My.Computer.FileSystem.OpenTextFileWriter("N:\GeneratedNumber.txt", False)
    file.WriteLine("Player1 Skill is " & Skill(0))
    file.WriteLine("Player1 Strength is " & Skill(1))
    file.WriteLine("Player2 Skill is " & Skill(2))
    file.WriteLine("Player2 Strength is " & Skill(3))
    file.Close()
End Sub
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top