10

Windowsでファイルを解凍すると、パスに問題が発生することがあります

  1. これはWindowsには長すぎます(ただし、ファイルを作成した元のOSでは問題ありません)。
  2. 大文字と小文字を区別しないために「重複」している

DotNetZipを使用ZipFile.Read(path)すると、これらの問題の1つでzipファイルを読み取るたびに呼び出しが失敗します。つまり、フィルターで除外することすらできないということです。

using (ZipFile zip = ZipFile.Read(path))
{
    ...
}

これらの種類のファイルの読み取りを処理するための最良の方法は何ですか?

更新しました:

ここからのzipの例: https ://github.com/MonoReports/MonoReports/zipball/master

複製: https ://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/DataSourceType.cs https://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/DatasourceType .cs

例外の詳細は次のとおりです。

Ionic.Zip.ZipException:それをZipFileとして読み取ることができません
---> System.ArgumentException:同じキーを持つ>アイテムがすでに追加されています。
System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary 2.Add(TKey key、TValue value) at Ionic.Zip.ZipFile.ReadCentralDirectory(ZipFile zf) at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf) 2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary


解像度:

@Cheesoの提案に基づいて、ストリームからすべてを読み取ることができ、重複を回避するもの、およびパスの問題を読み取ることができます。

//using (ZipFile zip = ZipFile.Read(path))
using (ZipInputStream stream = new ZipInputStream(path))
{
    ZipEntry e;
    while( (e = stream.GetNextEntry()) != null )
    //foreach( ZipEntry e in zip)
    {
        if (e.FileName.ToLower().EndsWith(".cs") ||
            e.FileName.ToLower().EndsWith(".xaml"))
        {
            //var ms = new MemoryStream();
            //e.Extract(ms);
            var sr = new StreamReader(stream);
            {
                //ms.Position = 0;
                CodeFiles.Add(new CodeFile() { Content = sr.ReadToEnd(), FileName = e.FileName });
            }
        }
    }
}
4

2 に答える 2

8

この問題で、 DotNetZipPathTooLongExceptionを使用できないことがわかりました。代わりに、私が行ったことは、7-zipのコマンドラインバージョンを呼び出すことでした。それは不思議に働きます。

public static void Extract(string zipPath, string extractPath)
{
    try
    {
        ProcessStartInfo processStartInfo = new ProcessStartInfo
        {
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = Path.GetFullPath(@"7za.exe"),
            Arguments = "x \"" + zipPath + "\" -o\"" + extractPath + "\""
        };
        Process process = Process.Start(processStartInfo);
        process.WaitForExit();
        if (process.ExitCode != 0) 
        {
            Console.WriteLine("Error extracting {0}.", extractPath);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error extracting {0}: {1}", extractPath, e.Message);
        throw;
    }
}
于 2015-02-05T02:28:38.207 に答える
3

で読んでくださいZipInputStream

クラスはZipFile、ファイル名をインデックスとして使用してコレクションを保持します。ファイル名が重複していると、そのモデルが壊れます。

ただし、を使用してZipInputStreamを読み込むことができますZipFile。その場合、コレクションやインデックスはありません。

于 2012-05-27T00:32:12.290 に答える