【问题标题】:Unzipping a file error解压文件错误
【发布时间】:2008-12-03 22:11:11
【问题描述】:

我正在使用来自www.icsharpcode.net 的 SharpZipLib 开源 .net 库

我的目标是解压缩 xml 文件并将其读入数据集。但是,将文件读入数据集时出现以下错误:“根级别的数据无效。第 1 行,位置 1。” 我相信正在发生的事情是由于以下原因,解压缩代码没有释放文件。

1.) 如果我解压缩文件并退出应用程序。当我重新启动应用程序时,我可以将解压缩的文件读入数据集中。 2.) 如果我在写出 xml 文件后立即读取它(没有压缩),那么它工作正常。
3.)如果我将数据集写入 xml,将其压缩,解压缩,然后尝试将其读回我得到异常。

下面的代码非常简单。 UnZipFile 将返回刚刚解压缩的文件的名称。在此调用的正下方是将其读入数据集的调用。变量 fileToRead 是新解压的 xml 文件的完整路径。

string fileToRead = UnZipFile(filepath, DOViewerUploadStoreArea);
ds.ReadXml(fileToRead )

private string UnZipFile(string file, string dirToUnzipTo)
{

       string unzippedfile = "";

        try
        {
            ZipInputStream s = new ZipInputStream(File.OpenRead(file));
            ZipEntry myEntry;
            string tmpEntry = String.Empty;
            while ((myEntry = s.GetNextEntry()) != null)
            {
                string directoryName = dirToUnzipTo;
                string fileName = Path.GetFileName(myEntry.Name);
                string fileWDir = directoryName + fileName;
                unzippedfile = fileWDir;

                FileStream streamWriter = File.Create(fileWDir);
                int size = 4096;
                byte[] data = new byte[4096];
                while (true)
                {
                    size = s.Read(data, 0, data.Length);
                    if (size > 0) { streamWriter.Write(data, 0, size); }
                    else { break; }
                }
                streamWriter.Close();
            }
            s.Close();
        }
        catch (Exception ex)
        {
            LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");

        }
        return (unzippedfile);
    }

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    那么,最终的文件是什么样的? (与原版相比)。您没有显示邮政编码,这可能是难题的一部分,尤其是当您部分吞下异常时。

    我也会尝试确保所有IDisposable 都是Dispose()d,最好是通过using;另外 - 如果问题出在路径构造上,请使用Path.Combine。请注意,如果myEntry.Name 包含子目录,则需要手动创建。

    这就是我所拥有的 - 它适用于解压缩 ICSharpCode.SharpZipLib.dll:

        private string UnZipFile(string file, string dirToUnzipTo)
        {
    
            string unzippedfile = "";
    
            try
            {
                using(Stream inStream = File.OpenRead(file))
                using (ZipInputStream s = new ZipInputStream(inStream))
                {
                    ZipEntry myEntry;
                    byte[] data = new byte[4096];
                    while ((myEntry = s.GetNextEntry()) != null)
                    {
                        string fileWDir = Path.Combine(dirToUnzipTo, myEntry.Name);
                        string dir = Path.GetDirectoryName(fileWDir);
                        // note only supports a single level of sub-directories...
                        if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                        unzippedfile = fileWDir; // note; returns last file if multiple
    
                        using (FileStream outStream = File.Create(fileWDir))
                        {
                            int size;
                            while ((size = s.Read(data, 0, data.Length)) > 0)
                            {
                                outStream.Write(data, 0, size);
                            }
                            outStream.Close();
                        }
                    }
                    s.Close();
                }
    
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
    
            }
            return (unzippedfile);
        }
    

    也可能是问题出在编写 zip 的代码中,或者出在读取生成文件的代码中。

    【讨论】:

      【解决方案2】:

      我使用 TextPad 将原始版本与最终版本进行了比较,它们是相同的。 我还重写了代码以利用 using。这是代码。 我的问题似乎集中在文件锁定或其他方面。如果我解压缩文件退出应用程序然后启动它会读取 find。

      private string UnZipFile(string file, string dirToUnzipTo)
          {
              string unzippedfile = "";
      
              try
              {
                  using (ZipInputStream s = new ZipInputStream(File.OpenRead(file)))
                  {
      
                      ZipEntry theEntry;
                      while ((theEntry = s.GetNextEntry()) != null)
                      {
                          string directoryName = dirToUnzipTo;
                          string fileName = Path.GetFileName(theEntry.Name);
                          string fileWDir = directoryName + fileName;
                          unzippedfile = fileWDir;
      
                          if (fileName != String.Empty)
                          {
                              using (FileStream streamWriter = File.Create(fileWDir))
                              {
                                  int size = 2048;
                                  byte[] data = new byte[2048];
                                  while (true)
                                  {
                                      size = s.Read(data, 0, data.Length);
                                      if (size > 0)
                                      {
                                          streamWriter.Write(data, 0, size);
                                      }
                                      else
                                      {
                                          break;
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
              catch (Exception ex)
              {
                  LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");
      
              }
              return (unzippedfile);
          }
      

      【讨论】:

        【解决方案3】:

        使用 DotNetZip 实现这一点要简单得多。

        using (ZipFile zip = ZipFile.Read(ExistingZipFile))
        {
             zip.ExtractAll(TargetDirectory);       
        }
        

        如果您想决定提取哪些文件......

        using (ZipFile zip = ZipFile.Read(ExistingZipFile))
        {
            foreach (ZipEntry e in zip)
            {
                if (wantThisFile(e.FileName)) e.Extract(TargetDirectory);
            }
        }
        

        如果您想在提取过程中覆盖现有文件:

        using (ZipFile zip = ZipFile.Read(ExistingZipFile))
        {
             zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
        }
        

        或者,提取受密码保护的条目:

        using (ZipFile zip = ZipFile.Read(ExistingZipFile))
        {
             zip.Password = "Shhhh, Very Secret!";
             zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-25
          • 1970-01-01
          • 2020-09-20
          相关资源
          最近更新 更多