C#/이모저모

파일 생성 및 다운로드 관리(물리 경로 vs 가상 경로)_Web

Red_Horse 2025. 11. 27. 00:18

물리 경로 (Physical Path)

// Server.MapPath()로 변환
string physicalPath = Server.MapPath("~/Content/Data");
// 결과: C:\Projects\MyApp\Content\Data

// 사용: 파일 시스템 작업
Directory.CreateDirectory(physicalPath);
File.WriteAllBytes(Path.Combine(physicalPath, "file.xlsx"), bytes);
File.Delete(Path.Combine(physicalPath, "file.xlsx"));

특징:

  • 실제 디스크 경로
  • 운영체제 파일 시스템이 이해하는 경로
  • C#의 File, Directory 클래스가 사용

가상 경로 (Virtual Path)

// 웹 URL 경로
string virtualPath = "/Content/Data/file.xlsx";

// 사용: 다운로드 링크
return Json(new { Data = virtualPath });

특징:

  • 웹 서버가 이해하는 경로
  • 브라우저가 접근하는 경로
  • 도메인 + 가상 경로 = 완전한 URL

분리해서 사용하는 이유

1. 역할이 다름

// 물리 경로로 다운로드 링크 만들면?
string physicalPath = "C:\\Projects\\MyApp\\Content\\file.xlsx";
return Json(new { Data = physicalPath });

// JavaScript에서
window.location.href = "C:\\Projects\\MyApp\\Content\\file.xlsx";
// 브라우저는 이걸 이해 못 함!
// 로컬 파일 시스템 접근은 보안상 차단됨! (브라우저에서 PC로 접근하려는 모습)
 
// 가상 경로로 다운로드 링크
string virtualPath = "/Content/file.xlsx";
return Json(new { Data = virtualPath });

// JavaScript에서
window.location.href = "/Content/file.xlsx";
// 브라우저가 이해 할수 있는 경로!
// 실제 요청: http://localhost/Content/file.xlsx
// 실행되고 있는 프로젝트 경로로 접근

 

2. 서버 환경마다 물리 경로가 다름

개발 서버: C:\Projects\MyApp\Content\file.xlsx
스테이징: D:\WebApps\MyApp\Content\file.xlsx
운영 서버: E:\inetpub\wwwroot\MyApp\Content\file.xlsx

가상 경로는 모든 환경에서 동일: /Content/file.xlsx
물리 경로는 환경마다 다름

 

3. 보안

// 물리 경로 노출 위험
return Json(new { Data = "C:\\Projects\\MyApp\\Content\\file.xlsx" });
// 사용자가 서버 구조를 알게 됨!(PC 경로 구성을 외부에 보이게됨)

// 가상 경로는 안전
return Json(new { Data = "/Content/file.xlsx" });
// 서버 구조는 숨겨짐

 

동작 원리

1. 파일 저장 (물리 경로)

// Step 1: 물리 경로 얻기
string physicalPath = Server.MapPath("~/Content/Data");
// C:\Projects\MyApp\Content\Data

// Step 2: 파일 시스템에 저장
File.WriteAllBytes(Path.Combine(physicalPath, "file.xlsx"), bytes);
// C:\Projects\MyApp\Content\Data\file.xlsx 생성

물리 경로를 사용하는 이유

  • File.WriteAllBytes()는 운영체제 API 호출
  • 운영체제는 물리 경로만 이해함
  • /Content/file.xlsx 같은 가상 경로는 이해 못 함(브라우저 접근용)

2. 다운로드 링크 (가상 경로)

// Step 1: 가상 경로 생성
string virtualPath = "/Content/Data/file.xlsx";

// Step 2: 클라이언트에 전달
return Json(new { Data = virtualPath });

 

window.location.href = "/Content/Data/file.xlsx";
// 브라우저가 요청: http://localhost/Content/Data/file.xlsx
//서버에서 (IIS/ASP.NET):**

1. 요청 받음: GET /Content/GoodsSelectJson/file.xlsx
2. 가상 경로를 물리 경로로 변환: C:\Projects\MyApp\Content\Data\file.xlsx
3. 파일 읽기
4. 응답 전송

 

예시

// Controllers/PresentController.cs
public ActionResult PresentInfomation(...)
{
    // 1. 물리 경로로 파일 저장
    string physicalFolder = Server.MapPath("~/Content/Present");
    // C:\Projects\MyApp\Content\Present
    
    if (!Directory.Exists(physicalFolder))
    {
        Directory.CreateDirectory(physicalFolder);
        // 물리 폴더 생성: C:\Projects\MyApp\Content\Present
    }
    
    string fileName = "items_20241126.xlsx";
    string physicalFilePath = Path.Combine(physicalFolder, fileName);
    // C:\Projects\MyApp\Content\Present\items_20241126.xlsx
    
    File.WriteAllBytes(physicalFilePath, excelBytes);
    // 운영체제 파일 시스템에 저장
    
    // 2. 가상 경로로 다운로드 링크 생성
    string virtualPath = $"/Content/Present/{fileName}";
    // /Content/Present/items_20241126.xlsx
    
    return Json(new
    {
        Success = true,
        Data = virtualPath  // 가상 경로 반환
    });
}
 
// JavaScript
$.ajax({
    success: function(result) {
        // result.Data = "/Content/Present/items_20241126.xlsx"
        
        // 3. 브라우저가 다운로드 요청
        window.location.href = result.Data;
        // 실제 요청: http://localhost/Content/Present/items_20241126.xlsx
    }
});
```
```
4. IIS/ASP.NET 처리(자동으로 됨)
요청: GET /Content/Present/items_20241126.xlsx

IIS:
- 가상 경로: /Content/Present/items_20241126.xlsx
- 물리 경로 변환: C:\Projects\MyApp\Content\Present\items_20241126.xlsx
- 파일 읽기
- 응답 전송 (파일 다운로드)

 

파일 삭제

// Controller
[HttpPost]
public ActionResult DeleteTemporaryFile(string fileUrl)
{
    // fileUrl = "/Content/Present/file.xlsx" (가상 경로)
    
    // 가상 경로를 물리 경로로 변환
    string physicalPath = Server.MapPath("~" + fileUrl);
    // C:\Projects\MyApp\Content\Present\file.xlsx
    
    // 물리 경로로 삭제
    if (File.Exists(physicalPath))
    {
        File.Delete(physicalPath);
    }
    
    return Json(new { Success = true });
}

 

만약 IIS가 없다면?

// 이렇게 직접 구현해야 함
public ActionResult DownloadFile(string fileName)
{
    // 가상 경로를 물리 경로로 변환
    string physicalPath = Server.MapPath($"~/Content/Present/{fileName}");
    
    if (!File.Exists(physicalPath))
    {
        return HttpNotFound();
    }
    
    // 파일 읽기
    byte[] fileBytes = File.ReadAllBytes(physicalPath);
    
    // 파일 전송
    return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}

// 사용
// window.location.href = "/Present/DownloadFile?fileName=file.xlsx";

 

비교표

항목 물리 경로 가상 경로
예시 C:\Projects\MyApp\Content\file.xlsx /Content/file.xlsx
사용 대상 파일 시스템 (C#) 웹 서버 (브라우저)
사용 시점 파일 생성/삭제/읽기 다운로드 링크/URL
환경 의존성 환경마다 다름 모든 환경 동일
보안 서버 구조 노출 안전
브라우저 접근 불가능 가능
File.WriteAllBytes 가능 불가능
window.location 불가능 가능

 

'C# > 이모저모' 카테고리의 다른 글

WebSocket 채팅 시스템  (0) 2026.03.22
WebSocket  (0) 2026.03.22
웹 애플리케이션(.NET)  (0) 2025.11.30
임시 파일 자동정리(.NET TimerQueue & .NET IHostedService)  (0) 2025.11.27
IIS(Internet Information Services)  (0) 2025.11.27