재우니의 블로그


ASP.NET 4.5부터 .NET Framework에서 클래스를 사용하여 파일 압축 및 압축 해제를 수행 할 수 있습니다. 그럼에도 불구하고 ASP.NET 응용 프로그램에서 zip 파일로 작업하는 것을 보여주는 거의 모든 예제에는 타사 오픈 소스 압축 라이브러리가 있습니다. 이 짧은 기사에서는 System.IO.Compression 클래스를 사용하여 업로드 된 zip 파일의 압축을 풀고 ASP.NET MVC 응용 프로그램에서 다운로드 용 System.IO.Compression 클래스를 만드는 방법을 보여줌으로써이를 해결하려고합니다.


업로드 된 zip 파일 압축 풀기

먼저 System.IO.Compression에 대한 참조를 프로젝트에 추가해야합니다. 이 작업을 마치면 zip 파일의 업로드 form 을 만듭니다.


@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="zip"  /> 
    <div>
        <button class="btn btn-default">Submit</button>
    </div>
}


업로드를 위해 multipart/form-data 을 명시합니다.



[HttpPost]
public ActionResult Index(HttpPostedFileBase zip)
{
    var uploads = Server.MapPath("~/uploads");
    using (ZipArchive archive = new ZipArchive(zip.InputStream))
    {
        foreach (ZipArchiveEntry entry in archive.Entries)
        {
            if (!string.IsNullOrEmpty(Path.GetExtension(entry.FullName))) //make sure it's not a folder
            {
                entry.ExtractToFile(Path.Combine(uploads, entry.FullName));
            }
            else
            {
                Directory.CreateDirectory(Path.Combine(uploads, entry.FullName));
            }
        }
    }
    ViewBag.Files = Directory.EnumerateFiles(uploads);
    return View();
}


작업의 매개 변수는 HttpPostedFileBase양식의 파일 업로드 컨트롤의 이름 특성에 따라 지정됩니다. 코드는 ZipArchive업로드 된 파일의 내용 에서 클래스 의 인스턴스를 만든 다음 아카이브의 내용을 반복합니다. 항목의 이름에 파일 확장자가 있으면 파일이며, 그렇지 않으면 폴더 입니다. 코드는 추출 된 파일을 저장하거나 폴더를 생성합니다.

다운로드 용 Zip 파일 만들기

다음 예제는 정적  메소드 의 사용법을 보여줍니다. 정적 메서드는 네임 스페이스에 있지만 실제로 어셈블리에 있으므로 컨트롤러에 해당 참조를 추가해야합니다. 사용자는 선택할 파일 선택을 나타내는 체크 박스 목록을 볼 수 있으며, form 을 submit 하면 해당 파일이 하나의 zip 파일로 패키지되고 다운로드됩니다.ZipFile.CreateFromDirectorySystem.IO.CompressionSystem.IO.Compression.FileSystem

파일 목록은 다음을 통해 뷰로 전달됩니다

public ActionResult Index()
{
    ViewBag.Files = Directory.EnumerateFiles(Server.MapPath("~/pdfs"));
    return View();
}

view 에 담겨진 파일들이 목록 형태로 뷰에 보여줍니다.


<h2>Select downloads</h2>
@using(Html.BeginForm("Download", "Home"))
{
    foreach(string file in ViewBag.Files)
    {
        <input type="checkbox" name="files" value="@file" /> @:&nbsp;  
             @Path.GetFileNameWithoutExtension(file) <br />
    }
    <div>
        <button class="btn btn-default">Submit</button>
    </div>
}

form 에서 submit 하면 아래의  Download의 컨트롤러에 호출되어 집니다..


[HttpPost]
public FileResult Download(List<string> files)
{
    var archive = Server.MapPath("~/archive.zip");
    var temp = Server.MapPath("~/temp");

    // clear any existing archive
    if (System.IO.File.Exists(archive))
    {
        System.IO.File.Delete(archive);
    }
    // empty the temp folder
    Directory.EnumerateFiles(temp).ToList().ForEach(f => System.IO.File.Delete(f));

    // copy the selected files to the temp folder
    files.ForEach(f => System.IO.File.Copy(f, Path.Combine(temp, Path.GetFileName(f))));

    // create a new archive
    ZipFile.CreateFromDirectory(temp, archive);

    return File(archive, "application/zip", "archive.zip");
}

archive.zip 파일있었는지 확인하기 위해 점검하고 삭제합니다. 그런 다음 temp 라는 폴더에 기존 파일이 삭제됩니다. 그런 다음 선택한 파일이 원본 디렉터리에서 임시 폴더로 복사됩니다. 이 ZipFile.CreateFromDirectory메소드는 temp 디렉토리 내용에서 zip 파일을 생성하고 이를 archive.zip 으로 저장합니다 .

이 두 예제는 가능한 한 명확하게 작업을 수행하는 데 필요한 주요 클래스와 메소드를 설명하기 위해 단순화되었습니다. 업로드를 처리 할 때 유효성 검사를 추가하여 업로드 된 파일이 사실 zip 파일인지 확인해야합니다. 또한 생성 된 zip 파일은 하드 코딩 된 폴더에 저장됩니다. 여러 사용자가 동시에 zip 파일을 다운로드하는 바쁜 사이트가있는 경우 한 사용자의 다운로드가 다른 사용자의 덮어 쓰기를 덮어 쓰지 않도록 Guid를 폴더 이름으로 사용할 수 있습니다.