简体   繁体   English

使用ZipArchive但不使用ZipFile时出现c#UnauthorizedAccessException

[英]c# UnauthorizedAccessException when using ZipArchive but not ZipFile

I am able to zip files from a specific folder using ZipFile.CreateFromDirectory in the following test code (I only used this code to test how zipping works): 我可以在以下测试代码中使用ZipFile.CreateFromDirectory从特定文件夹压缩文件(我仅使用此代码来测试压缩的工作方式):

// Where the files are located
string strStartPath = txtTargetFolder.Text;

// Where the zip file will be placed
string strZipPath = @"C:\Users\smelmo\Desktop\testFinish\" + strFileNameRoot + "_" + txtDateRange1.Text.Replace(@"/", "_") + "_" + txtDateRange2.Text.Replace(@"/", "_") + ".zip";

ZipFile.CreateFromDirectory(strStartPath, strZipPath);

However, this zips together ALL of the contents in the folder. 但是,这会将文件夹中的所有内容压缩在一起。 I am trying to zip together specific items in the folder using ZipArchive in the following code: 我正在尝试使用ZipArchive在以下代码中将文件夹中的特定项目压缩在一起:

// Where the files are located
string strStartPath = txtTargetFolder.Text;

// Where the zip file will be placed
string strZipPath = @"C:\Users\smelmo\Desktop\testFinish\" + strFileNameRoot + "_" + txtDateRange1.Text.Replace(@"/", "_") + "_" + txtDateRange2.Text.Replace(@"/", "_") + ".zip";

using (ZipArchive archive = ZipFile.OpenRead(strStartPath))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        if (!(entry.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
        {
            entry.ExtractToFile(Path.Combine(strZipPath, entry.FullName));
         }
     }
 }

It is giving the error at ZipFile.OpenRead(strStartPath) . 它在ZipFile.OpenRead(strStartPath)处给出错误。 Why am I able to access the exact folder in the first block of code but not the second? 为什么我可以在第一个代码块中访问确切的文件夹,但不能访问第二个代码块? Or is there an easier way to search through a folder and only zip specific items? 还是有一种更简单的方法来搜索文件夹并仅压缩特定项目?

You are utilizing the Zip libraries wrong 您错误地使用了Zip库

Effectively you are trying to open a directory as if it were a zip file, then loop over the contents of that directory (which again is actually a zip file) and then attempting to extract each member into a different zip file 实际上,您试图打开一个目录,就好像它是一个zip文件一样,然后遍历该目录的内容(实际上也是一个zip文件),然后尝试将每个成员提取另一个zip文件中

Here is a working example of what you have described you are trying to do: 这是您正在尝试做的事的一个工作示例:

string strStartPath = @"PATH TO FILES TO PUT IN ZIP FILE";

string strZipPath = @"PATH TO ZIP FILE";

if (File.Exists(strZipPath))
    File.Delete(strZipPath);

using (ZipArchive archive = ZipFile.Open(strZipPath,  ZipArchiveMode.Create))
{
    foreach (FileInfo file in new DirectoryInfo(strStartPath).GetFiles())
    {
        if (!(file.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
        { 
            archive.CreateEntryFromFile(Path.Combine(file.Directory.ToString(), file.Name), file.Name);
        }
    }
}

This will take all the root level contents of a folder and put it in the zip file. 这将获取文件夹的所有根目录级内容,并将其放入zip文件中。 You will need to implement your own way of getting subfolders and their contents recursively, but that is beyond the scope of this question. 您将需要实现自己的递归获取子文件夹及其内容的方式,但这超出了此问题的范围。

EDIT: Here is a working example with proper folder recursion to select all files even in subdirectories 编辑:这是一个具有适当文件夹递归的工作示例,即使在子目录中也可以选择所有文件

public void ZipFolder()
{
    string strStartPath = @"PATH TO FILES TO PUT IN ZIP FILE";

    string strZipPath = @"PATH TO ZIP FILE";

    if (File.Exists(strZipPath))
        File.Delete(strZipPath);

    using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
    {
        foreach (FileInfo file in RecurseDirectory(strStartPath))
        {
            if (!(file.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
            {
                var destination = Path.Combine(file.DirectoryName, file.Name).Substring(strStartPath.Length + 1);
                archive.CreateEntryFromFile(Path.Combine(file.Directory.ToString(), file.Name), destination);
            }
        }
    }
}

public IEnumerable<FileInfo> RecurseDirectory(string path, List<FileInfo> currentData = null)
{
    if (currentData == null)
        currentData = new List<FileInfo>();   

    var directory = new DirectoryInfo(path);

    foreach (var file in directory.GetFiles())
        currentData.Add(file);

    foreach (var d in directory.GetDirectories())
        RecurseDirectory(d.FullName, currentData);
    return currentData;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM