Допустим, у меня есть файл длиной 8 байтов, содержащий только символы ASCII: brownfox
.
Вместо загрузки всего файла и работы с if, я не хочу загружать блок из 2 байтов [UInt8]
и выполнять операции с блоками размером 2 байта, поэтому операции выполняются следующим образом:
- загрузить
br
из файла (а не весь файл)
- выполнить любые действия с данными, например, вернуться к
rb
- сохранить вывод в другой файл
- повторить для:
ow
nf
ox
Причина этого:
Таким образом, если я обрабатываю файл объемом 1 ГБ, мне фактически не нужно иметь 1 ГБ свободной памяти (или 2 ГБ для файла ввода и вывода).
Этот метод для обработки файлов важен для меня для шифрования и отправки в облачные решения.
Я использую это расширение:
extension Data {
/**
Consumes the specified input stream, creating a new Data object
with its content.
- Parameter reading: The input stream to read data from.
- Note: Closes the specified stream.
*/
init(reading input: InputStream) {
self.init()
input.open()
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
self.append(buffer, count: read)
}
buffer.deallocate()
input.close()
}
/**
Consumes the specified input stream for up to `byteCount` bytes,
creating a new Data object with its content.
- Parameter reading: The input stream to read data from.
- Parameter byteCount: The maximum number of bytes to read from `reading`.
- Note: Does _not_ close the specified stream.
*/
init(reading input: InputStream, for byteCount: Int) {
self.init()
input.open()
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: byteCount)
let read = input.read(buffer, maxLength: byteCount)
self.append(buffer, count: read)
buffer.deallocate()
}
}
Но init(reading input: InputStream, for byteCount: Int)
всегда идет от 1-го байта. Как я могу прочитать, например, с 16-го по 20-й байт?
Документация по InputStream.read(_:maxLength:)
Из текущего индекса чтения возьмите до указанного количества байтов
во втором параметре из потока и поместите их в
предоставленный клиентом буфер (первый параметр). Буфер должен быть
размер указан вторым параметром. Вернуть фактическое количество
байты, помещенные в буфер; если в потоке ничего не осталось,
return 0. Сбросить индекс в поток для следующей операции чтения.
Что я могу сделать, чтобы не сбросить индекс и получить следующую операцию из того места, где закончилась предыдущая?