본문 바로가기
Programming/C#

C# 16 : File(파일)

by 공부합시다홍아 2020. 6. 17.

파일 다루기

파일 정보와 디렉토리 정보 다루기

파일(File)은 컴퓨터 저장 매체에 기록되는 데이터의 묶음이다. 

디렉토리(Diretory)는 파일이 위치하는 주소로, 파일(서류)을 담는다는 의미에서 폴더(Folder)라고 부르기도 한다.

.NET 프레임워크에서는 파일과 디렉토리 정보를 손쉽게 다룰 수 있도록 System.IO 네임스페이스 아래에 다음과 같은 클래스들을 제공한다.

  • File : 파일의 생성, 복사, 삭제, 이동, 조회를 처리하는 정적메소드를 제공

  • FileInfo : File 클래스와 하는 일은 동일하지만 정적 메소드 대신 인스턴스 메소드를 제공

  • Directory : 디렉토리의 생성, 삭제, 이동, 조회를 처리하는 정적 메소드를 제공 / static 메소드 -> 일반 함수에 가까움 

  • DirectoryInfo : Directroy 클래스와 하는 일은 동일하지만 정적 메소드 대신 인스턴스 메소드를 제공

 

File 클래스와  FileInfo 클래스는 거의 같은 기능을 제공합니다. 차이라면 File 클래스는 같은 기능을 정적 메소드를 통해 제공하고 FileInfo 클래스는 인스턴스 메소드를 통해 제공한다는 점뿐입니다. 어떤 경우에 File클래스와 FileInfo 클래스 중 어느 것을 사용해야 한다는 규칙같은 것은 없지만, 한의 파일에 대해 한두 가지 정도의 작업을 할 때는 File클래스의 정적메소드를 이용하고, 하나의 파일에 여러 작업을 수행할 때에는 FileInfo클래스의 인스턴스 메소드를 이용하는 편입니다. 

Directory 클래스와 DirectroyInfo클래스에 대해서도 마찬가지이다. 디렉토리에 대해 한 두가지 작업을 해야할 때는 Directroy 클래스를, 여러 작업을 할 때는 DirectoryInfo 클래스를 이용한다.

 

                               생성            복사            삭제         이동          존재여부확인    속성조회

File                           Create()       Copy()          Delete()                    Exists()            GetAttributes() 

FileInfo                      Create()       CopyTo()      Delete()                      Exists             Attributes()   

Directory                   CreateDiretory()               Delete()     Move()        Exists()             GetAttributes()

DirectroyInfo               Create()                         Delete()    MoveTo()      Exists                Attributes()

 

                              하위디렉토리조회        하위파일조회

File    

FileInfo

Directory                  GetDiretories()            GetFiles()

DirectroyInfo              GetDiretories()            GetFiles()

 

파일 생성 및 읽기

파일 설명

파일 조회

 

파일을 읽고 쓰기 위해 알아야 할 것들 

파일의 내용을 읽고 쓰는 방법, 즉 파일의 입력과 출력에 대한 것이다. 

스트림 ( Stream )

스트림은 영어로 시내, 강 또는 도로의 차선을 뜻하는 단어로 파일을 다룰 때 말하는 스트림은 "데이터가 흐르는 통로"를 뜻합니다. 

메모리에서 하드딧크로 데이터를 옮길 때에는 먼저 이 스트림을 만들어 둘 사이를 연결한 뒤에 메모리에 있는 데이터를 바이트 단위로 하드디스크로 옮겨 넣습니다. 하드디스크에서 메모리로 데이터를 옮길 때 (즉 파일을 읽을 때)도 마찬가지 이다. 하드 디스크와 메모리 사이에 스트림을 놓은 후 파일에 담겨 있는 데이터를 바이트 단위로 메모리로 차례차례 옮겨 옵니다. 

스트림은 "데이터 흐림"이기 때문에 스트림을 이용하여 파일을 다룰 때는 처음부터 끝까지 순서대로 읽고 쓰는 것이 보통입니다, ( 이것을 순차 접근 방식 이라 함) 이러한 스트림의 구조는 네트워크나 데이터 백업 장치의 데이터 입/출력 구조와도 통하기 때문에 스트림을 이용하면 파일이 아닌 네트워크를 향해서 데이터를 흘려 보낼 수 있고 테이프 백업 장치를 통해 데이터를 기록하거나 읽을 수 있습니다. 

하지만 하드디스크는 데이터의 흐름이 단방향성을 가지는 네트워크나 자기 테이프 장치와는 달리 암과 헤드를 움직여 디스크의 어떤 위치에 긹된 데이터에라도 즉시 찾아갈 수 있습니다. 가량 1MB크기의 파일에서 768byte번째 위치한 데이터를 읽고 싶을 때, 하드 디스크는 앞에 있는 767byte를 읽지 않아도 곧장 원하는 위치로 이동할 수 있습니다. 이렇게 임의의 주소에 있는 데이터에 접근하는 것을 가리켜 "임의 접근(Random Access)방식이라고 합니다. 

Stream 클래스는 그 자체로 입력 스티림, 출력 스트림의 역할을 모두 할 수 있으며 파일을 읽고 쓰는 방식 역시 순차 접근 방식과 임의 접근 방식 모두를 지원합니다. 단 Stream클래스는 추상 클래스이기 떄문에 이 클래스의 인스턴스를 직접 만들어 사용할 수는 없고 이 클래스로 부터 파생된 클래스를 이용해야합니다. Stream클래스가 이렇게 만들어진 이유는 스트림이 다루는 다양한 매체나 장치들에 대한 파일 입출력을 스트림 모델 하나로 다룰 수 있도록 하기 위해서 이다.

파생클래스

  • FileStream : 디스크 파일에 데이터를 기록

  • NetworkStream : 네트워크 피어에 데이터를 전송

  • GZipStream : 데이터를 GZip 형식으로 압축

  • BufferedStream : 데이터를 파일이나 네트워크에 즉시 기록하는 대신 메모리 버퍼에 담아 두었다 일정량이 쌓일 때마다 기록

Stream stream1 = new FileStream("a.dat", FileMode.Create)   : 새 파일 생성

Stream stream1 = new FileStream("a.dat", FileMode.Open)     : 파일 열기

Stream stream1 = new FileStream("a.dat", FileMode.OpenCreate)   : 파일 존재시 오픈, 존재하지 않을 시 생성

Stream stream1 = new FileStream("a.dat", FileMode.Truncate)    : 파일을 비워서 열기

Stream stream1 = new FileStream("a.dat", FileMode.Append)     : 덧붙이기 모드로 열기 

 

Stream 클래스에는 Position이라는 프로퍼티가 존재, Stream 클래스를 상속하는 FileStream클래스도 이 프로퍼티를 보유하고 있다. 

Position 프로퍼티는 현재 스트림의 읽는 위치 또는 쓰는 위치를 나타냅니다. 가령 Position이 3이라면 파일의 3번 째 바이트에서 쓰거나 읽을 준비가 되어 있는 상태입니다. 

 

이진 데이터 처리를 위한 BinaryWriter / BinaryReader

BinaryWriter는 스티림에 이진 데이터를 기록하기 위한 목적입니다.

BinaryReader 클래스는 스트림으로부터 이진 데이터를 읽어들이기 위한 목적으로 만들어진 클래스입니다. 

이 두 클래스는 어디까지나 파일처리의 도우미 역할을 할 뿐이기 때문에 이들 클래스들을 이용하려면 Stream으로부터 파생딘 클래스의 인스턴스가 있어야합니다. 

 

텍스트 파일 처리를 위한 StreamWriter/StreamReader 

텍스트 파일은 구조는 간단하지만 활용도가 높은 파일 형식입니다. ASCII 인코딩에서는 각 바이트가 문자 하나를 나타내기 때문에 바이트 오더의 문제에서도 벗어날 수 있고, 이로 인해 플랫폼에 관계없이 생성하고 읽을 수 있습니다. 뿐만 아니라 프로그램이 생성한 파일의 내용을 편집기로 열면 사람이 바로 읽을 수도 있습니다.

.NET 프레임워크가 이렇게 활용도가 높은 파일 형식에 대한 지원을 하지 않을 리가 없습니다. 바이너리 파일 쓰기/읽기를 위해 BinaryWriter/BinaryReader를 제공했던 것처럼 .NET프레임워크는 텍스트 파일을 쓰고 읽을 수 있도록 StreamWriter/StreamReader를 제공합니다.

 

객체 직렬화하기 

BinaryWriter/Reader와 StreamWriter/Reader는 기본 데이터 형식을 스트림에 쓰고 읽을 수 있도록 메소드들을 제공하지만, 프로그래머가 직접 정의한 클래스나 구조체 같은 복합 데이터 형식은 지원하지 않습니다. BinaryWriter/Reader와 StreamWriter/Reader로 복합 데이터 형식을 기록하고 읽으려면 그 형식이 갖고 있는 필드의 값을 저장할 순서를 정한 후, 이 순서대로 저장하고 읽는 코드를 작성해야 합니다. 

이 문제를 위해 C#은 복합 데이터 형식을 쉽게 스트림에 쓰기/읽기를 할 수 있게 하는 직렬화[Serialization]라는 메커니즘을 제공한다. 

직렬화란, 객체의 상태(객체의 필드에 저장된 값)를 메모리나 영구 저장 장치에 저장이 가능한 0과1의 순서로 바꾸는 것을 의미합니다. 

 

728x90

'Programming > C#' 카테고리의 다른 글

C# 18 : 네트워크 프로그래밍1  (2) 2020.06.17
c# 17 : Thread(스레드)  (0) 2020.06.17
c# 15 : 리플랙션  (0) 2020.06.15
C# 14 : 람다식  (0) 2020.06.15
C#_13 : WinForm으로 만드는 사용자 인터페이스1  (0) 2020.06.12