将大视频文件路径转换为 NSData 时出现内存问题。如何使用 InputStream/FileHandle 来解决这个问题?
Memory issue while converting big video file path to NSData. How to use InputStream/FileHandle to fix this issue?
我的文档目录中保存了一个大尺寸的视频。我想检索此视频并删除它的前 5 个字节。
对于超过 300 MB 的大型视频文件,使用 [NSData(contentsOf: videoURL)] 会导致内存问题错误。
我经历过Swift: Loading a large video file (over 700MB) into memory
发现我们需要对大文件使用 [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)")
}
这对我来说适用于更改前 4 个字节,而且我没有收到弃用警告。
let input = FileHandle(forWritingAtPath: "/tmp/test.in")!
input.write("12345".data(using: .utf8)!)
使用 InputStream/OutputStream 解决了这个问题。
我已经使用 InputStream 读取视频,使用 Array 的 dropFirst() 方法删除了它的前 5 个字节,并使用 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)
})
}
我的文档目录中保存了一个大尺寸的视频。我想检索此视频并删除它的前 5 个字节。 对于超过 300 MB 的大型视频文件,使用 [NSData(contentsOf: videoURL)] 会导致内存问题错误。
我经历过Swift: Loading a large video file (over 700MB) into memory 发现我们需要对大文件使用 [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)")
}
这对我来说适用于更改前 4 个字节,而且我没有收到弃用警告。
let input = FileHandle(forWritingAtPath: "/tmp/test.in")!
input.write("12345".data(using: .utf8)!)
使用 InputStream/OutputStream 解决了这个问题。
我已经使用 InputStream 读取视频,使用 Array 的 dropFirst() 方法删除了它的前 5 个字节,并使用 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)
})
}