2017-01-15 7 views
0

Wie kann ich Dateien in Swift/iOS zusammenführen? Die FileManager kann Elemente verschieben und kopieren, aber ich habe nichts über das Zusammenführen von Dateien gesehen. Ich möchte etwas haben, wieSwift - Dateien zusammenführen

FileManager.default.merge(files: [URL], to location: URL) throws

Dateien potenziell groß sein können, so dass ich lieber vermeiden, dass ihre Daten im Speicher übergeben.

=== hier ist meine eigene im Speicher merge:

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) 
+1

gibt es immer die Möglichkeit des Kochens dein eigenes. Lesen Sie nacheinander aus jeder Datei, während Sie an das Ziel schreiben. – Alexander

+1

Aber gibt es etwas wie "an das Ziel anhängen"? Wenn möglich, möchte ich vermeiden, die gesamte Datei zu lesen und dann zu schreiben, um die Speicherbelegung zu begrenzen. – Guig

+1

Deshalb haben Sie 'FileHandle.readData (ofLength: Int)'. Sie können eine Schleife erstellen, die etwa 4 KB große Blöcke liest und in die Ausgabe schreibt. Den Puffer größer zu machen, würde die Leistung erhöhen, indem der Overhead des Kernel-Kontext-Switching minimiert wird, würde aber mehr Speicher benötigen. – Alexander

Antwort

1

Hier ist meine eigene Lösung (dank @Alexander für die Führung)

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() 
    } 
} 
+0

Merging funktioniert gut, jede Idee, wie Speicherproblem beim Zusammenführen von großen Dateien zu behandeln? – sujay

+0

ChunkSize steuert, wie viel Speicher verwendet wird – Guig

+0

und wie können wir es löschen, wenn wir große Datei zusammenführen.?. – sujay

0
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) 

     } 
    } 
Verwandte Themen