Swift iOSアプリケーションを使用して多数のファイルをダウンロードしています。コンテンツの増分更新を使用しています。Swift - ファイルの移動または更新に失敗しました
マイダウンロードコードはかなり基本的ですが、私は、一時ディレクトリにAlamofireを使用してファイルをダウンロードし、それを解凍し、ファイルまたはフォルダがターゲットディレクトリに存在するかどうかを確認、見つかった場合はそれを削除し、新しいファイルを移動します/フォルダに移動します。
ただし、既存のディレクトリを確認して削除することはほとんどありません。私はそのディレクトリに新しいファイル/フォルダを移動しようとすると、私は
のエラーが出る「ファイルまたはディレクトリが既に存在するか、内容が空ではありません。」
しかし、デバイスディレクトリで失敗した後でそれを確認すると、完全に細かいディレクトリが表示されます。また、衝突する可能性のあるファイルがないか、新しいコンテンツが実際にターゲットディレクトリに移動されるそれは失敗したと言った。それが私を最も悩ますものです。
ディレクトリにファイルを保存して移動するときに、この種の動作をしたことがありますか?
私はほとんど忘れていました、私はアプリケーションのサポートディレクトリで働いています。
internal func loadArtifact(artifact: Artifact, updateClosure: @escaping ((Bool, Int64, Int64, String?) ->()))
{
let serverpath = artifact.serverpath
let name = artifact.name
let zipname = artifact.zipname
let root = artifact.artifactSetroot
let hidden = artifact.artifactSet!.hidden
let objectID = artifact.objectID
let baseArtifactSet = artifactSetManager.defaultartifactSetManager.getartifactSetDirectory(artifact.artifactSet!)
if baseArtifactSet == nil
{
errorLog("No target directory for artifactSet")
return
}
if name == nil
{
errorLog("No name for artifact. Can´t save in temp")
return
}
var targetDirectory = baseArtifactSet
targetDirectory?.appendPathComponent("temp")
targetDirectory?.appendPathComponent(zipname!.replacingOccurrences(of: ".zip", with: ""))
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
return (targetDirectory!, [.removePreviousFile, .createIntermediateDirectories])
}
let url = URL(string: serverpath!)
alamofireManager!.download(url!, to: destination).downloadProgress { (progress) in
updateClosure(false, progress.completedUnitCount, progress.completedUnitCount, nil)
}.responseData { (data) in
traceLog("\(data)")
if data.response?.statusCode == 200
{
traceLog("Got an artifact. Will continue to extract itto target position")
self.asyncQueue.async {
var unzipTarget = baseArtifactSet
SSZipArchive.unzipFile(atPath: targetDirectory!.path, toDestination: root ? "\(unzipTarget!.path)/temp/root" : "\(unzipTarget!.path)/temp", progressHandler: { (message, something, progress, max) in
}, completionHandler: { (message, finished, error) in
let tmpPath = root ? "\(unzipTarget!.path)/temp/root" : "\(unzipTarget!.path)/temp/artifacts/\(zipname!.replacingOccurrences(of: ".zip", with: ""))"
let targetPath = root ? unzipTarget!.path : "\(unzipTarget!.path)/artifacts/\(zipname!.replacingOccurrences(of: ".zip", with: ""))"
if error == nil && root == false && FileManager.default.fileExists(atPath: targetPath)
{
do
{
try FileManager.default.removeItem(atPath: targetPath)
traceLog("Deletet old directory at path: \(unzipTarget!.path)")
}catch
{
errorLog("Could not remove directory at path: \(unzipTarget!.path) - \(error)")
updateClosure(true,0,0,"Could not remove directory at path: \(unzipTarget!.path) - \(error)")
}
}
do
{
if FileManager.default.fileExists(atPath: "\(unzipTarget!.path)/artifacts") == false
{
try FileManager.default.createDirectory(atPath: "\(unzipTarget!.path)/artifacts", withIntermediateDirectories: true, attributes: nil)
}
if root
{
do{
let targetDirContent = try FileManager.default.contentsOfDirectory(atPath: targetPath)
for file in targetDirContent
{
if file != "artifacts" && file != "temp"
{
try FileManager.default.removeItem(atPath: "\(targetPath)/\(file)")
}
}
let files = try FileManager.default.contentsOfDirectory(atPath: tmpPath)
for file in files
{
let fileURL = URL(fileURLWithPath: "\(tmpPath)/\(file)")
if fileURL != nil
{
try FileManager.default.moveItem(atPath: fileURL.path, toPath: "\(targetPath)/\(file)")
}
}
if root && hidden
{
let deviceInfoString = "var deviceInfo={'platform':'iOS'}"
if FileManager.default.fileExists(atPath: "\(targetPath)/deviceInfo.js")
{
try FileManager.default.removeItem(atPath: "\(targetPath)/deviceInfo.js")
}
}
}
catch{
errorLog("Error while enumerating files in temp root directory: \(error)")
updateClosure(true,0,0,"Error while enumerating files in temp root directory: \(error)")
}
}else
{
if FileManager.default.fileExists(atPath: targetPath)
{
debugLog("Deleting: \(targetPath)")
try FileManager.default.removeItem(atPath: targetPath)
}else
{
debugLog("Creating: \(targetPath)")
}
debugLog("Trying to move")
try FileManager.default.moveItem(atPath: tmpPath, toPath: targetPath)
}
}catch
{
errorLog("Could not move directory for artifact: \(unzipTarget!.path) - \(error)")
updateClosure(true,0,0,"Could not move directory for artifact: \(unzipTarget!.path) - \(error)")
}
try FileManager.default.removeItem(atPath: targetDirectory!.path)
self.asyncQueue.async (flags: .barrier) {
let ownContext = MyStorageClient.defaultManager.newBackgroundWorkerMOC()
let ownArtifact = ownContext.object(with: objectID) as! Artifact
ownArtifact.state = ArtifactState.Ready.rawValue
ownArtifact.updateAvaiable = false
if root == true && ownArtifact.artifactSet?.state == artifactSetState.Initialised.rawValue
{
ownArtifact.artifactSet?.state = artifactSetState.Created.rawValue
}
do{
try ownContext.save()
updateClosure(true, 0,0,nil)
}catch{
errorLog("Error while saving artifact context")
updateClosure(true, 0,0, "Error while saving context after artifact Update. \(error)")
}
}
})
}
}else
{
errorLog("Something went wrong downloading an artifact: \(data.response)")
updateClosure(true,0,0,"Something went wrong downloading an artifact: \(data.response)")
}
}
}
だから誰も私に教えてもらえませんが、なぜ失敗していますか? 私はトライラインのほとんどの周りの試行ん-キャッチを追加し、それが失敗したとき、それは基本的に、このチャンクに失敗している:
if FileManager.default.fileExists(atPath: targetPath)
{
debugLog("Deleting: \(targetPath)")
try FileManager.default.removeItem(atPath: targetPath)
}else
{
debugLog("Creating: \(targetPath)")
}
debugLog("Trying to move")
try FileManager.default.moveItem(atPath: tmpPath, toPath: targetPath)
TARGETPATHがある: ファイル:/// VAR /モバイル/コンテナ/ Data/Application/applicationIdAndStuff/Library/Application%20Support/environment/workspace/customers/customer/temp/downloadFileOrFolder
別のアップデート: コードを変更したので、古いファイルは削除されずにバックアップフォルダに移動されます。私はアドレスを変更するほうがファイルを完全に削除するよりも速くなければならないと考えていたからです。違う。今度はエラーが以前よりも頻繁に発生します。
私の問題はFileManagerを参照しているため、手順を完了するのに時間がかかりすぎます。私はいつも私のブロックをいつでも寝たいと思っていません。あなたはこの問題をどう扱うかという別のアイディアを持っていますか?
あなたは、私が問題である部分の下に、完全なコード上に、更新した – zombie
のすべてを読むのが面倒だ、少ないコードを作ることができます。 –
@Viktor_DE、実行時の 'targetPath'の値は何ですか? – holex