
C#에서 파일과 디렉토리를 다룰 때 주로 사용하는 네임스페이스와 클래스들:
using System;
using System.IO;
// 방법 1: Directory.CreateDirectory (정적 메서드)
string dirPath = @"C:\MyApp\Logs";
DirectoryInfo createdDir = Directory.CreateDirectory(dirPath);
Console.WriteLine($"디렉토리 생성됨: {createdDir.FullName}");
// 방법 2: DirectoryInfo 클래스 사용
DirectoryInfo dirInfo = new DirectoryInfo(@"C:\MyApp\Data");
if (!dirInfo.Exists)
{
dirInfo.Create();
Console.WriteLine("디렉토리가 생성되었습니다.");
}
// 여러 단계의 디렉토리를 한 번에 생성
string nestedPath = @"C:\MyApp\Year2025\Month05\Day29";
Directory.CreateDirectory(nestedPath);
// 존재하지 않는 모든 상위 디렉토리도 자동으로 생성됩니다.
// 현재 실행 디렉토리 기준으로 상대 경로 사용
string relativePath = Path.Combine("Data", "Logs", DateTime.Now.ToString("yyyy-MM"));
DirectoryInfo dir = Directory.CreateDirectory(relativePath);
Console.WriteLine($"생성된 경로: {dir.FullName}");
using System;
using System.IO;
using System.Text;
public class FileManager
{
public void CreateLogFile(string directoryPath, string content)
{
try
{
// 1. 디렉토리 생성 (존재하지 않을 경우)
Directory.CreateDirectory(directoryPath);
// 2. 파일 경로 생성
string fileName = $"log_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
string filePath = Path.Combine(directoryPath, fileName);
// 3. 파일 생성 및 내용 쓰기
using (StreamWriter writer = new StreamWriter(filePath, append: true, Encoding.UTF8))
{
writer.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {content}");
}
Console.WriteLine($"로그 파일 생성: {filePath}");
}
catch (Exception ex)
{
Console.WriteLine($"파일 생성 오류: {ex.Message}");
}
}
}
using System;
using System.IO;
using System.Threading.Tasks;
public class ModernFileManager
{
public async Task CreateFileAsync(string directoryPath, string fileName, string content)
{
try
{
// 디렉토리 생성
Directory.CreateDirectory(directoryPath);
// 파일 경로
string filePath = Path.Combine(directoryPath, fileName);
// 비동기 파일 쓰기 (.NET 6.0+)
await File.WriteAllTextAsync(filePath, content);
Console.WriteLine($"파일 생성 완료: {filePath}");
}
catch (Exception ex)
{
Console.WriteLine($"파일 생성 실패: {ex.Message}");
}
}
}
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public class LogManager
{
private readonly string _baseLogPath;
private readonly object _lockObject = new object();
public LogManager(string baseLogPath = "Logs")
{
_baseLogPath = baseLogPath;
}
public void WriteLog(string message, LogLevel level = LogLevel.Info)
{
try
{
// 날짜별 디렉토리 생성
string dateFolder = DateTime.Now.ToString("yyyy-MM");
string logDirectory = Path.Combine(_baseLogPath, dateFolder);
Directory.CreateDirectory(logDirectory);
// 파일명 생성
string fileName = $"{DateTime.Now:yyyyMMdd}_{level}.log";
string filePath = Path.Combine(logDirectory, fileName);
// Thread-safe 파일 쓰기
lock (_lockObject)
{
using (StreamWriter writer = new StreamWriter(filePath, append: true))
{
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{level}] {message}";
writer.WriteLine(logEntry);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"로그 쓰기 실패: {ex.Message}");
}
}
public async Task WriteLogAsync(string message, LogLevel level = LogLevel.Info)
{
try
{
string dateFolder = DateTime.Now.ToString("yyyy-MM");
string logDirectory = Path.Combine(_baseLogPath, dateFolder);
Directory.CreateDirectory(logDirectory);
string fileName = $"{DateTime.Now:yyyyMMdd}_{level}.log";
string filePath = Path.Combine(logDirectory, fileName);
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{level}] {message}{Environment.NewLine}";
// 비동기 파일 쓰기
await File.AppendAllTextAsync(filePath, logEntry);
}
catch (Exception ex)
{
Console.WriteLine($"비동기 로그 쓰기 실패: {ex.Message}");
}
}
}
public enum LogLevel
{
Info,
Warning,
Error,
Debug
}
class Program
{
static async Task Main(string[] args)
{
var logManager = new LogManager("C:\\MyApp\\Logs");
// 동기 방식
logManager.WriteLog("애플리케이션 시작", LogLevel.Info);
logManager.WriteLog("경고 메시지", LogLevel.Warning);
// 비동기 방식
await logManager.WriteLogAsync("비동기 로그 테스트", LogLevel.Debug);
Console.WriteLine("로그 작성 완료!");
}
}
public class SafeFileManager
{
public bool CreateDirectoryAndFile(string directoryPath, string fileName, string content)
{
try
{
// 디렉토리 생성
Directory.CreateDirectory(directoryPath);
string filePath = Path.Combine(directoryPath, fileName);
// 파일 쓰기
File.WriteAllText(filePath, content);
return true;
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("권한이 없습니다. 관리자 권한으로 실행하거나 다른 경로를 사용하세요.");
return false;
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("지정된 경로의 일부를 찾을 수 없습니다.");
return false;
}
catch (IOException ex)
{
Console.WriteLine($"I/O 오류 발생: {ex.Message}");
return false;
}
catch (ArgumentException)
{
Console.WriteLine("잘못된 경로 형식입니다.");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"예상치 못한 오류: {ex.Message}");
return false;
}
}
}
public async Task WriteLargeFileAsync(string filePath, IEnumerable<string> lines)
{
using (StreamWriter writer = new StreamWriter(filePath, append: false))
{
foreach (string line in lines)
{
await writer.WriteLineAsync(line);
}
}
}
public void WriteWithBuffer(string filePath, string[] data)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create))
using (BufferedStream bs = new BufferedStream(fs, bufferSize: 65536)) // 64KB 버퍼
using (StreamWriter writer = new StreamWriter(bs))
{
foreach (string item in data)
{
writer.WriteLine(item);
}
}
}
A: Directory.CreateDirectory()는 디렉토리가 이미 존재해도 예외를 발생시키지 않습니다. 안전하게 여러 번 호출할 수 있습니다.
A: IOException이 발생할 수 있습니다. 재시도 로직을 구현하거나 다른 파일명을 사용하세요.
public string GetAvailableFileName(string directoryPath, string baseFileName)
{
string filePath = Path.Combine(directoryPath, baseFileName);
int counter = 1;
while (File.Exists(filePath))
{
string nameWithoutExt = Path.GetFileNameWithoutExtension(baseFileName);
string extension = Path.GetExtension(baseFileName);
string newFileName = $"{nameWithoutExt}_{counter}{extension}";
filePath = Path.Combine(directoryPath, newFileName);
counter++;
}
return filePath;
}
A: Path.Combine(), Path.DirectorySeparatorChar 등을 사용하여 플랫폼별 경로 구분자를 자동으로 처리하세요.
// 올바른 방법 - 모든 플랫폼에서 동작
string path = Path.Combine("Users", "Documents", "MyApp");
// 잘못된 방법 - Windows에서만 동작
string wrongPath = "Users\\Documents\\MyApp";
이 포스트가 도움이 되었다면 댓글로 피드백을 남겨주세요! 🙏
관련 포스트:
| C#으로 텍스트 파일 읽고 문자열 분리하기 (0) | 2021.04.29 |
|---|---|
| ASP.NET - GET, POST 방식 차이 (0) | 2018.09.04 |
| ASP.NET - ServerVariable 컬렉션 (0) | 2018.09.04 |
| C# - 네이밍 룰 (4) | 2018.09.04 |
| ASP.NET - 웹 켄버스(Silver Light) (0) | 2018.01.02 |
댓글 영역