ZIPFoundation icon indicating copy to clipboard operation
ZIPFoundation copied to clipboard

Unzip aborts when a file being unzipped already exists

Open thomfriedel opened this issue 7 years ago • 8 comments

Summary

Unzip aborts when a file being unzipped already exists

not unzipped Error Domain=NSCocoaErrorDomain Code=516 "The file “Painted_Bunting_184832.jpg” couldn’t be saved in the folder “Documents” because a file with the same name already exists." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/9C36C53F-A273-4C59-BCFB-241CA89ED18F/Documents/Painted_Bunting_184832.jpg}

I think there should be a way to configure abort/overwrite/skip for this situation. I need anything but abort. How can I change that? Thanks!

Steps to Reproduce

Expected Results

Actual Results

Regression & Version

Related Link

thomfriedel avatar Mar 17 '18 16:03 thomfriedel

The unzipItem method in the FileManager extension currently only supports simple extraction of an archive to an empty destination. I plan to add a delegate protocol (similar to the FileManagerDelegate of Foundation) in the future. This will allow custom actions before- or after individual entry extraction.

In the meantime, you can manually instantiate an Archive and iterate over all entries:

guard let archive = Archive(url: archiveURL, accessMode: .read) else  {
    return
}
for entry in archive {
    // Perform extraction here and skip for already existing entries
     try? archive.extract(entry, to: destinationURL)
}

weichsel avatar Mar 19 '18 09:03 weichsel

thanks,

On Mon, Mar 19, 2018 at 4:40 AM, Thomas Zoechling [email protected] wrote:

The unzipItem method in the FileManager extension currently only supports simple extraction of an archive to an empty destination. I plan to add a delegate protocol (similar to the FileManagerDelegate https://developer.apple.com/documentation/foundation/filemanagerdelegate of Foundation) in the future. This will allow custom actions before- or after individual entry extraction.

In the meantime, you can manually instantiate an Archive and iterate over all entries:

guard let archive = Archive(url: archiveURL, accessMode: .read) else { return }for entry in archive { // Perform extraction here and skip for already existing entries try? archive.extract(entry, to: destinationURL) }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/weichsel/ZIPFoundation/issues/54#issuecomment-374153216, or mute the thread https://github.com/notifications/unsubscribe-auth/Aeu_-d0jt47Xscc3NM5TaL4cg0ZDEEAiks5tf30WgaJpZM4Su3pd .

thomfriedel avatar Mar 19 '18 16:03 thomfriedel

Hi @weichsel

I want to extract each files in .zip into a folder. And this folder has other files which can not be removed. So I need to extract my default data from .zip into that folder which default data sometimes modified.

How could I replace the existing file? I do the solution like above which you provide. But still face the same error.

Error Domain=NSCocoaErrorDomain Code=516 "The file “acc_head077_ch011.png” couldn’t be saved in the folder “DefaultData” because a file with the same name already exists." " UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/71AD1914-4645-43D8-ACB2-14199BF24A65/Documents/AvatarDefaultData/acc_head077_ch011.png}

Here is my code

guard let archive = Archive(url: sourceURL, accessMode: .read) else {
        return
}
for entry in archive {
  let destinationEntryURL = destinationURL.appendingPathComponent(entry.path)
  _ = try archive.extract(entry, to: destinationEntryURL)
}

What do I miss?

Thanks for the reply

lyc2345 avatar Jan 21 '19 03:01 lyc2345

You have to manually check for the items existence and then remove it via FileManager.removeItem(at:).

weichsel avatar Jan 21 '19 07:01 weichsel

Got it! Thanks so much

lyc2345 avatar Jan 21 '19 09:01 lyc2345

The unzipItem method in the FileManager extension currently only supports simple extraction of an archive to an empty destination. I plan to add a delegate protocol (similar to the FileManagerDelegate of Foundation) in the future. This will allow custom actions before- or after individual entry extraction.

In the meantime, you can manually instantiate an Archive and iterate over all entries:

guard let archive = Archive(url: archiveURL, accessMode: .read) else  {
    return
}
for entry in archive {
    // Perform extraction here and skip for already existing entries
     try? archive.extract(entry, to: destinationURL)
}

I've trying to do this but the performance is so terrible. Has any way to make it faster

tranty9597 avatar Dec 11 '19 08:12 tranty9597

Are you running a debug build? There is a huge difference between debug and release builds.
You can also try to pass skipCRC32: true during extraction. This skips checksum calculations, which also speeds up extraction.

weichsel avatar Dec 11 '19 08:12 weichsel

Any news?

NikKovIos avatar Mar 23 '23 13:03 NikKovIos