Swift - объединить файлы
Как я могу объединить файлы в Swift / iOS? FileManager
могу перемещать и копировать элементы, но я ничего не видел о слиянии файлов. Я хотел бы иметь что-то вроде
FileManager.default.merge(files: [URL], to location: URL) throws
Файлы могут быть большими, поэтому я бы предпочел не передавать их данные в память.
=== вот мое собственное слияние в памяти:
let data = NSMutableData()
files.forEach({ partLocation in
guard let partData = NSData(contentsOf: partLocation) else { return }
data.append(partData as Data)
do {
try FileManager.default.removeItem(at: partLocation)
} catch {
print("error \(error)")
}
})
data.write(to: destination, atomically: true)
2 ответа
Решение
Вот мое собственное решение (спасибо @Alexander за руководство)
extension FileManager {
func merge(files: [URL], to destination: URL, chunkSize: Int = 1000000) throws {
try FileManager.default.createFile(atPath: destination.path, contents: nil, attributes: nil)
let writer = try FileHandle(forWritingTo: destination)
try files.forEach({ partLocation in
let reader = try FileHandle(forReadingFrom: partLocation)
var data = reader.readData(ofLength: chunkSize)
while data.count > 0 {
writer.write(data)
data = reader.readData(ofLength: chunkSize)
}
reader.closeFile()
})
writer.closeFile()
}
}
func merge(files: [URL], to destination: URL, chunkSize: Int = 100000000) {
for partLocation in files {
// create a stream that reads the data above
let stream: InputStream
stream = InputStream.init(url: partLocation)!
// begin reading
stream.open()
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: chunkSize)
// var writeData : Data = Data()
while stream.hasBytesAvailable {
let read = stream.read(buffer, maxLength: chunkSize)
var writeData:Data = Data()
writeData.append(buffer, count: read) enter code here
if let outputStream = OutputStream(url: destination, append: true) {
outputStream.open()
writeData.withUnsafeBytes { outputStream.write($0, maxLength: writeData.count) }
outputStream.close()
writeData.removeAll()
}
}
stream.close()
buffer.deallocate(capacity: chunkSize)
}
}