質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1831questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • .NET Framework

    457questions

    .NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

  • zip

    58questions

    ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

  • マルチスレッド

    52questions

    マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

c# zip圧縮 マルチスレッド

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 422

maple123

score 1

 前提・実現したいこと

c#で大量のファイルが入ったフォルダをマルチスレッドで高速で1つのzipに圧縮したい。

環境

c#7.1 .net4.7 VS2017

質問内容

一つのzipファイルに並列処理で複数のファイルを圧縮することはそもそも可能でしょうか?

質問内容追加(20180716 12:47)

・zipファイル内にディレクトリができない
・並列で一つのzipファイルにアクセスする為例外発生

画像

イメージ図

C#

private void button2_Click(object sender, EventArgs e)
{
  //FolderBrowserDialogクラスのインスタンスを作成
     FolderBrowserDialog fbd = new FolderBrowserDialog();
  //上部に表示する説明テキストを指定する
     fbd.Description = "フォルダを指定してください。";
  //ルートフォルダを指定する
  //デフォルトでDesktop
     fbd.RootFolder = Environment.SpecialFolder.Desktop;
  //最初に選択するフォルダを指定する
  //RootFolder以下にあるフォルダである必要がある
     fbd.SelectedPath = @"C:\Windows";
  //ユーザーが新しいフォルダを作成できるようにする
  //デフォルトでTrue
     fbd.ShowNewFolderButton = true;
  //ダイアログを表示する
     if (fbd.ShowDialog(this) == DialogResult.OK)
       {
          //選択されたフォルダを表示する
            Console.WriteLine(fbd.SelectedPath);
            textBox1.Text = fbd.SelectedPath;
       }
  //ListBoxに一覧を表示する
      listBox1.Items.Clear();
      var directries = Directory.GetDirectories(fbd.SelectedPath);
      foreach (var directry in directries)
        {
           Console.WriteLine(directry);
           listBox1.Items.Add(directry);
        }
}

private void button1_Click(object sender, EventArgs e)
{
  //デスクトップ
    string zipFilePath = $@"{System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}\test.zip";
  //ZIP書庫を作成
    ZipFile.CreateFromDirectory(listBox1.Items[0].ToString(), zipFilePath);
  //ディレクトリ分タスクを生成する
    List<Task<bool>> task = new List<Task<bool>>();
  //読み取りと書き込みができるようにして、ZIP書庫を開く
    using (ZipArchive ziparchive = ZipFile.Open(zipFilePath, ZipArchiveMode.Update))
     {
       foreach (var directry in listBox1.Items)
        {
           task.Add(Task<bool>.Run(() =>
            {
              string[] fileList = Directory.GetFiles(directry.ToString(), "*", SearchOption.AllDirectories);
              foreach (var file in fileList)
               {
                 Console.WriteLine(file);
                 ZipArchiveEntry x = ziparchive.CreateEntryFromFile(file, System.IO.Path.GetFileName(file));
               }
               return true;
             }));
         }
         Task.WhenAll(task);
      }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+4

出力先が一つのファイルで、

並列処理で複数のファイル

ファイル毎に、圧縮処理を行い、一つのファイルにまとめるという事でしょうか?
それならば、ファイル毎に Zip(圧縮)処理を行い、その結果をマージする事になります。ただし、効率よく行うためには、専用の圧縮処理、解凍処理が必要となりますが、ここまでくると Zipと言うより、専用処理を検討すべきかと思います。

確か、Lhaの開発者だったかの人が、リアルタイム圧縮を開発していたかと思いますが、同様にすべき。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/15 06:40

    やはりzipは難しいでしょうか…

    キャンセル

  • 2018/07/15 08:52

    Zip圧縮は、ライブラリも公開されているので、それを使えば、簡単にできると思います。(使った事ないですが...)
    ただ、わざわざマルチスレッドで、と書かれているので、特別な理由があると思った次第です。マルチスレッドにするという事は、それぞれの処理に依存関係があると高速化できないので、ファイル毎に圧縮する事になります。
    Zip圧縮 --> アーカイブ処理 の流れになり、そんな都合の良い方法と思った時、Zip圧縮と書かれていたので、専用処理(ファイル形式)の作成が必要かもと考え、そこまでするなら、Zipに拘る必要が無いのでは? と思った次第。
    現状、Zipは、特定のコードに対し、最速でもコンパクトでも無いので、わざわざマルチスレッド(タスク?)にして高速化を図りたい要望に対しては、専用の方法が最適と考えました。

    キャンセル

+3

直接の回答ではなくてすみません。

質問者さんは、たぶん、以下の記事の「マルチスレッドの動作原理」セクションにある図の ③ をイメージされているのではないかと思います。

第1回 マルチスレッドはこんなときに使う (1/2)
http://www.atmarkit.co.jp/ait/articles/0503/12/news025.html

しかし、シングルコアのマシンでは ② のようになり、スレッドを切り替えるためのオーバーヘッドが発生して逆に遅くなるということは認識されてますか? そのあたりは初学者の人が陥りやすい誤解のようです。

マルチコアの能力を生かした高速処理(図の ③)を行うにはそのためのコーディングが必要です。

VS 2010、.NET 4 で導入された Parallelクラスを使うという手段があるそうで(下記の記事参照)、それ以前と比較して実装が容易になっているそうです。

Visual Studio 2010 の 優れた機能(3)マルチコア プログラミングへの対応
https://blogs.msdn.microsoft.com/myamada/2010/03/02/visual-studio-2010-1/

ループをParallelクラスで並列処理にするには?[C#/VB]
http://www.atmarkit.co.jp/ait/articles/1706/21/news021.html

上記が質問者の課題を解決できるかは分かりませんが、自力で課題を解決したいということであれば検討されてはいかがでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

  • 「C# ZIP」でぐぐる
  • 一つのファイルをZIP圧縮するコードを組む
  • 「C# parallel for」でぐぐる
  • 非同期で並列実行させて、複数のファイルをZIP圧縮させるようにコードを組む
  • バッチシ!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/15 06:38

    複数のファイルをそれぞれ1つずつ圧縮処理をしたいのではなく、複数のファイルを一つにまとめて圧縮したかったです。

    キャンセル

  • 2018/07/15 08:38 編集

    一つのzipにしたいというなら、C#標準のライブラリでは無理なので、他の方法を探す必要があります
    他回答のように、各ファイルをzipにした上でマージするということになりますねー
    まー、まずは各ファイルを並列でzipにすることから始めましょう

    キャンセル

+1

複数のファイルを同時に圧縮とするよりも、ファイルの読み込みと圧縮のスレッドを分ける方が良さそうな気がします
同じ物理ドライブに対して同時に読み込もうとしても時間の短縮にはならないと思いますので

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/16 12:50

    ファイルの読み込みと圧縮のスレッドを分ける件になりますが、
    いい方法が思いつきませんでした。
    プログラムを追加いたしましたのでよろしければ見ていただけないでしょうか。

    キャンセル

0

Zip圧縮 --> アーカイブ処理 を
parallel for each又は、ファイル分Taskを生成して、async awaitさせようと思います。

皆様有難う御座います。

一つ一つをzip化して最後にまとめるのが最善でしょうが、圧縮無しで、まとめてzipにしたかったのでそこは別途考えてみます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1831questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • .NET Framework

    457questions

    .NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

  • zip

    58questions

    ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

  • マルチスレッド

    52questions

    マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。