Ошибка памяти при преобразовании большого видеофайла в NSData.Как использовать InputStream / FileHandle, чтобы исправить эту проблему? - PullRequest
0 голосов
/ 23 сентября 2019

В моем каталоге документов сохранено видео большого размера.Я хочу получить это видео и удалить его первые 5 байт.Для больших видеофайлов размером более 300 МБ, использующих [NSData (contentsOf: videoURL)], вызывающих ошибку памяти.

Я прошел Swift: загрузка большого видеофайла (более 700 МБ) в память и обнаружил, что нам нужно использовать [InputStream] и [OutputStream] или [NSFileHandle] для больших файлов,Как это использовать?

Пример кода приведен ниже:

   let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
   let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
   let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
   if let dirPath = paths.first{
      let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(filePath)
          do {
                let videoData = try NSData(contentsOf: videoURL)
                let mutabledata = videoData.mutableCopy() as! NSMutableData
                mutabledata.replaceBytes(in: NSRange(location: 0, length: 5), withBytes: nil, length: 0)
   }catch {
       print("Error Writing video: \(error)")
   }

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Решил эту проблему, используя InputStream / OutputStream.

Я использовал InputStream для чтения видео, удалил его первые 5 байтов с помощью метода dropFirst () Array и сохранил новые данные с помощью OutputStream.write ().

Пример кода:

func read(stream : InpuStream){
        let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: totalLength)
        while stream.hasBytesAvailable {
            let length = self.inputStream.read(buffer, maxLength: totalLength)
            if(length == totalLength){
                let array = Array(UnsafeBufferPointer(start: buffer, count: totalLength))
                var newArray: [UInt8] = []
                newArray = [UInt8](array.dropFirst(5))
            }
    }
    func write(){
        let data = Data(_: newArray)
        data.withUnsafeBytes({ (rawBufferPointer: UnsafeRawBufferPointer) -> Int in
            let bufferPointer = rawBufferPointer.bindMemory(to: UInt8.self)
            return self.outputStream.write(bufferPointer.baseAddress!, maxLength: data.count)
        })
    }
0 голосов
/ 24 сентября 2019

Это работает для меня, чтобы изменить первые 4 байта, и я не получаю предупреждения об устаревании.

let input = FileHandle(forWritingAtPath: "/tmp/test.in")!
input.write("12345".data(using: .utf8)!)
...