Основная ошибка здесь:
let read = self.sessionController.readFile(handle, data: bufferPointer, len: singleSize)
Если вы читаете несколькими порциями, то второе и все последующие чтения будут перезаписывать данные, прочитанные ранее.Так что это, вероятно, должно быть
let read = self.sessionController.readFile(handle, data: bufferPointer + sum, len: singleSize)
Обратите также внимание, что размер файла определен как UInt64
, но переменная sum
(которая содержит общее количество прочитанных байтов) - UInt32
,Это приведет к проблемам, если данных больше 4 ГБ.
Но обычно я бы не считывал полные данные в буфер памяти.Вы уже прочитали порциями, поэтому вы можете сразу записать данные в файл назначения.Вот как это может выглядеть:
// Output file:
let fileURL = ...
let fileHandle = try FileHandle(forWritingTo: fileURL)
defer { fileHandle.closeFile() }
// Buffer:
let bufferSize = 1024 * 1024 // Choose some buffer size
var buffer = Data(count: bufferSize)
// Read/write loop:
let fileSize: UInt64 = file.size
var remainingToRead = fileSize
while remainingToRead > 0 {
let read = buffer.withUnsafeMutableBytes { bufferPointer in
self.sessionController.readFile(handle, data: bufferPointer, len: UInt32(min(remainingToRead, UInt64(bufferSize))))
}
if read == 0 {
return // Read error
}
remainingToRead -= UInt64(read)
fileHandle.write(buffer)
}
Обратите также внимание, что данные считываются непосредственно в значение Data
, а не считываются в выделенную память и затем копируются в другую Data
.