* Stream
// stream은 데이터가 움직이는 통로이다.
// 파일에 접근하려면 스트림을 사용한다.
// 이 스트림이 흐르는 방식은 순차접근과 임의접근이 있다.
Stream st1 = new FileStream("a.txt", FileMode.Create); // 파일 생성
// st1.Close(); // 파일 잡고 있는거 해제
st1 = new FileStream("a.txt", FileMode.Open); // 파일 열기
st1 = new FileStream("a.txt", FileMode.OpenOrCreate); // 파일 없음 생성 있음 열기
st1 = new FileStream("a.txt", FileMode.Truncate); // 비우고 열기
st1 = new FileStream("a.txt", FileMode.Append); // 덧붙이기로 열기
// file fileinfo와 비슷함.
// 스트림과 위에 네임스페이스들과 다른 점은.. 스트림은 바이트 배열로 저장해야만 한다.
// 스트림의 write와 read 함수가 바이트 배열만 받게 되어있음.
long abc = 123456;
Stream st = new FileStream("b.txt", FileMode.Create); // 파일 생성
byte[] bt = BitConverter.GetBytes(abc); // 바이트 배열로 변환
foreach(byte bb in bt)
{
Console.Write(bb);
}
Console.WriteLine();
st.Write(bt, 0, bt.Length); // 보낼 바이트배열, 0은 시작 오프셋, 길이
st.Close(); // 스트림 종료
Stream st2 = new FileStream("b.txt", FileMode.Open);
byte[] bt2 = new byte[8];
int i = 0;
while(st2.Position < st2.Length) // position은 0 부터 증가함
{
bt2[i++] = (byte)st2.ReadByte(); // 바이트를 하나씩 읽어서 배열에 저장
}
long abc2 = BitConverter.ToInt64(bt2, 0); // 바이트배열의 형식 변환
Console.WriteLine(abc2);
st2.Close();
// 스트림.length = 스트림의 길이
// 스트림.position = 스트림의 포지션의 현재 위치를 나타내는 프로퍼티
// position을 통해 순서대로 접근하는 것이 순차접근임.
// 그냥 메모장 펼쳐보면 이상하게 보이고 바이너리 파일 뷰어로 열어야함
// 임의 접근은.. 스트림.writebyte(offset순서) 로 접근한다.
st.writebyte(0x01);
st.writebyte(0x03);
st.seek(3,seekorigin.current); // 0x03에서 3번째 떨어진 곳으로 이동 0x06으로 이동함.
// 바이트 배열로 바꾸고 형변환하면서까지 굳이 쓸 필요가 없어보인다.
* BinaryWriter, BinaryReader
BinaryWriter bw = new BinaryWriter(new FileStream("a.txt", FileMode.Create)); // 선언
bw.Write(100); // 쓰기
bw.Write("abc");
bw.Close();
BinaryReader br = new BinaryReader(new FileStream("a.txt", FileMode.Open)); // 선언
Console.WriteLine("{0}", br.ReadInt32()); // 읽기
Console.WriteLine("{0}", br.ReadString());
br.Close();
// BitConverter 이게 데이터를 바이트 단위로 나눠 저장하지 않고 offset 순서에 맞게 알아서 저장해줌
// 위에 같은 형식인데 간단해진 것이다.
* StreamWriter, StreamReader
// 스트림라이터나 바이러니라이터나 스트림이 메인이고 나머지는 도와주는 클래스들이다.
// 메모장에 바이너리 형식이 아니라 string을 그대로 뽑고 싶을 때 이걸 사용함.
StreamWriter sw = new StreamWriter(new FileStream("a.txt", FileMode.Create)); // 선언
sw.WriteLine(100); // 입력
sw.WriteLine("abc"); // 입력
sw.Close(); // 연결해제
StreamReader sr = new StreamReader(new FileStream("a.txt", FileMode.Open));
Console.WriteLine("File size : {0} bytes", sr.BaseStream.Length);
while (sr.EndOfStream == false)
{
Console.WriteLine(sr.ReadLine()); // 한 줄씩 출력
}
sr.Close();
* 직렬화
// 네임스페이스 system.runtime.serialization.formatters.binary
// 직렬화는 객체의 필드값들을 메모리나 저장장치에 저장 가능하게 만드는 것이다.
// 바이너리라이터나 스트림라이터는 클래스나 구조체 형식을 지원하지 않음
// 간단히 클래스에 이것저것 저장한 인스턴스를 통째로 메모장에 넣는 것이 직렬화다.
// 물론 컬렉션들도 직렬화 됨
[Serializable] // 애트리뷰트 선언하면 직렬화할 수 있는 형식으로 변환
class info // 뽑을 클래스
{
public string name;
public int age;
[NonSerialized] // 이 아래로는 직렬화 제외
public string address;
}
class Program
{
static void Main(string[] args)
{
Stream st = new FileStream("a.txt", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
info num1 = new info();
num1.name = "kim";
num1.age = 20;
num1.address = "OC";
bf.Serialize(st, num1); // 직렬화
st.Close();
Stream st2 = new FileStream("a.txt", FileMode.Open);
BinaryFormatter bf2 = new BinaryFormatter();
info num2;
num2 = (info)bf2.Deserialize(st2); // 역직렬화
Console.WriteLine(num2.name);
Console.WriteLine(num2.age);
Console.WriteLine(num2.address);
}
}