2017-03-15 14 views
0

こんにちは私はZipInputStream(Unseekable入力ストリームなど)を使用してZipを解凍しようとしています。 SharpZipLibの助けを借りて。しかし、これはいつも私にエラーを与える:例外がスローされました: 'System.IO.DirectoryNotFoundException'とSystem.IO.PathTooLongException

エラー:スロー

例外:がmscorlib.dll エラーで 'System.IO.DirectoryNotFoundException':パス「Cの一部が見つかりませんでしたが。 \ Users \ username \ Documents \ Visual Studio 2015 \ Projects \ WpfApplication1 \ WpfApplication1 \ bin \ Debug \ ASPNETWebAPISamples-master \ 'に移動します。

私は**ZipFile.ExtractToDirectory**のエクストラクタとhttp://dotnetzip.codeplex.com/を試しました。彼らはまた、パスも長すぎた例外を与えた。

パスに関する長すぎる例外に関するいくつかの質問があります。しかし誰も私のために働いていませんでした。

このエラーを解決するにはどうすればよいですか?おかげさまで

public static async Task HttpGetForLargeFileInRightWay() 
    { 
     using (HttpClient client = new HttpClient()) 
     { 
      const string url = "https://github.com/tugberkugurlu/ASPNETWebAPISamples/archive/master.zip"; 
      using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) 
      using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync()) 
      { 
       try 
       { 
        Debug.Print("A"); 
        UnzipFromStream(streamToReadFrom, Environment.CurrentDirectory); 
        Debug.Print("M"); 
       } 
       catch (Exception ex) 
       { 

        Debug.Print("Error: " + ex.Message); 
       } 
      } 
     } 
    } 


    public static void UnzipFromStream(Stream zipStream, string outFolder) 
    { 

     ZipInputStream zipInputStream = new ZipInputStream(zipStream); 
     ZipEntry zipEntry = zipInputStream.GetNextEntry(); 
     Debug.Print("B"); 
     while (zipEntry != null) 
     { 
      String entryFileName = zipEntry.Name; 
      // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); 
      // Optionally match entrynames against a selection list here to skip as desired. 
      // The unpacked length is available in the zipEntry.Size property. 

      byte[] buffer = new byte[4096];  // 4K is optimum 

      Debug.Print("C"); 
      // Manipulate the output filename here as desired. 
      String fullZipToPath = Path.Combine(outFolder, entryFileName); 
      Debug.Print("D"); 
      string directoryName = Path.GetDirectoryName(fullZipToPath); 
      Debug.Print("E"); 
      if (directoryName.Length > 0) 
      { 

       Debug.Print("F"); 
       Directory.CreateDirectory(directoryName); 
       Debug.Print("G"); 
      } 

      Debug.Print("H"); 
      // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size 
      // of the file, but does not waste memory. 
      // The "using" will close the stream even if an exception occurs. 
      using (FileStream streamWriter = File.Create(fullZipToPath)) 
      { 
       Debug.Print("I"); 
       StreamUtils.Copy(zipInputStream, streamWriter, buffer); 
       Debug.Print("J"); 
      } 
      Debug.Print("K"); 
      zipEntry = zipInputStream.GetNextEntry(); 
      Debug.Print("L"); 
     } 
    } 
+0

ディレクトリは存在しますか? – TheLethalCoder

+0

うまく 'Directory.CreateDirectory(directoryName)'行が実際に存在しない場合に作成する – djkp

+0

どこでエラーが発生しますか?そしてサイドノート 'fullZipToPath'はファイルパスであると思われ、' outFolder'はそれが存在するディレクトリです。なぜあなたは 'OutFolder'ではなく' Path.GetDirectoryName(fullZipToPath) 'にディレクトリを作成していますか? – TheLethalCoder

答えて

1

問題はzipInputStream.GetNextEntry()は、zipファイル内のディレクトリとファイルの両方を返すことです。これは問題ではありませんが、コードはファイルのみを処理します。これを修正するには、変数fullZipToPathがファイルまたはディレクトリへのパスを保持しているかどうかを検出する必要があります。

これを行う方法は、ZipEntry.IsDirectoryのプロパティを調べることです。コードを次のように変更します。

if (!zipEntry.IsDirectory) 
{ 
    using (FileStream streamWriter = File.Create(fullZipToPath)) 
    { 
     StreamUtils.Copy(zipInputStream, streamWriter, buffer); 
    } 
} 

zipファイルがダウンロードされ、正常に抽出されます。

PathTooLongExceptionについては、this questionを参照してください。

関連する問題