User 13204940 Ответов: 1

Запись в файл кусками


Привет
Я пытаюсь записать байты в файл кусками размера chunkSize. Это очень медленно с большими файлами, например 9 МБ, и мне нужно найти способ сделать это намного быстрее.

For i As Integer = 0 To If(remainder = 0, 0, 1) + ((contents.Length - remainder) / blockSize)
    If contents.Length < i * blockSize Then
        IO.File.WriteAllBytes(outputPath, contents.Skip(i * blockSize).Take(blockSize).ToArray())
    Else
        IO.File.WriteAllBytes(outputPath, contents.Skip(i * blockSize).Take(contents.Length - (i * blockSize)).ToArray())
    End If
Next


Идея состоит в том, чтобы либо записать размер блока (4096) байт, либо то, что осталось в конце, если количество байтов не является идеальным кратным размеру блока.

Что я уже пробовал:

Различные формы этой функции

Richard MacCutchan

Что такое contents, что вам нужно каждый раз добавлять к нему эти три метода?

1 Ответов

Рейтинг:
0

OriginalGriff

Зачем ты это делаешь?
Все, что вы делаете, это ужасно замедляете все это - потому что вам приходится выделять новый массив каждый раз, когда вы пишете, и вы уничтожаете все предыдущие данные в файле: вот что делает WriteAllBytes!

Цитата:
Создает новый файл, записывает указанный массив байтов в файл, а затем закрывает файл. Если целевой файл уже существует,он перезаписывается.

Файл.Метод WriteAllBytes (String, Byte []) (System.IO)[^]
Поскольку размер вашего блока составляет 4096 байт, это означает, что для этого вы выделяете более 2000 новых массивов!

Во-первых, для .NET 9 МБ-это не такой уж большой файл: один WriteAllBytes с массивом 9 МБ будет настолько быстрым, насколько файловая система сможет справиться с ним (и это довольно быстро, она знает гораздо больше о размерах блоков и кэшах, чем вы!).
Во-вторых, если вы хотите писать кусками, то откройте один поток вне цикла и используйте файловый поток.Метод Записи (Byte [], Int32, Int32) (System.IO)[^] для вывода каждого фрагмента - он предоставляет параметры смещения и длины только для этой цели без необходимости выделять память для каждого фрагмента. Но... это все равно будет медленнее, чем писать все сразу!


[no name]

Это связано с шифрованием, мне нужно, чтобы данные были в кусках той же длины, что и ключ.

Richard Deeming

Но вы каждый раз переписываете весь файл через цикл!

И ты ничего не меняешь. outputPath, так что это не похоже на то, что вы пишете в разные файлы.

Если вам нужен только последний блок байтов в файле, то замените цикл его последней итерацией.

Если вам нужны все байты в одном файле, то просто запишите их в файл. Нет никакой разницы между записью 9 МБ в файл за один удар и записью его несколькими меньшими кусками.

Если вы хотите, чтобы куски были в разных файлах, то вам нужно будет изменить outputPath на каждой итерации.