반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발꿈나무

[C# 교과서] 35. C# 확장 기능(10) - 스트림과 파일 입출력 본문

C# 기초

[C# 교과서] 35. C# 확장 기능(10) - 스트림과 파일 입출력

HYOKYE0NG 2022. 1. 26. 14:24
반응형
스트림과 파일 입출력

 

프로그램 코드에서 작성된 데이터를 목적에 따라 영구적으로 보관해야 할 때가 있는데, 이때는 파일이나 데이터베이스에 저장한다. 파일에 데이터를 저장하고 이를 사용해보자.

 

System.IO 네임스페이스

C#에서 파일에 대한 입력과 출력을 담당하는 네임스페이스는 System.IO이며, 수많은 파일과 디렉터리 관련 클래스를 제공한다.

 

  • File.Exists(): 지정된 경로에 파일이 있으면 true, 없으면 false 반환
  • new DirectoryInfo().Parent.FullName: 지정된 경로의 부모 폴더 값 반환
  • Path.GetDirectoryName(): 지정한 경로의 디렉터리 값 반환
  • Path.Combile(): 졍로 2개를 합치거나 경로와 파일 이름을 묶어서 반환
  • Directory.Exists(): 지정된 디렉터리가 있는지 확인
  • Directory.CreateDirectory(): 디렉터리 생성
  • Directory.Delete(): 디렉터리 삭제
  • Path.GetFileName(): 파일 이름 추출
  • Path.GetExtension(): 파일 확장자 추출
  • File.Copy(): 파일 복사
  • File.Move(): 파일 이동
  • Directory.GetFiles(): 지정된 경로의 파일 이름 리스트를 문자열 배열로 반환
  • File.ReadAllText(): 텍스트 파일 읽기
  • File.WriteAllText(): 텍스트 파일 쓰기
  • File.ReadAllLines(): 텍스트 파일의 모든 줄을 읽어 문자열 배열로 반환
  • File.WriteAllLines(): 문자열 배열을 줄 단위로 텍스트 파일에 저장
  • File.AppendAllText(): 텍스트 파일에 내용 추가
  • File.AppendAllLines(): 컬렉션 형태의 문자열 추가
  • File.ReadAllBytes(): 바이너리 파일 읽기
  • File.ReadAllBytes(): 바이너리 파일 쓰기

 

File 클래스와 Stream 클래스

  • File 클래스: File 클래스는 사용하기 편하지만 모든 파일 내용을 다 읽어 처리하기 때문에 대용량 파일을 처리할 때는 메모리를 관리하기 어렵다.
  • Stream 클래스: Stream 클래스는 모든 데이터를 메모리에 올려 두지 않고 사용하기 때문에 대용량 파일 처리에 효과적이다.

 

 

문자열에서 파일 이름 추출하기

using System;

class GetFileNameDemo
{
    static void Main()
    {
        //[Q] 아래 전체 경로가 입력되었을 때 파일명과 확장자 추출      
        //[1] Input
        string dir = "C:\\Website\\RedPlus\\images\\test.gif";
        string fullName = String.Empty;
        string name = "";
        string ext = name;

        //[2] Process
        // 전체파일명: 마지막 \\ 위치값 + 1한 위치부터 마지막까지 검색
        fullName = dir.Substring(dir.LastIndexOf('\\') + 1);
        name = fullName.Substring(0, fullName.LastIndexOf('.'));
        ext = fullName.Substring(fullName.LastIndexOf('.') + 1);

        //[3] Output
        Console.WriteLine($"전체 파일명: {fullName}");
        Console.WriteLine($"순수 파일명: {name}");
        Console.WriteLine($"확장자: {ext}");
    }
}

/*
전체 파일 이름 : test.gif
순수 파일 이름 : test
확장자 : gif
*/

substring(n, m)은 n부터 m개의 문자를 읽어오는 메소드로,

매개변수가 하나만 들어온다면 해당 번째 문자부터 마지막 문자까지 읽어온다.

 

 

Path 클래스로 파일 이름 및 확장자, 폴더 정보 얻기

var dir = "C:\\Website\\RedPlus\\images\\test.gif";
Path.GetFileName(dir) //test.gif
Path.GetFileNameWithoutExtension(dir) //test
Path.GetExtension(dir) //.gif
Path.GetDirectoryName(dir) //C:\\Website\\RedPlus\\images
Path.GetFullPath(dir) //C:\\Website\\RedPlus\\images\\test.gif

다음 코드를 C# 인터렉티브(Ctrl + E + E)에서 실행해보면 주석과 같은 결과가 나올 것이다.

 

 

파일과 디렉터리 관련 클래스

파일을 생성하고 삭제하는 일반적인 절차는 다음과 같다.

  • StreamWriter 클래스를 사용하여 텍스트 파일 쓰기
  • StreamReader 클래스를 사용하여 텍스트 파일 읽기
  • File과 FileInfo 클래스로 파일 정보 얻기
  • Directory와 DirectoryInfo 클래스로 폴더 정보 얻기

 

 

텍스트 파일을 만드록 문자열 저장하기

윈도 운영 체제의 C 드라이브에 Temp 폴더를 경로로 설정했지만 개인의 실행환경에 맞춰 경로를 변경하면 된다.

using System;
using System.IO;

class StreamWriterWriteLineDemo
{
    static void Main()
    {
        string data =
            "안녕하세요.\r\n반가습니다." + Environment.NewLine + "또 만나요.";

        //[1] StreamWriter 클래스를 사용하여 파일 생성
        // C 드라이브에 Temp 폴더 미리 생성해야 함
        StreamWriter sw = new StreamWriter("C:\\Temp\\Test.txt");
        
        //[2] Write() 메서드 : 저장
        sw.WriteLine(data);

        //[3] StreamWrite 개체를 생성했으면 반드시 닫기
        sw.Close();
        
        //[4] 메모리 해제 
        sw.Dispose();
    }
}

코드를 실행하면 C 드라이브의 Temp 폴더에 Test.txt 파일이 만들어지고 data 변수에 지정된 문자열 값이 저장된다.

문자열의 \r\n 또는 Environment.NewLine 값은 텍스트 파일에서 줄 바꿈을 나타낸다.

 

[1]의 StreamWriter 같은 파일 처리 관련 클래스의 인스턴스를 생성하고 사용했다면, 반드시 [3]. [4]처럼 닫기와 해제

작업을 해주어야 한다.

 

 

텍스트 파일의 내용을 읽어 출력하기

using System;
using System.IO;

class StreamReaderReadToEndDemo
{
    static void Main()
    {
        //[1] StreamReader 클래스로 텍스트 파일 읽기
        StreamReader sr = new StreamReader(@"C:\Temp\Test.txt");

        //[2] ReadToEnd() 메서드로 텍스트 파일의 내용 읽어 콘솔에 출력하기 
        Console.WriteLine("{0}", sr.ReadToEnd()); // 전체 읽어오기

        //[3] 사용 후 파일 닫고 메모리 정리하기 
        sr.Close(); 
        sr.Dispose();
    }
}

C드라이버의 Temp 폴더에 Test.txt라는 파일이 있다는 가정하에 코드를 작성하였다.

해당 경로에 텍스트 파일을 추가하던가, 자신의 텍스트 파일 경로로 바꿔 코드를 실행하면 된다.

 

[1]의 StreamReader 같은 파일 처리 관련 클래스의 인스턴스를 생성하고 사용했다면, 반드시 [3]. [4]처럼 닫기와 해제

작업을 해주어야 한다.

 

 

텍스트 파일 정보 얻기

using System;
using System.IO;

class FileAndFileInfo
{
    static void Main()
    {
        string file = "C:\\Temp\\Test.txt";

        //[1] File 클래스: 정적 멤버 제공
        if (File.Exists(file)) // 파일이 있다면.
        {
            Console.WriteLine("{0}", File.GetCreationTime(file));
            File.Copy(file, "C:\\Temp\\Test2.txt", true); // 파일 복사 테스트
        }

        //[2] FileInfo 클래스: 인스턴스 멤버 제공
        FileInfo fi = new FileInfo(file);
        if (fi.Exists) // 파일이 존재한다면,
        {
            Console.WriteLine($"{fi.FullName}"); // 파일명 출력
        }
    }
}

/*
2022-01-25 오후 14:14:56
C:\TEMP\Test.txt
*/

C드라이버의 Temp 폴더에 Test.txt라는 파일이 있다는 가정하에 코드를 작성하였다.

해당 경로에 텍스트 파일을 추가하던가, 자신의 텍스트 파일 경로로 바꿔 코드를 실행하면 된다.

 

 

폴더 정보 얻기

using System;
using System.IO;

class DirectoryAndDirectoryInfo
{
    static void Main()
    {
        string dir = "C:\\";

        //[1] Directory 클래스
        if (Directory.Exists(dir))
        {
            Console.WriteLine("[1] C 드라이브의 모든 폴더 목록을 출력");
            foreach (string folder in Directory.GetDirectories(dir))
            {
                Console.WriteLine($"{folder}");
            }
        }

        //[2] DirectoryInfo 클래스
        DirectoryInfo di = new DirectoryInfo(dir + "Temp\\");
        if (di.Exists)
        {
            Console.WriteLine("[2] C 드라이브의 Temp 폴더의 모든 파일 목록 출력");
            foreach (var file in di.GetFiles())
            {
                Console.WriteLine($"{file}");
            }
        }
    }
}

Directory 또는 DirectoryInfo 클래스의 GetDerectories() 메서드는 전체 디렉터리 리스트를 보여주고,

GetFiles() 메서드는 전체 파일 리스트를 보여준다.

 

 

텍스트 데이터를 컬렉션 데이터로 가져오기

C드라이브 Temp 폴더에 Src.txt 파일이 있고, 그 파일의 내용이 다음과 같다고 가정한 후 코드를 작성해보자.

홍길동,112,2019-09-01,1234
백두산,114,2020-10-02,2345
한라산,119,2021-11-03,3456

C:\Temp\Src.txt 파일의 내용

 

using System;
using System.Collections.Generic;

namespace DotNet
{
    public class Record
    {
        public string Name { get; set; }
        public string PhoneNumber { get; set; }
        public DateTime BirthDate { get; set; }
        public string AuthCode { get; set; }
    }

    class TextToCollection
    {
        static void Main()
        {
            //[1] 텍스트 파일 읽기
            string[] lines =
                System.IO.File.ReadAllLines(
                    @"C:\Temp\src.txt", System.Text.Encoding.Default);
            foreach (var line in lines)
            {
                Console.WriteLine(line);
            }

            //[2] 문자열 배열의 정보를 컬렉션 형태의 개체에 담기
            List<Record> records = new List<Record>();
            foreach (var line in lines)
            {
                string[] splitData = line.Split(',');
                records.Add(
                    new Record
                    {
                        Name = splitData[0],
                        PhoneNumber = splitData[1],
                        BirthDate = Convert.ToDateTime(splitData[2]),
                        AuthCode = splitData[3]
                    });
            }

            //[3] 한개 데이터만 출력해보기 
            Console.WriteLine(records[0]?.Name ?? "데이터가 없습니다.");
        }
    }
}

구분자로 콤마를 사용하는 텍스트 파일의 데이터를 읽어 List<T> 형태의 C# 컬렉션으로 변환한다.

[1]에서 파일 내용을 ReadAllLines() 메서드로 한 줄씩 읽어 lines 리스트에 담은 후 [2]에서 한 줄을 콤마(,)를 구분자로

끊어 splitData 리스트에 담아 List<Record> 형태에 저장한다. 

 

 

 

 

 

 

<Reference>

 

반응형
Comments