C# 파일 다루기

김민구·2025년 5월 27일
0

C#

목록 보기
28/31

1. 파일 및 디렉터리 정보 다루기

C#에서 파일 시스템 정보를 다루기 위해 여러 클래스가 제공됩니다. 소스에서는 File, FileInfo, Directory, DirectoryInfo 클래스를 언급하고 있습니다. 이 클래스들을 사용하여 파일이나 디렉터리의 존재 여부를 확인하거나, 생성, 삭제, 이름 변경, 시간 정보 확인 등의 작업을 수행할 수 있습니다 [예: 8, 9].

예를 들어, 특정 경로가 파일인지 디렉터리인지 확인하고, 존재한다면 마지막 쓰기 시간을 업데이트하거나, 존재하지 않는다면 파일이나 디렉터리를 새로 생성하는 코드를 살펴볼 수 있습니다.

2. 파일 읽고 쓰기의 기본: Stream

파일의 내용을 직접 읽거나 쓸 때는 '스트림(Stream)'이라는 개념을 사용합니다. 스트림은 데이터가 흐르는 통로와 같으며, 파일을 읽거나 쓰는 작업은 이 스트림을 통해 바이트 단위로 이루어집니다. System.IO.Stream 클래스는 모든 스트림의 기본 클래스이며, FileStream, NetworkStream, BufferedStream, GZipStream 등 다양한 종류의 스트림이 이 클래스를 상속받아 구현됩니다.

FileStream은 파일을 다루는 가장 기본적인 스트림으로, 파일을 열 때 FileMode 열거형을 사용하여 어떤 방식으로 열지를 지정할 수 있습니다.

  • FileMode.Create: 파일을 새로 생성합니다. 파일이 이미 있으면 덮어씁니다.
  • FileMode.Open: 기존 파일을 엽니다.
  • FileMode.OpenOrCreate: 파일이 있으면 열고, 없으면 새로 생성합니다.
  • FileMode.Truncate: 기존 파일의 내용을 모두 지우고 엽니다.
  • FileMode.Append: 기존 파일의 끝에 이어서 쓰도록 엽니다.

스트림을 통해 데이터를 쓸 때는 Write() 또는 WriteByte() 메서드를, 읽을 때는 Read() 또는 ReadByte() 메서드를 사용합니다. 이 메서드들은 바이트 배열이나 단일 바이트 단위로 데이터를 처리합니다.

using 선언의 중요성: 파일 스트림과 같은 리소스는 사용 후 반드시 닫아주어야 합니다 (Close() 또는 Dispose()). 이를 놓치면 문제가 발생할 수 있는데, C#에서는 using 선언을 통해 스트림 사용 범위를 벗어나면 자동으로 Dispose() 메서드가 호출되도록 하여 이러한 문제를 방지할 수 있습니다. 이는 리소스 관리를 간편하고 안전하게 만들어 줍니다.

3. 바이너리 데이터 처리: BinaryWriter/BinaryReader

숫자나 문자열 등 정형화된 바이너리 형식의 데이터를 읽고 쓸 때는 BinaryWriterBinaryReader 클래스를 사용하는 것이 편리합니다. 이 클래스들은 다양한 기본 데이터 형식(int, string, double 등)을 바이너리 형식으로 파일에 쓰거나 읽는 메서드를 제공합니다.

예를 들어, BinaryWriterWrite(32), Write("Good Morning!"), Write(3.14)와 같이 데이터를 형식에 맞춰 바로 쓸 수 있습니다. BinaryReaderReadInt32(), ReadString(), ReadDouble()과 같이 해당 형식에 맞는 메서드를 호출하여 데이터를 읽어옵니다.

참고로, BinaryWriter로 문자열을 저장할 때는 문자열의 길이 정보가 먼저 저장된 후 문자열 데이터가 뒤따라 저장됩니다.

4. 텍스트 파일 처리: StreamWriter/StreamReader

사람이 읽을 수 있는 일반 텍스트 파일을 다룰 때는 StreamWriterStreamReader 클래스를 사용하는 것이 편리합니다. 이 클래스들은 내부적으로 스트림을 사용하며, 인코딩 방식 등을 지정하여 문자를 읽고 쓸 수 있습니다.

StreamWriterWriteLine()과 같은 메서드를 제공하여 데이터를 쓰고 줄바꿈 문자를 자동으로 추가할 수 있습니다. StreamReaderReadLine() 메서드를 사용하여 한 줄씩 텍스트를 읽거나, EndOfStream 속성을 통해 파일의 끝에 도달했는지 확인할 수 있습니다.

5. 객체 직렬화 (Serialization)

객체 직렬화는 메모리에 있는 객체의 상태를 파일이나 네트워크 등으로 저장하거나 전송할 수 있는 연속적인 데이터 형식으로 변환하는 과정입니다. .NET에서는 다양한 직렬화 형식을 지원하지만, 소스에서는 특히 JSON 형식의 직렬화를 다루고 있습니다.

JSON 직렬화를 사용하면 복잡한 객체를 간단하게 파일로 저장하고, 다시 객체로 불러올 수 있습니다. System.Text.Json.JsonSerializer 클래스를 사용하여 객체를 JSON 문자열로 변환하거나 (Serialize), JSON 문자열을 다시 객체로 변환할 수 있습니다 (Deserialize). 변환된 JSON 문자열은 파일 스트림 등을 통해 파일에 쓰고 읽을 수 있습니다.

클래스의 특정 프로퍼티를 직렬화 대상에서 제외하고 싶다면 [JsonIgnore] 속성을 해당 프로퍼티에 붙일 수 있습니다. 또한, 단일 객체뿐만 아니라 객체 컬렉션(List<T> 등)도 JSON 형식으로 직렬화하고 역직렬화할 수 있습니다.

그 외 중요 사항

  • 바이트 순서 (Endianness): 컴퓨터 시스템에 따라 데이터를 저장하는 바이트 순서(리틀 엔디안 또는 빅 엔디안)가 다를 수 있습니다. C#은 일반적으로 CLR이 지원하는 바이트 순서(리틀 엔디안)를 따르지만, 다른 시스템과 데이터를 주고받을 때는 바이트 순서를 고려해야 합니다.
  • 파일 입출력의 복잡성: 메모리의 데이터 구조와 파일/네트워크 저장 장치의 데이터 구조는 다르기 때문에 파일 입출력은 생각보다 복잡할 수 있습니다. Stream 클래스를 통한 프로그래밍 모델을 익히는 것이 중요하며, FileStream과 같은 특정 구현체에 대한 이해도 필요합니다.
profile
C#, Unity

0개의 댓글