复制目标文件夹不存在的文件

时间:2021-01-03 20:26:57

标签: swift swift5 file-copying

我正在编写一个应用程序来批量导入文件。我已经完成了大部分工作,但是当目标文件夹不存在时,该过程会停止。

这是代码的简化版本:

let fm = FileManager.default
do {
    try fm.copyItem(atPath: "/…/source/file.ext",toPath: "/…/destination/NewFolder/file.ext")
}
catch let error as NSError {
    print("Drat: \(error)")
}

在这种情况下,需要创建 NewFolder。如果我不这样做,我会收到类似以下内容的消息:

<块引用>

Drat: Error Domain=NSCocoaErrorDomain Code=4 “文件“file.ext”不存在。 UserInfo={NSSourceFilePathErrorKey=/…/source/file.ext, NSUserStringVariant=( 复制 )、NSDestinationFilePath=/…/destination/NewFolder/file.ext、NSFilePath=/…source/file.ext、NSUnderlyingError=0x7fbaa9071270 {Error Domain=NSPOSIXErrorDomain Code=2“没有这样的文件或目录”}}

认为这意味着目标文件夹不存在,尽管从消息中根本看不出来。我发现如果我删除目标的 NewFolder/ 部分,文件复制成功。

如何快速创建丢失的目标文件夹。

我可能会补充说,作为批量复制,将创建多个丢失的目标文件夹。

1 个答案:

答案 0 :(得分:0)

也许这太复杂或者代码太多,但你有没有尝试过这种方式?

/// This method copies the objects in the pathList from the given sourceURL to the targetURL. If the object in the pathList is a folder the existence is being checked by calling
/// checkExistenceOf(path: String, at sourcePath: String, in targetPath: String). If the object is not a directory, the object is copied from the source to the target. The delegate is expected to
/// handle the conflict options set by the user.
/// - Parameters:
///   - sourceURL: The source folder from where the objects are being copied.
///   - targetURL: The target folder to where the objects need to be copied.
///   - pathList: The objects that need to be copied.
private func copy(sourceURL: URL, to targetURL: URL, with pathList: [String]) {
    
    for path in pathList {
        
        let fullSourceURL = sourceURL.appendingPathComponent(path)
        let reportPath = path
        let reportSource = fullSourceURL.lastPathComponent.replacingOccurrences(of: "%20", with: " ")
        let reportTarget = targetURL.path

        if fullSourceURL.hasDirectoryPath {
            //The path is a directory and we are checking the existence.
            checkExistenceOf(path: path, at: sourceURL, in: targetURL)

        } else {
            //The path is a file and we are going to copy it.
            let fullTargetURL = targetURL.appendingPathComponent(path)
            
            do {
                try mainFileManager.manager.copyItem(at: fullSourceURL, to: fullTargetURL)
            } catch {
                print(error.localizedDescription)
            }
        }
    }
}

然后使用方法 checkExistenceOf() 像这样:

/// This method checks if a folder in the source location already exists in the target location. If the folder does not exist at the target, the folder is created by the method.
/// - Parameters:
///   - path: The folder that needs to be checked.
///   - sourcePath: The source location where the path already exists.
///   - targetPath: The target location where the existence of path is being chekced.
private func checkExistenceOf(path: String, at sourceURL: URL, in targetURL: URL) {
    
    //The function fileExists can't deal with the %20 for space and the file:// for the source and target.
    let sourcePath = sourceURL.relativePath
    let targetPath = targetURL.relativePath
    let fullSourcePath = String(sourcePath + "/" + path)
    let fullTargetPath = String(targetPath + "/" + path)
    
    //If the path doesn't exist create the folder at target with the same attributes as pth at source.
    if !mainFileManager.manager.fileExists(atPath: fullTargetPath) {
        
        let newDirectory = targetURL.appendingPathComponent(path)
        
        do {
            let attributes = try mainFileManager.manager.attributesOfItem(atPath: fullSourcePath)
            try mainFileManager.manager.createDirectory(at: newDirectory, withIntermediateDirectories: false, attributes: attributes)
            
        } catch {
            print(error.localizedDescription)
        }
    }
}

代码来自之前的一个项目。我很抱歉没有擦洗它。

希望它以任何方式帮助您。

亲切的问候, MacUserT