티스토리 뷰

LANGUAGE/C#

[C#] 파일 입출력

진심스테이크 2018. 6. 14. 17:11

 

파일 스트림 (File Stream)

1. 스트림 (stream) : 파일, 네트워크 등에서 데이터를 바이트 단위로 읽고 쓰는 클래스

- Stream class는 상위 기본 클래스

  -> 상속 클래스 : FileStream, MemoryStream, NetworkStream, SqlFileStream 등

- using System.IO 선언해서 사용

2. File Stream : 파일 입출력을 다루는 기본 클래스

- 상속 계층 구조

  System.Object

   + System.MarshlByRefObject

      + System.IO.Stream

         + System.IO.FileStream

- byte[ ] 배열로 데이터를 읽거나 저장

  -> 형변환이 요구됨

- 파일 정보 설정에 사용

- 기본 형태

 public FileStream ( string path, FileMode mode, FileAccess access)

- FileMode 열거형

  -> Append, Create, CreateNew

  -> Open, OpenOrCreate, Truncate

- FileAccess 열거형 

  -> Read, ReadWrite, Write

- StreamWriter / StreamReader + BinaryWrite / BinaryReader와 사용

 

StreamWriter

- 역할 : 파일 쓰기

- 상속 계층 구조

  Sytem.Object

  + System.MarshalByRefObject

     + System.IO.TextWriter

        + System.IO.StreamWriter

- public class StreamWriter : TextWriter

- 객체 생성과 해제

- using 문 : Close( )를 자동으로 해줌\

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            //방법1
            int value = 12;
            float value2 = 3.14f;
            string str1 = "Hello World!";
            FileStream fs = new FileStream("test.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            sw.Write(value);
            sw.Write(value2);
            sw.Write(str1);
            sw.Close();

            //방법2
            using (StreamWriter sww = new StreamWriter(new FileStream("text.txt", FileMode.Create)))
            {
                sww.WriteLine(value);
                sww.WriteLine(value2);
                sww.WriteLine(str1);
            }
        }
    }
}
 

StreamReader

- 역할 : 파일 읽기

- 상속 계층 구조

  System.Object

  + System.MarshalByRefObject

     + System.IO.TextReader

        + System.IO.StreamReader

- public class StreamReader : TextReader

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            FileStream fs = new FileStream("text.txt", FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);
            int value = int.Parse(sr.ReadLine()); //타입 변환
            float value2 = float.Parse(sr.ReadLine()); // 타입 변환
            string str1 = sr.ReadLine();
            sr.Close();
            Console.WriteLine("{0} {1} {2}", value, value2, str1);
        }
    }
}
namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            //읽기 전용
            StreamReader sr = new StreamReader("text.txt");
            int value = int.Parse(sr.ReadLine()); //타입 변환
            float value2 = float.Parse(sr.ReadLine()); // 타입 변환
            string str1 = sr.ReadLine();
            Console.WriteLine("{0} {1} {2}", value, value2, str1);
        }
    }
}

 

 

BinartWriter / BinaryReader

- Write( )

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            using (BinaryWriter bw = new BinaryWriter(new FileStream("test.dat", FileMode.Create)))
            {
                bw.Write(12);
                bw.Write(3.14f);
                bw.Write("Hello World!");
            }
        }
    }
}

 

- BinaryReader를 이용한 파일 읽기

  -> BinaryReader(Stream)

  -> BinaryReader(Stream, Encoding)

  -> BinaryReader(Stream, Encoding, Boolean)

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            int var1;
            float var2;
            string str1;

            using (BinaryReader br = new BinaryReader(File.Open("test.dat", FileMode.Open)))
            {
                var1 = br.ReadInt32();
                var2 = br.ReadSingle();
                str1 = br.ReadString();
            }
            Console.WriteLine("{0} {1} {2}", var1, var2, str1);
        }
    }
}

 

- 구조체를 이진파일로 저장하고 읽기

namespace _0614
{
    struct Data
    {
        public int var1;
        public float var2;
    }
    class Program
    {
        static void Main(string[] args)
        {
            Data[] array = new Data[2];
            array[0].var1 = 7;
            array[0].var2 = 3.14f;

            array[1].var1 = 12;
            array[1].var2 = 0.5f;

            BinaryWriter bw = new BinaryWriter(File.Open("test.txt", FileMode.Create));
            for(int i = 0; i < array.Length; i++)
            {
                bw.Write(array[i].var1);
                bw.Write(array[i].var2);
            }
            bw.Close();

            int var1;
            float var2;

            BinaryReader br = new BinaryReader(File.Open("test.txt", FileMode.Open));
            while (true)
            {
                try
                {
                    var1 = br.ReadInt32();
                    var2 = br.ReadSingle();
                    Console.WriteLine("{0} {1}", var1, var2);
                }
                catch(EndOfStreamException e) //파일 끝에 도달한 예외처리
                {
                    br.Close();
                    break;
                }
            }
        }
    }
}
 

텍스트 파일 처리

- StreamWriter, StreamReader

- 특징

1. 기본 단위 : 1 byte

2. 아스키코드 기반

   -> 아스키코드를 유니코드로 인코딩

 

 


 

 

예시

- string 데이터 분리

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "국어: 90 영어: 100 수학: 70";
            string[] str_Element = str.Split(new char[] { ' ' }); //공백 기준으로 자름
            //문자열 형으로 반환
            //배열로 return

            int kor = int.Parse(str_Element[1]);
            int eng = int.Parse(str_Element[3]);
            int math = int.Parse(str_Element[5]);
            int total = kor + eng + math;
            float avg = total / 3.0f;
            Console.WriteLine("{0} {1} {2} {3} {4}", kor, eng, math, total, Math.Round(avg));
        }
    }
}

 

 

- ReadLine( ) 활용

  -> 쓰기

namespace _0614
{
    struct GRADE
    {
        public int kor, eng, math, total;
        public float avg;
    }
    class Program
    {
        static void Main(string[] args)
        {
            string str;
            Console.Write("성적 처리를 위한 학생 수 입력 : ");
            int count = int.Parse(Console.ReadLine());
            Console.WriteLine("국어, 영어, 수학 순서로 입력");
            GRADE[] grade = new GRADE[count];
            StreamWriter sw = new StreamWriter("text.txt");
            sw.WriteLine("학생수 : {0}", count);

            for (int i = 0; i < count; i++)
            {
                str = Console.ReadLine();
                string[] data = str.Split(new char[] { ' ' });
                grade[i].kor = int.Parse(data[0]);
                grade[i].eng = int.Parse(data[1]);
                grade[i].math = int.Parse(data[2]);
                grade[i].total = grade[i].kor + grade[i].eng + grade[i].math;
                grade[i].avg = grade[i].total / 3.0f;
                grade[i].avg = (float)Math.Round(grade[i].avg);
            }

            for(int i = 0; i<count; i++)
            {
                sw.WriteLine("{0}, {1}, {2}, {3}, {4}", grade[i].kor, grade[i].eng, grade[i].math, grade[i].total, grade[i].avg);
                sw.Close();
            }
        }
    }
}

 

  -> 읽어오기

namespace _0614
{
    class Program
    {
        static void Main(string[] args)
        {
            string str;
            Console.Write("파일명 입력");
            string filename = Console.ReadLine();
            StringReader sr = new StringReader(filename);
            str = sr.ReadLine();
            string[] data = str.Split(new char[] { ':' });
            int count = int.Parse(data[1]);
            Console.WriteLine("---------------------------");

            for (int i = 0; i <count; i++)
            {
                str = sr.ReadLine();
                string[] data2 = str.Split(new char[] { ':' });
                Console.WriteLine("{0} {1} {2} {3} {4}", data2[0], data2[1], data2[2], data2[3], data2[4]);
            }
            Console.WriteLine("---------------------");
            sr.Close();
        }
    }
}

 


 

직렬화 (serialize)

- StreamWriter / StreamReader와 BinaryWriter / BinaryReader -> 기본 데이터형만 저장 및 읽기 가능

- 구조체, 클래스 저장 및 읽기 -> FileStream, BinaryFormatter

- BinaryFormatter 네임스페이스 -> using System.Runtime.Serialization.Formatters.Binary;

- 대상 설정

  [Serializable]

  struct / class A

  { 

  

  }

 

BinaryFormatter

1. serialize (직렬화)

- public void Serialize (Stream serializationStream, object graph)

namespace _0614
{
    [Serializable] //꼭 명시!
    struct DATA
    {
        public int var1;
        public float var2;
        public string str1;
    }

    class Program
    {
        static void Main(string[] args)
        {
            DATA[] data = new DATA[2];
            data[0].var1 = 1;
            data[0].var2 = 0.5f;
            data[0].str1 = "Test1";
            data[1].var1 = 2;
            data[1].var2 = 1.5f;
            data[1].str1 = "Test2";

            using (FileStream fs1 = new FileStream("test.dat", FileMode.Create))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs1, data);
            }

            DATA[] result;
            using (FileStream fs2 = new FileStream("test.dat", FileMode.Create))
            {
                BinaryFormatter bf2 = new BinaryFormatter();
                result = (DATA[])bf2.Deserialize(fs2);
            }

            for (int i = 0; i < 2; i++)
                Console.WriteLine("{0} {1} {2}", result[i].var1, result[i].var2, result[i].str1);
        }
    }
}

 

2. deserialize (역직렬화)

- public object Deserialize (Stream serializationStream)

namespace _0614
{
    [Serializable] //꼭 명시!
    struct DATA
    {
        public int var1;
        public float var2;

        [NonSerialized] //저장하고 싶지 않음!
        public string str1;
    }

    class Program
    {
        static void Main(string[] args)
        {
            DATA[] data = new DATA[2];
            data[0].var1 = 1;
            data[0].var2 = 0.5f;
            data[0].str1 = "Test1";
            data[1].var1 = 2;
            data[1].var2 = 1.5f;
            data[1].str1 = "Test2";

            using (FileStream fs1 = new FileStream("test.dat", FileMode.Create))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs1, data);
            }

            DATA[] result;
            using (FileStream fs2 = new FileStream("test.dat", FileMode.Create))
            {
                BinaryFormatter bf2 = new BinaryFormatter();
                result = (DATA[])bf2.Deserialize(fs2);
            }

            for (int i = 0; i < 2; i++)
                Console.WriteLine("{0} {1} {2}", result[i].var1, result[i].var2, result[i].str1);
            //str1은 빈공간으로 출력
        }
    }
}

 


 

컬렉션의 직렬화

- 컬렉션과 제네릭 : 같은 데이터형의 임의의 메모리 또는 연속적인 메모리를 다룰 수 있도록 하는 클래스

- ArrayList, List<T>

namespace _0614
{
    [Serializable] //꼭 명시!
    struct Data
    {
        public int data;
        public string str;
        public Data(int data1, string str1)
        {
            data = data1;
            str = str1;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Data> result;
            List<Data> datalist = new List<Data>();
            datalist.Add(new Data(7, "test1"));
            datalist.Add(new Data(12, "test2"));
            datalist.Add(new Data(12, "test2"));
            datalist.Add(new Data(12, "test2"));
            datalist.Add(new Data(12, "test12"));

            using (FileStream fs1 = new FileStream("test.dat", FileMode.Create))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs1, datalist);
            }

            using (FileStream fs2 = new FileStream("test.dat", FileMode.Open))
            {
                BinaryFormatter bf2 = new BinaryFormatter();
                result = (List<Data>)bf2.Deserialize(fs2);
            }

            for (int i = 0; i < 5; i++)
                Console.WriteLine("{0} {1}", result[i].data, result[i].str);
        }
    }
}

 

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

[C#] 배열  (0) 2018.06.14
[C#] 기본 문법  (0) 2018.06.13
[C#] 값 형식 / 참조 형식  (0) 2018.06.12
[C#] 사용자 지정형  (0) 2018.06.12
[C#] 표준 입력  (0) 2018.06.12
댓글