설명
DEXTUploadX5는 1.3.0.0 버전부터 압축 다운로드를 지원한다.
압축 다운로드는 여러 파일을 동시에 받기 위해서 서버에 대상 파일을 하나의 압축 파일로 묶도록 서버에 요청하고, 그 압축 파일을 내려받는다. 다른 예제에서 보았던, 단일/다중 파일 다운로드 예제와 달리, 압축 다운로드는 압축 과정을 서버에 일임하기 때문에, 대상 파일에 대한 다운로드 경로를 지정하는 속성(downUrl)에 영향을 받지 않는다.
압축 다운로드를 하려면, 압축을 담당하며, 압축된 파일을 다운로드할 수 있도록 그 경로값을 반환하는 주소를 setCompressURL 메소드를 사용하여 지정해야 한다. 그리고 단일/다중 파일 다운로드와 달리 압축 다운로드를 시작할 때에는 downloadCompressed 메소드를 호출한다.
var dx = dx5.get("컴포넌트 아이디");
// downUrl 속성이 불필요하다.
// 다만 압축 작업을 해야 하는 서버에서 압축 대상을 구별하기 위한 vindex 속성값을 반드시 지정해 주어야 한다.
// vindex는 일종의 유니크한 문자열 값으로써, 가상 파일을 구별하기 위한 유일한 수단이다.
dx.addVirtualFile({ vindex: "IDX0003", name: "서강대교_509147.jpg", size: 509147 });
dx.addVirtualFile({ vindex: "IDX0004", name: "우도해변_239826.jpg", size: 239826 });
dx.addVirtualFile({ vindex: "IDX0005", name: "코스모스 (빈공간) 195779.jpg", size: 195779 });
// 압축을 처리하고 압축 파일 다운로드 경로를 반환하는 주소를 설정한다.
dx.setCompressURL("http://도메인/경로../service/compress.do");
// 플래그 값에 따라 다운로드를 수행한다.
// AUTO: 가상 파일을 다운로드한다.
// SELECTED: 선택된 가상 파일을 다운로드한다.
// CHECKED: 체크된 가상 파일을 다운로드한다.
dx.downloadCompressed("SELECTED");
예제에서 파일 압축은 compress.ashx 제너릭 핸들러가 담당한다.
DEXTUploadX5는 downloadCompressed 메소드를 호출하면, 압축 다운로드할 가상 파일의 vindex 속성값을콤마(,)를 구분자로 하는 하나의 목록으로 하는 문자열 정보를 'DEXTUploadX5_VIndexes' 이름의 폼 데이터를 서버에 POST 형식으로 보낸다. 서버에서는 'DEXTUploadX5_VIndexes' 값을 얻어 콤마(,) 문자로 분리를 하여 대상 정보를 얻고 압축을 수행해야 하는데, .NET Framework 4.5 부터 zip 압축을 지원하는 라이브러리가 제공된다.
// DEXTUploadX5_VIndexes 폼 이름으로부터 압축할 대상의 가상 인덱스 집합을 얻을 수 있다.
var data = context.Request.Form["DEXTUploadX5_VIndexes"] ?? string.Empty;
var vindexes = data.Split(',');
var targets = new List<string>();
foreach (string index in vindexes)
{
if (index.Equals("IDX0003")) targets.Add(context.Server.MapPath("~/files/attach/서강대교_509147.jpg"));
else if (index.Equals("IDX0004")) targets.Add(context.Server.MapPath("~/files/attach/우도해변_239826.jpg"));
else if (index.Equals("IDX0005")) targets.Add(context.Server.MapPath("~/files/attach/코스모스 (빈공간) 195779.jpg"));
}
var zipPath = Path.GetTempFileName();
// .NET Framework 4.5 부터 지원하는 ZipArchive를 이용하여 압축 파일을 생성한다.
using (var fs = new FileStream(zipPath, FileMode.Create))
using (var za = new ZipArchive(fs, ZipArchiveMode.Create, false, System.Text.Encoding.UTF8))
{
foreach (string path in targets)
{
za.CreateEntryFromFile(path, Path.GetFileName(path));
}
}
// 예제가 아닌 실제 상황에서는 세션 또는 데이터베이스와 같은 다른 저장 방식을 이용하여
// 실제로 다운로드를 수행해야 하는 핸들러(zip-download.ashx)에서 압축 파일의 경로를 얻을 수 있도록 처리해야 한다.
...
// 압축된 파일을 다운로드할 수 있는 핸들러 경로를 생성한다.
UriBuilder b = new UriBuilder(context.Request.Url);
b.Path = VirtualPathUtility.ToAbsolute("~/service/zip-download.ashx");
b.Query = string.Concat("key=", key);
// 압축된 파일을 다운로드할 수 있는 경로를 응답 데이터에 실어 클라이언트에 전달해야 한다.
context.Response.ContentType = "text/plain";
context.Response.Write(b.ToString());
var key = context.Request.QueryString["key"] ?? string.Empty;
var entry = FileRepository.Get(key);
if (entry != null)
{
using (var dext = new DEXTUpload.NET.FileDownload())
{
dext.Download(entry.Path, entry.FileName, new DEXTUpload.NET.DownloadOption
{
// 다운로드를 한 후 압축 파일은 무의미한 파일이므로 삭제하도록 한다.
RemoveAfterDownloading = true,
// 압축 파일은 매 요청마다 생성되므로 클라이언트 캐시를 사용하지 않도록 한다.
UseClientCache = false,
// application/x-zip-compressed
MimeType = entry.MimeType
});
}
}
else
{
throw new HttpException(404, "The zip file not found.");
}
파일을 압축하는 작업은 서버의 리소스(CPU, I/O)를 상당히 소모하는 작업이기 때문에, 크기가 큰 파일 또는 압축 파일의 대상이 되는 파일의 개수가 많은 경우, 서버에 상당한 오버헤드가 발생하므로, 상황에 따라 파일 압축 과정을 기다리는 시간이 길어질 수 있으며, 이는 세션이 끊기는 문제가 초래하거나, 서비스 자체가 중지되는 중대한 문제로 이어질 수 있다. 따라서 압축 다운로드을 하기 위한 정책적 제한을 수립 후, 기능을 사용하는 것을 권장한다.
DEXTUpload.NET Professional 제품은 압축 작업을 위한 클래스와 같은 라이브러리를 제공하지 않는다. .NET Framework 4.5 이상에서는 ZipArchive, ZipFile과 같은 압축 관련 클래스가 제공되므로 이를 활용하여 파일을 압축할 수 있다. 만일 .NET Framework 4.0과 같은 이전 버전인 경우는 third-party 라이브러리를 사용하거나 직접 개발하여 적용하는 방법을 강구해야 한다.
예제
|
압축 다운로드 |
|
압축은 서버에서 진행된다. 압축이 진행되는 동안은 진행창이 표시되지만, 압축된 파일을 다운로드할 때는 단일 파일 다운로드로 전환되기 때문에 다운로드 과정에 대한 자체 진행창은 제공되지 않는다. |