Question

Nous avons des informations que nous avons besoin d'écrire (environ 18 Ko) dans un fichier .txt stocké sur un de nos lecteurs réseau. Le fichier est réécrite environ une fois toutes les 15 minutes, mais il est lu pratiquement au moins tous les deux. Nous utilisons actuellement StreamWriter pour écrire le fichier.

Le serveur de fichiers se trouve dans un endroit éloigné et le ping aller-retour varie de moins de 1 ms à 15 ms.

Le problème est, il faut parfois aussi longtemps que six secondes pour écrire le contenu du fichier, ce qui est sans aucun doute trop longtemps, même après que nous prenons compte de la vitesse du réseau.

Par conséquent, je me demande s'il y a un moyen efficace d'écrire le fichier en utilisant VB.NET pour améliorer les performances? Java a un très bon outil nommé BufferedOutputStream, qui est malheureusement pas disponible en VB.NET (ou je viens pas trouvé).

Était-ce utile?

La solution

L'option la plus rapide:

Collect tout votre texte dans une grande chaîne, puis utilisez System.IO.File.WriteAllText(text).

Autres conseils

Cette fonction a été écrit à lire à partir d'une base de données et la sortie vers un fichier texte. S'il vous plaît ne hésitez pas à l'utiliser comme point de départ.

 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

Considérez ces facteurs:

  1. Créez le fichier local
  2. Copiez le dossier à distance avec une extension temporaire
  3. Renommer le fichier distant à votre nom de fichier original

Étape 2 et 3 est le suivant (en utilisant System.IO):

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 première File.Copy prend le temps. Mais comme il ne se verrouille pas les gens fichier réel utilisent, il ne soit pas verrouillé. La deuxième File.Copy fait juste renomme le fichier et remplace le fichier réel avec celui qui vient téléchargé. File.Delete supprime le fichier temporaire téléchargé.

L'espoir qui aide.

Il y a deux choses qui entrent en vigueur ici. Mais j'ai trouvé que l'utilisation de IO.File.AppendText fonction accélère les processus d'écriture énormément.

De plus, en utilisant la classe System.Text.StringBuilder par opposition comme une chaîne traditionnelle (en supposant que vous concating le texte à écrire dans un fichier) améliore la vitesse encore plus.

Voir Accélération fichier écriture .

Un vieux fil, mais je pense qu'il ya encore quelque chose à ajouter:

Ecrire tous les textes à la fois en utilisant:
System.IO.File.WriteAllText (chemin As String, contenu As String).

Cependant, il faudra encore du temps pour écrire le fichier si elle est en cours d'écriture sur une connexion lente à un emplacement distant. Pour éviter d'avoir des utilisateurs lire un fichier partiellement écrit, vous devez écrire les données dans un fichier temporaire sur le serveur distant. Une fois que toutes les données ont été écrites, copiez le fichier temporaire sur l'ancien fichier, puis supprimez le fichier temporaire.

Si vous voulez être vraiment que personne ne lit un fichier partiellement écrit, vous pouvez supprimer l'ancien fichier, puis déplacer / renommer le fichier temporaire pour remplacer le fichier que vous venez de supprimer. Dans ce cas, vous devez vous assurer que les programmes clients gèrent gracieusement fichier des erreurs ne trouve pas qui va inévitablement se produire de temps à autre.

Pensez à écrire à un lecteur local d'abord, puis en déplaçant ce fichier sur votre lecteur réseau.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top