[Web Form] C# 파일입출력을 이용하여 HTML 파일 다운로드 기능만들기
배경
사실 운영자들은 실행 프로그램을 관리하는 게 더 어렵고 귀찮은 일입니다. 운영을 관리하는 웹 사이트에서 바로 다운로드하는 것을 더 선호합니다. 시험공부에 홀려서 C를 파고드는 동안 놓친 부분이 있습니다. C#에도 파일 입출력 기능이 아주 잘 되어 있다는 사실을 말이죠.
항상 만들어야지 나중에 알아봐야지 하고 뒷전으로 미룬 일입니다. 그런데 같이 일하시는 분이 재밌게 즐기면서 업무의 프로세스를 확 줄이는 모습을 보며, 막연하게 웹 환경 보안 상 하면 안 될 거야 하고 찾아보지 않고 넘어간 지난날을 반성하였습니다.
2023.06.20 - [개발/Computer Science] - [C프로그래밍] HTML 생성 프로그램 만들기
[C프로그래밍] HTML 생성 프로그램 만들기
개발 배경 C프로그래밍 시험을 위해서 공부를 하다가 C언어 파일 입출력, 메모리 동적 할당 파트에서 엄청 재미를 느꼈습니다. 웹은 보안 상 파일을 다루기 어려운데, C에서는 파일 입출력에 관
hyangforest.tistory.com
기능 정의
기존 배경 및 방식
정해진 양식이 있고 컨텐츠의 텍스트와 이미지만 바뀌는 웹 페이지가 존재하며 가끔은 타사 담당자에게 승인 목적의. html을 보내야 합니다. HTML 코드를 모르는 운영자는. html을 만들어 달라는 요청이 오며 페이지 소스 가져와서 DB 관련되고 웹 프레임워크에 관련된 코드를 지우고 저장하여 전달하였습니다. 가끔 있는 일이지만 작업에 흐름 끊기는 일입니다.
목표
해당 컨텐츠 상세 보기 페이지에 [HTML 다운로드하기] 기능을 추가하여 모든 사용자에게 콘텐츠 HTML 파일 제공하기
방식
- 기본 HTML 코드 구문을 작성한다.
- 기본 HTML + DB에 저장된 컨텐츠 HTML 코드를 합친다
- 합친 코드의 내용을 가진 .html 확장자 파일을 만든다.
- 3번의 파일 제목은 중복되지 않게 현재 일시로 만든다.
- 사용자 컴퓨터에 만든 파일을 다운로드한다.
- 서버 저장 폴더에서 파일을 삭제한다.
코드
웹 페이지(.aspx)
<asp:Button ID="btnHTMLSave" runat="server" CssClass="btn btn-md btn-success" Text="HTML 다운로드" OnClick="btnHTMLSave_Click" />
서버 코드(. aspx.cs)
protected void btnHTMLSave_Click(object sender, EventArgs e)
{
string DirectoryPath = @"서버 파일 업로드 관련 디렉토리";
string fileName = string.Format("HTML_{0}.html", DateTime.Now.ToString("yyyyMMddHHmmdd"));
string fullFileName = string.Empty;
// 서버에 해당 경로가 없다면 생성하기
if (!Directory.Exists(DirectoryPath))
{
Directory.CreateDirectory(DirectoryPath);
}
fullFileName = Path.Combine(DirectoryPath, fileName);
// 파일 업로드
using (StreamWriter outputFile = new StreamWriter(fullFileName))
{
outputFile.WriteLine("<html>");
outputFile.WriteLine("<head>");
outputFile.WriteLine("<meta charset=\"UTF-8\">");
outputFile.WriteLine("<title>");
outputFile.WriteLine(this.ltrlTitle.Text);
outputFile.WriteLine("</title>");
outputFile.WriteLine("</head>");
outputFile.WriteLine("<body>");
outputFile.WriteLine(this.ltrlContents.Text);
outputFile.WriteLine("</body>");
outputFile.WriteLine("</html>");
}
// 파일 다운로드
FileInfo file = new FileInfo(fullFileName);
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
Response.AddHeader("Content-Length", file.Length.ToString());
Response.BufferOutput = false;
Response.OutputStream.Write(File.ReadAllBytes(fullFileName), 0, (int)file.Length);
Response.Flush();
// 파일 삭제
file.Delete();
}
System.IO
C#에서 파일 및 데이터 스트림에 대한 읽기와 쓰기를 허용하는 것과 파일과 디렉터리에 관한 namespace입니다. Web Forms의 웹 서버 컨트롤 file을 이용하여 서버에 파일을 저장할 때 주로 사용합니다.
StreamWriter
특정 인코딩으로 stream에 문자를 쓸 수 있습니다. 별도로 지정하지 않으면 기본으로 UTF-8로 인코딩 됩니다.
StreamWriter는 문자용으로 설계된 반면에 Stream은 바이트로 설계되어 있습니다.
using을 사용하여 자원 관리를 해주어야 합니다. using으로 인해 코드 사용이 완료되면 자동으로 Dispose를 호출하여 자원을 해제합니다.
IDisposable 인터페이스를 구현합니다. 그렇기 때문에 사용을 하고 나면 자원을 직접 또는 간접적으로 폐기해야 합니다.
FileInfo
파일을 생성, 복사, 삭제, 이동 그리고 파일 정보에 관한 메서드를 제공하고 FileStream 생성을 지원합니다.
HTTP Response Setting
- Header : Content-Disposition
Disposition은 배치, 배열, 성향이라는 뜻을 가지고 있습니다. HTTP 응답 해더에 콘텐츠의 성향을 알려줍니다. attachment와 filename을 함께 설정하면 filename을 다운로드 하라는 뜻입니다. - IIS가 응답을 버퍼링 하는 것을 중지하려면 클라이언트가 헤더를 덮어써야 합니다. Reponsse BufferOutput 속성을 false로 지정해주어야 합니다.
- Flush 메서드를 호출하여 클라이언트에게 HTTP 응답 콘텐츠를 전송합니다.
참고
https://learn.microsoft.com/en-us/dotnet/api/system.io?view=netframework-4.5
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter?view=netframework-4.5
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileinfo?view=netframework-4.5
https://stackoverflow.com/questions/24821/why-is-response-bufferoutput-false-not-working
https://learn.microsoft.com/ko-kr/dotnet/api/system.web.httpresponse.flush?view=netframework-4.5