비동기 파일 입출력

00·2025년 1월 20일

C#

목록 보기
147/149

비동기 파일 입출력

비동기 파일 입출력은 파일을 읽고 쓰는 작업을 비동기적으로 수행하는 것을 의미한다. 즉, 파일 작업이 완료될 때까지 기다리지 않고 다른 작업을 계속 수행할 수 있다.

이는 UI 응답성을 유지하거나 CPU를 효율적으로 사용하는 데 유용하다.

C#에서는 asyncawait 키워드를 사용하여 비동기 파일 입출력을 쉽게 구현할 수 있다. FileStream 클래스는 비동기 파일 입출력을 위한 ReadAsync() 메서드와 WriteAsync() 메서드를 제공한다.

ReadAsync() 메서드

  • 파일에서 데이터를 비동기적으로 읽는다.
  • Task<int> 객체를 반환한다. Task<int> 객체는 비동기 작업의 결과를 나타내며, Result 프로퍼티를 통해 읽어온 바이트 수를 가져올 수 있다.

WriteAsync() 메서드

  • 파일에 데이터를 비동기적으로 쓴다.
  • Task 객체를 반환한다. Task 객체는 비동기 작업을 나타내며, Wait() 메서드를 사용하여 작업이 완료될 때까지 기다릴 수 있다.

예시

using (FileStream fileStream = new FileStream("file.txt", FileMode.Open))
{
    byte[] buffer = new byte[1024];
    int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length);
    // ...
}

이 코드는 file.txt 파일에서 1024 바이트를 비동기적으로 읽어온다. await 키워드는 ReadAsync() 메서드가 완료될 때까지 기다린다.


예제 코드

using System;  // 기본적인 C# 기능을 사용하기 위해 필요한 네임스페이스
using System.IO; // 파일 입출력을 위한 FileStream 클래스를 사용하기 위해 필요한 네임스페이스
using System.Threading.Tasks;  // 비동기 작업을 위한 Task 클래스를 사용하기 위해 필요한 네임스페이스

namespace AsyncFileIO  // AsyncFileIO라는 이름의 네임스페이스를 정의한다
{
    class MainApp  // MainApp이라는 이름의 클래스를 정의한다
    {
        // 파일 복사 후 복사한 파일 용량을 반환하는 비동기 메서드이다.
        static async Task<long> CopyAsync(string FromPath, string ToPath)  
        {
            using (var fromStream = new FileStream(FromPath, FileMode.Open))  // FromPath 경로의 파일을 읽기 모드로 연다. using 구문을 사용하여 스트림을 자동으로 닫는다.
            {
                long totalCopied = 0;  // 복사된 바이트 수를 저장할 변수를 0으로 초기화한다.

                using (var toStream = new FileStream(ToPath, FileMode.Create))  // ToPath 경로의 파일을 쓰기 모드로 연다. 만약 파일이 없으면 새로 생성한다. using 구문을 사용하여 스트림을 자동으로 닫는다.
                {
                    byte[] buffer = new byte[1024];  // 1024 바이트 크기의 버퍼를 생성한다. 파일 데이터를 버퍼 단위로 읽고 쓴다.
                    int nRead = 0;  // 읽어온 바이트 수를 저장할 변수를 선언한다.

                    // fromStream에서 데이터를 읽어와 toStream에 쓸 때까지 반복한다.
                    while ((nRead = await fromStream.ReadAsync(buffer, 0, buffer.Length)) != 0)  // fromStream에서 buffer 크기만큼 데이터를 비동기적으로 읽어온다. 읽어온 바이트 수를 nRead에 저장한다.
                    {
                        await toStream.WriteAsync(buffer, 0, nRead);  // toStream에 buffer의 내용을 비동기적으로 쓴다.
                        totalCopied += nRead;  // 복사된 바이트 수를 누적한다.
                    }
                }  // toStream을 닫는다.

                return totalCopied;  // 복사된 바이트 수를 반환한다.
            }  // fromStream을 닫는다.
        }

        static async void DoCopy(string FromPath, string ToPath)  // 파일 복사를 수행하는 비동기 메서드이다.
        {
            long totalCopied = await CopyAsync(FromPath, ToPath);  // CopyAsync 메서드를 호출하여 파일을 복사하고, 복사된 바이트 수를 totalCopied에 저장한다.
            Console.WriteLine($"Copied Total {totalCopied} Bytes.");  // 복사된 바이트 수를 출력한다.
        }

        static void Main(string[] args)  // 프로그램의 진입점이다.
        {
            if (args.Length < 2)  // 명령줄 인수가 2개 미만이면
            {
                Console.WriteLine("Usage : AsyncFileIO <Source> <Destination>");  // 사용법을 출력하고
                return;  // 프로그램을 종료한다.
            }

            DoCopy(args[0], args[1]);  // DoCopy 메서드를 호출하여 파일을 복사한다.

            Console.ReadLine();  // 사용자 입력을 기다린다.
        }
    }
}

코드 설명

이 C# 코드는 비동기 파일 입출력을 사용하여 파일을 복사하는 프로그램이다.

CopyAsync 메서드는 FileStreamasync/await 키워드를 사용하여 파일을 비동기적으로 복사하고, DoCopy 메서드는 CopyAsync 메서드를 호출하여 파일 복사를 수행한다. Main 메서드는 명령줄 인수를 확인하고 DoCopy 메서드를 호출한다.

async/await 키워드

  • async 키워드는 메서드가 비동기적으로 실행될 수 있음을 나타낸다.
  • await 키워드는 비동기 작업이 완료될 때까지 메서드의 실행을 일시 중지한다.

FileStream 클래스

  • FileStream 클래스는 파일을 읽고 쓰는 데 사용된다.
  • FileMode.Open: 기존 파일을 연다.
  • FileMode.Create: 새 파일을 생성한다. 파일이 이미 있으면 덮어쓴다.

ReadAsync 메서드

  • ReadAsync 메서드는 파일에서 데이터를 비동기적으로 읽는다.

WriteAsync 메서드

  • WriteAsync 메서드는 파일에 데이터를 비동기적으로 쓴다.

출력 결과

Copied Total {파일 크기} Bytes.

오류 발생

출력 결과 다음과 같은 메시지가 콘솔에 표시된다.

Usage : AsyncFileIO <Source> <Destination>

해결 방법

Usage : AsyncFileIO <Source> <Destination> 이 출력 결과는 사용자가 프로그램 실행 시 필요한 명령줄 인수를 입력하지 않았을 때 나타나는 메시지이다. 즉, 프로그램을 실행하려면 <Source><Destination>에 해당하는 파일 경로를 입력해야 한다.

예를 들어, "source.txt" 파일을 "destination.txt" 파일로 복사하려면 다음과 같이 명령줄에 입력해야 한다.

AsyncFileIO source.txt destination.txt

0개의 댓글