【问题标题】:DotNetZip crashing when reading a zip file from UNC Path从 UNC 路径读取 zip 文件时 DotNetZip 崩溃
【发布时间】:2016-02-26 02:01:52
【问题描述】:

我围绕我在 VB6 应用程序中使用的 DotNetZip 库为 COM 创建了一个包装器(类库)。我在 XP 机器上使用包装器创建了一个示例应用程序,它工作正常。当我在 Windows Server 2008 R2 上创建安装程序并安装应用程序时,它无法从 UNC 路径读取 zip 文件。

以下是我的 C# 代码:

if (File.Exists(zipFileName))
{
    // check if the directory exists
    if (Directory.Exists(extractionPath))
    {
        // remove the directory
        Directory.Delete(extractionPath, true);
    }

    // recreate the directory
    Directory.CreateDirectory(extractionPath);

    // unzip the files
    using (ZipFile loZip = ZipFile.Read(zipFileName))
    {
        // Add this line to fix an issue with the DLL
        // http://dotnetzip.codeplex.com/workitem/14087
        loZip.ParallelDeflateThreshold = -1;

        loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
    }
}
else
{
    lsResult = "@@@Error - Zip file does not exist. ";
}

Zip 文件位于以下位置(这是一个共享的本地文件夹,因此我使用的是 UNC 路径,但这很可能位于网络位置)

    Zip File Name = '\\\\DEV-2012X\\1454444717051\\MB4.zip'

这是异常消息:

    Could not find file '\\DEV-2012X\1454444717051\MB4.zip'.

这是堆栈跟踪

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
    at Ionic.Zip.ZipFile.get_ReadStream()
    at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)
    at Ionic.Zip.ZipFile.Read(String fileName, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress)
    at Ionic.Zip.ZipFile.Read(String fileName)
    at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)

我可以从那台机器访问该文件夹,没有任何问题。我还尝试在 this 链接上使用 .net Impersonation,但这也无济于事。

感谢您对此进行调查

[编辑 - 1]

这是我尝试将流传递给 Read 方法的时候:

MemoryStream ms = new MemoryStream();

try
{
    using (FileStream file = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
    {
        byte[] bytes = new byte[file.Length];
        file.Read(bytes, 0, (int)file.Length);
        ms.Write(bytes, 0, (int)file.Length);
    }
}
catch (Exception ex)
{
    lsResult = "Stream reading crashed. " + ex.Message + Environment.NewLine + Environment.NewLine + ex.InnerException + Environment.NewLine + Environment.NewLine + ex.StackTrace + Environment.NewLine + Environment.NewLine;
}

// unzip the files
using (ZipFile loZip = ZipFile.Read(ms))
{
    // Add this line to fix an issue with the DLL
    // http://dotnetzip.codeplex.com/workitem/14087
    loZip.ParallelDeflateThreshold = -1;

    loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
}

以下是我得到的错误:

    Stream reading crashed. Could not find file '\\DEV-2012X\SLWatch\Test Everything1454444717051\MB4.zip'.

堆栈跟踪是:

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
    at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)

[/EDIT - 1]

[编辑 - 2]

以下是 ZipFile.Read 方法的签名:

public static ZipFile Read(string fileName)
public static ZipFile Read(System.IO.Stream zipStream)
public static ZipFile Read(string fileName, ReadOptions options)
public static ZipFile Read(System.IO.Stream zipStream, ReadOptions options)

[/EDIT - 2]

[编辑 - 3]

现在运行的代码:

public string UnZipAllContents(string zipFileName, string extractionPath)
{
    string lsResult = string.Empty;
    string lsRemoteComputerName = string.Empty;
    string lsStep = "1-";

    try
    {
        lsRemoteComputerName = Path.GetPathRoot(zipFileName);
        lsStep += "2," + lsRemoteComputerName + "-";

        lsStep += "3-";
        using (UNCAccessWithCredentials unc = new UNCAccessWithCredentials())
        {
            lsStep += "3.1-";
            bool lb = unc.NetUseWithCredentials(Path.GetPathRoot(zipFileName),
                                          "Bhatti",
                                          string.Empty,
                                          "MyPassword");

            lsStep += "4, " + lb.ToString() + "-";

            string[] dirs = Directory.GetFiles(Path.GetPathRoot(zipFileName), "*",SearchOption.AllDirectories);
            lsStep += "4.1,";
            foreach (string d in dirs)
            {
                lsStep += d + ",";
            }
            lsStep += "-";

            if (File.Exists(zipFileName))
            {
                lsStep += "5-";
                // check if the directory exists
                if (Directory.Exists(extractionPath))
                {
                    // remove the directory
                    Directory.Delete(extractionPath, true);
                }

                // recreate the directory
                Directory.CreateDirectory(extractionPath);

                lsStep += "6-";
                // unzip the files
                using (ZipFile loZip = ZipFile.Read(zipFileName))
                {
                    lsStep += "7-";
                    loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
                }
                lsStep += "8-";
            }
            else
            {
                lsResult += "@@@Error - Zip file does not exist. " + lsStep;
            }
        }
    }
    catch (Exception loException)
    {
        lsResult += lsStep + Environment.NewLine + "@@@Error - " + loException.Message + Environment.NewLine + Environment.NewLine + loException.InnerException + Environment.NewLine + Environment.NewLine + loException.StackTrace;
    }

    return lsResult;
}

这是创建的日志:

    1-2,\\DEV-2012X\SLWatch-3-3.1-4, True-4.1,\\DEV-2012X\SLWatch\BW123.zip,\\DEV-2012X\SLWatch\1454444717051.xml,\\DEV-2012X\SLWatch\1454444717051\MB4.zip,-5-6-

    @@@Error - Could not find file '\\DEV-2012X\SLWatch\1454444717051\MB4.zip'.

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
    at Ionic.Zip.ZipFile.get_ReadStream()
    at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)
    at Ionic.Zip.ZipFile.Read(String fileName, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress)
    at Ionic.Zip.ZipFile.Read(String fileName)
    at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)

[/EDIT - 3]

【问题讨论】:

  • 你能传递文件流而不是 zipfile.read 的路径吗?
  • 很可能是权限错误。
  • @SteveWellens:我已授予“所有人”对该文件夹的完全权限。
  • @MigueldeSousa:让我尝试这样做,我会尽快回复您。
  • @SteveWellens:这就是我的想法,不知何故,当 Bhatti 调用包装器时,它会失去当前用户。将文件读入流可能是一种更简单的解决方法。

标签: c# dotnetzip


【解决方案1】:

您的问题在于文件访问,例外就是证明

因为您尝试将文件加载到内存流中,您捕获了 FileNotFoundException 但您的代码继续运行,因此您从空的 MemoryStream 中收到来自 DotNetZip 的另一个错误。

你的代码应该是这样的:

MemoryStream ms = new MemoryStream();
bool success;
try
{    
    if(File.Exists(zipFileName))
    {
        using (FileStream file = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
        {
            byte[] bytes = new byte[file.Length];
            file.Read(bytes, 0, (int)file.Length);
            ms.Write(bytes, 0, (int)file.Length);
        }


        // unzip the files
        using (ZipFile loZip = ZipFile.Read(ms))
        {
            // Add this line to fix an issue with the DLL
            // http://dotnetzip.codeplex.com/workitem/14087
            loZip.ParallelDeflateThreshold = -1;

            loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
        }
      success = true;
    }
    else
    {
      lsResult = "ZipFile Not Found";
      success = false;
    }
 }
catch (Exception ex)
{
      success = false;
    lsResult = "Stream reading crashed. " + ex.Message + Environment.NewLine + Environment.NewLine + ex.InnerException + Environment.NewLine +     Environment.NewLine + ex.StackTrace + Environment.NewLine + Environment.NewLine;
}

[编辑] 勾选此项。

Check if directory exists on Network Drive [/编辑]

【讨论】:

  • 我使用的路径为“\\DEV-2012X\1454444717051\MB4.zip”,而 DEV-2012X 是我正在测试的服务器。是的,我知道代码应该是这样的,但我只是快速添加它以测试并仅更新我从第一次捕获中获得的异常。 UNC 路径是一场噩梦
  • 查看此链接并检查您是否添加了凭据,它将起作用stackoverflow.com/questions/10214596/…
  • 也试过了,但没有运气..我可以通过代码看到那里的文件,但 ZipFile.Read 函数仍然崩溃并出现同样的错误
  • 在此处更新您的代码,因为它现在正在运行。我认为您的代码无法访问该文件。你可以尝试使用相同的代码到一个已知的有效路径吗?
  • 我在“Edit -3”中添加了当前代码和异常信息
猜你喜欢
  • 2015-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多