Эффективный способ записи в текстовый файл в vb.net

StackOverflow https://stackoverflow.com/questions/4786281

Вопрос

У нас есть некоторая информация, которую нам нужно написать (около 18 КБ) в файл .txt, хранящийся на одном из наших сетевых дисков. Файл переписывается примерно раз в 15 минут, но он читается практически, по крайней мере, каждую секунду. В настоящее время мы используем Streamwriter для написания файла.

Файл -сервер находится в удаленном месте, а пинг -обратно варьируется от менее 1 мс до 15 мс.

Проблема в том, что иногда требуется шесть секунд, чтобы написать содержимое в файл, что определенно слишком долго даже после того, как мы рассмотрим скорость сети.

Поэтому мне просто интересно, есть ли какой -либо эффективный способ написать файл с помощью vb.net для повышения производительности? У Java есть очень хороший инструмент под названием BufferedOutputStream, который, к сожалению, недоступен в VB.NET (или я просто не нашел его).

Это было полезно?

Решение

Самый быстрый вариант:

Сначала соберите весь свой текст в одну большую строку, а затем используйте System.IO.File.WriteAllText(text).

Другие советы

Эта функция была записана для чтения из базы данных и вывода в текстовый файл. Пожалуйста, не стесняйтесь использовать его в качестве отправной точки.

 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

Рассмотрим это в свою очередь:

  1. Создайте файл локально
  2. Скопируйте его в удаленную папку с временным расширением
  3. Переименовать удаленный файл в исходное имя файла

Шаг 2 и 3 заключаются в следующем (с использованием 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);

Первый файл.copy занимает время. Но поскольку он не блокирует настоящий файл, который используют люди, он не заблокирован. Второй файл.copy на самом деле просто переименовает файл и заменяет реальный файл на то, что только что загружен. File.delete Удаляет загруженный временный файл.

Надеюсь, это поможет.

Здесь вступают в силу пару вещей. Но я обнаружил, что использует Io.file.appendtext Функция значительно ускоряет процессы написания.

Кроме того, использование класса System.Text.StringBuilder, в отличие от традиционной строки (при условии, что вы согласны с текстом для записи в файл), улучшает скорость еще больше.

Видеть Ускорение написания файлов.

Старая ветка, но я думаю, что еще есть что добавить:

Напишите весь текст сразу, используя:
System.io.file.writealltext (путь как строка, содержимое как строка).

Однако, чтобы написать файл, если он будет записан на медленное соединение с удаленным местоположением. Чтобы пользователи не читали частично написанный файл, вы должны записать данные во временный файл на удаленном сервере. После того, как все данные записаны, скопируйте временный файл через старый файл, а затем удалите временный файл.

Если ты хочешь быть В самом деле Конечно, никто не читает частично написанный файл, вы можете удалить старый файл, а затем переместить/переименовать временный файл, чтобы заменить только что удаленный файл. В этом случае вы должны убедиться, что клиентские программы изящно обрабатывают файл, не найденные ошибки, которые неизбежно случаются время от времени.

Сначала подумайте о том, чтобы написать на локальный диск, а затем перенести этот файл на свой сетевой диск.

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top