728x90

데이터를 읽고 쓰기 위해 C# 에서는 stream(스트림) 객체를 사용한다.

닷넷의 스트림 관련 클래스들은 System.IO 네임스페이스에 정의되어 있다.


HDD(하드디스크), SSD 에 있는 파일을 읽고 쓰는데 사용되는 기본 클래스는 FileStream 이다.


var fs = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);

- srcFile : 파일의 경로 + 파일명

- FileMode : https://msdn.microsoft.com/ko-kr/library/system.io.filemode%28v=vs.110%29.aspx

- FileAccess : https://msdn.microsoft.com/ko-kr/library/4z36sx0f%28v=vs.110%29.aspx

- FileShare : https://msdn.microsoft.com/ko-kr/library/system.io.fileshare%28v=vs.110%29.aspx


byte[] buffer = new byte[4]; // 스트림으로부터 읽은 데이터를 저장할 크기가 4인 바이트 배열 버퍼
var fs = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);
fs.Read(buffer, 0, 4);
fs.Close();


byte[] buffer;
using (var fs = File.Open(srcFile, FileMode.Open))
{
    buffer = new byte[fs.Length];
    fs.Read(buffer, 0, (int)fs.Length);   
}


buffersize : 스트림을 입출력 효율 향상을 위해 버퍼를 사용한다.

HDD 에서 블럭 단위로 몽땅 읽어와 버퍼에 쌓아두고 다음에 읽을 때는 버퍼에서 읽어 입출력 속도가 향상된다.


FileStream 은 입출력 대상이 byte 배열로 고정되어 있어 실제 사용하기에는 불편하다.

응용 프로그램은 문자열, 실수, 정수와 같은 고수준 타입을 다루는 경우가 더 많다.

텍스트파일은 아주 단순한 구조로 되어 있지만 인코딩 방식에 따라 ANSI, UTF8, Unicode, UTF7 등 여러가지 포멧이 있다. 파일을 읽어올 때 인코딩 방식을 잘못 읽어오면 파일이 깨질 수 있다.

닷넷은 입출력 과정에서 자동으로 문자열 변환을 수행하는 StreamReader, StreamWriter 클래스를 제공한다.

using 문은 자동으로 해당 코드를 수행한 후 스트림의 Dispose() 메소드를 호출한다. using 문을 사용하면 스트림이 닫히지 않는 상태에서 해당 파일을 사용하려고 할 때 발생하는 버그를 걱정하지 않아도 된다.


//인코딩
C# 에서의 자료형을 갖는 데이터 -> 스트림(byte[])
EUC-KR(ANSI, MS949)
  - 영어(숫자,특수) 1칸
  - 한글 2칸
UTF-8(C#의 기본 인코딩 방식)
  - 영어(숫자,특수) 1칸
  - 한글 3칸
UTF-16
  - 영어(숫자,특수) 2칸
  - 한글 2칸


using (StreamReader sr = new StreamReader(fileName, System.Text.Encoding.UTF8))
{
    readText = sr.ReadToEnd();
    sr.Dispose();
}


HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
resResult = readerPost.ReadToEnd();

readerPost.Close();

string txt = string.Empty;
while ((txt = result.ReadLine()) != null)  // 한줄씩 읽어서 구분자로 나눠서 배열로 담아서 처리
{
    //1. 파싱
    string[] item = txt.Split(';');
    //2. Member 배열 객체 생성, m 은 참조변수
    Member m = new Member(item[0], item[1], item[2], item[3]);
    //3. Member 배열(ArrayList) 삽입
    list.Add(m);
} //while
result.Close();


using(Stream stream = File.Create(fileName))
{
    using (var textExport = new StreamWriter(stream, Encoding.UTF8))
    {
        foreach (ListViewItem row in LV.Items)
        {
            textExport.WriteLine(row.SubItems[0].Text);
            textExport.WriteLine(row.SubItems[1].Text);
            textExport.Write(Environment.NewLine);
        }

        textExport.Flush(); // flush from the buffers
        textExport.Close();
    }
}


여러 객체에 대해서는 여러개의 using 문을 사용하면 된다.

위의 코드에 using 을 두번 사용하고 중괄호{} 두번 사용했는데 첫번째 것은 중괄호를 생략해도 된다.

using(Stream stream = File.Create(fileName))
using (var textExport = new StreamWriter(stream, Encoding.UTF8))
{
    foreach (ListViewItem row in LV.Items)
    {
        textExport.WriteLine(row.SubItems[0].Text);
        textExport.WriteLine(row.SubItems[1].Text);
        textExport.Write(Environment.NewLine);
    }

    textExport.Flush(); // flush from the buffers
    textExport.Close();
}

클래스나 구조체같은 복잡한 이진 데이터를 저장할 때는 BinaryReader, BinaryWriter 클래스를 사용한다.

아직 이걸로 작성해본 것이 없어서 다음에 작성하게 되면 자료를 추가 보완할 예정


MemoryStream 참조하면 도움되는 사이트 http://net-informations.com/q/faq/memory.html


728x90

'C# > 문법 및 기능' 카테고리의 다른 글

C# Directory (폴더) 생성 및 삭제  (0) 2016.01.16
C# 시간 메소드  (0) 2016.01.15
C# int.TryParse  (0) 2015.12.25
C# 오버라이딩(Overriding) 개념 이해  (1) 2015.12.21
C# 메소드 오버로딩 개념잡기  (0) 2015.12.21
블로그 이미지

Link2Me

,