読者です 読者をやめる 読者になる 読者になる

Zipファイル解凍

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ionic.Zip;

namespace JsonClient
{
    public partial class Form1 : Form
    {
        private static CancellationTokenSource cancelSource = new CancellationTokenSource();
        private LockedQueue<string> que = new LockedQueue<string>(Timeout.Infinite, cancelSource.Token);

        private Thread ExtractThread;
        private Thread GetWebApiThread;

        public Form1()
        {
            InitializeComponent();

            ExtractThread = new Thread(new ThreadStart(WaitQueue));
            ExtractThread.Start();

            GetWebApiThread = new Thread(new ThreadStart(GetWebApi));
            GetWebApiThread.Start();
        }

        private void GetWebApi()
        {
            try
            {

                string path = @"http://localhost:65339/" + "Handler1.ashx";

                using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromMinutes(10) })
                {
                    // Get
                    var response = client.GetAsync(path).Result;
                    response.EnsureSuccessStatusCode();

                    response.Content.LoadIntoBufferAsync();
                    string pathCompress = Path.Combine(@"C:\test\");

                    pathCompress = Path.Combine(pathCompress, DateTime.Now.ToString("yyyyMddHHmmss") + ".zip");
                    //if (!File.Exists(pathCompress)) { File.Create(pathCompress); }


                    using (FileStream fs = new FileStream(pathCompress, FileMode.Create))
                    {
                        // 圧縮ファイルを格納
                        response.Content.ReadAsStreamAsync().Result.CopyTo(fs);
                    }

                    que.Enqueue(pathCompress);
                }
            }
            catch (Exception)
            {

            }

        }

        private void WaitQueue()
        {
            string dequeue;

            try
            {
                while (true)
                {
                    dequeue = que.Dequeue();

                    if (dequeue != null)
                    {
                        using (ZipFile zipFile = new ZipFile(Encoding.GetEncoding("shift_jis")))
                        {
                            zipFile.Initialize(dequeue);


                            //ZIP書庫内のエントリを取得
                            foreach (Ionic.Zip.ZipEntry entry in zipFile.EntriesSorted)
                            {
                                if (entry.FileName.Contains("summary"))
                                {
                                    // TODO 月報ファイル名を取得
                                    entry.FileName = System.IO.Path.GetFileName(entry.FileName);

                                    // TODO 月報のフォルダを指定
                                    entry.Extract(@"D:\test\", ExtractExistingFileAction.OverwriteSilently);
                                }
                                else
                                {
                                    entry.FileName = Path.Combine(Path.GetFileNameWithoutExtension(entry.FileName) + "/" + Path.GetFileName(entry.FileName));

                                    // TODO 日報のフォルダを指定
                                    entry.Extract(@"D:\test\", ExtractExistingFileAction.OverwriteSilently);
                                }
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch(OperationCanceledException)
            {
                // キューの内容を削除
            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(que.Count != 0)
            {
                // まだ解凍してないの残ってるけど終了させいいか確認
                // OK:続行 NG:return
            }


            // これ以上キューに値を追加させない
            que.Stop();

            // キュー取得をキャンセル
            cancelSource.Cancel();

            while (ExtractThread != null && ExtractThread.IsAlive) 
            {
                //最後の解凍が実行中の為、待機
                Thread.Sleep(1000); 
            }
        }
    }
}