안녕하세요. 언제나휴일입니다.
이전 게시글에서 FileStream 개체를 이용한 파일 입출력을 다뤘습니다.
이번에는 BinaryWriter와 BinaryReader를 이용한 파일 입출력 실습을 해 볼게요.
1. 시나리오
실습할 시나리오는 이전 게시글과 같습니다.
프로그램 시작할 때 파일에 있는 내용을 로딩하여 ListView에 보여줍니다.
사용자가 회원 정보를 입력하여 추가 버튼을 누르면 ListView에 추가합니다.
프로그램 종료할 때 ListView에 회원 정보를 파일에 기록합니다.
2. 이전 게시글과 같은 부분
컨트롤 배치 및 이벤트 핸들러 등록하는 부분까지 똑같습니다.
파일 이름을 상수로 선언한 부분도 같습니다.
1 |
const string fname = "data"; |
Form1.cs에서 btn_add의 Click 이벤트 핸들러는 같습니다.
1 2 3 4 5 6 7 8 9 10 |
private void btn_add_Click(object sender, EventArgs e) { string id = tbox_id.Text; string name = tbox_name.Text; int age = tbar_age.Value; AddMember(id, name, age); tbox_id.Text = tbox_name.Text = ""; tbar_age.Value = 0; lb_age.Text = "0"; } |
물론 but_add의 Click 이벤트 핸드러에서 호출하는 AddMember 메서드도 같습니다.
1 2 3 4 5 6 |
private void AddMember(string id, string name, int age) { string[] sitems = new string[] { id, name, age.ToString() }; ListViewItem lvi = new ListViewItem(sitems); lv_member.Items.Add(lvi); } |
Form1.cs에서 tb_age의 Scroll 이벤트 핸들러도 같습니다.
1 2 3 4 |
private void tbar_age_Scroll(object sender, EventArgs e) { lb_age.Text = tbar_age.Value.ToString(); } |
3. 파일 입출력 구현
FileStream 개체의 Write 메서드와 Read 메서드를 사용할 때는 byte[]에 있는 내용을 기록하거나 읽어왔습니다.
BinaryWriter 개체와 BinaryReader 개체를 이용하면 byte[]로 변환하지 않고 기록하거나 읽어올 수 있습니다. BinaryWriter와 BinaryReader 개체 내부에서 이러한 작업을 대신 수행해 준다고 볼 수 있습니다.
3.1 Form1의 FormClosed 이벤트 핸들러 구현
파일을 생성하는 것은 같습니다.
대신 FileStream 개체에 출력을 해 주는 BinaryWriter 개체를 생성합니다.
모든 입출력 작업을 마치면 닫아주겠죠.
1 2 3 4 5 |
FileStream fs = File.Create(fname); BinaryWriter bw = new BinaryWriter(fs); ...입출력 작업... bw.Close(); fs.Close(); |
lv_member에 있는 모든 회원 정보를 얻어오는 부분도 같습니다.
1 2 3 4 5 6 7 |
foreach(ListViewItem lvi in lv_member.Items) { string id = lvi.SubItems[0].Text; string name = lvi.SubItems[1].Text; int age = int.Parse(lvi.SubItems[2].Text); ...출력... } |
BinaryWriter 개체를 기록할 때는 Write 메서드를 호출하는 것으로 끝납니다.
문자열도 Write 메서드를 호출하면 내부에서 알아서 필요한 작업을 수행해 줍니다.
1 2 3 |
bw.Write(id); bw.Write(name); bw.Write(age); |
다음은 Form1의 FormClosed 이벤트 핸들러 코드 내용입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private void Form1_FormClosed(object sender, FormClosedEventArgs e) { FileStream fs = File.Create(fname); BinaryWriter bw = new BinaryWriter(fs); foreach(ListViewItem lvi in lv_member.Items) { string id = lvi.SubItems[0].Text; string name = lvi.SubItems[1].Text; int age = int.Parse(lvi.SubItems[2].Text); bw.Write(id); bw.Write(name); bw.Write(age); } bw.Close(); fs.Close(); } |
3.2 Form1의 Load 이벤트 핸들러
파일이 존재하는지 확인하여 없다면 메서드를 끝냅니다.
1 2 3 4 |
if (File.Exists(fname) == false) { return; } |
파일을 읽기 모드로 연 후에 BinaryReader 개체를 생성합니다.
이제 FileStream 개체의 내용을 읽어올 때 BinaryReader 개체를 사용할 수 있습니다.
모든 입출력 작업을 마치면 닫아주세요.
1 2 3 4 5 |
FileStream fs = File.OpenRead(fname); BinaryReader br = new BinaryReader(fs); ...입출력 작업... br.Close(); fs.Close(); |
파일의 작업 위치(Postion)이 파일 길이(Length)보다 작으면 아직 읽어올 내용이 남아 있는 것이므로 반복합니다.
1 2 3 4 |
while(fs.Position< fs.Length) { ...읽어와서 처리... } |
회원 정보를 기록한 순서대로 읽어와서 추가합니다.
1 2 3 4 |
string id = br.ReadString(); string name = br.ReadString(); int age = br.ReadInt32(); AddMember(id, name, age); |
다음은 Form1의 Load 이벤트 핸들러입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private void Form1_Load(object sender, EventArgs e) { if (File.Exists(fname) == false) { return; } FileStream fs = File.OpenRead(fname); BinaryReader br = new BinaryReader(fs); while(fs.Position< fs.Length) { string id = br.ReadString(); string name = br.ReadString(); int age = br.ReadInt32(); AddMember(id, name, age); } br.Close(); fs.Close(); } |
4. Form1.cs 코드 내용
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
using System; using System.IO; using System.Windows.Forms; namespace 브릿지 { public partial class Form1 : Form { const string fname = "data"; public Form1() { InitializeComponent(); } private void btn_add_Click(object sender, EventArgs e) { string id = tbox_id.Text; string name = tbox_name.Text; int age = tbar_age.Value; AddMember(id, name, age); tbox_id.Text = tbox_name.Text = ""; tbar_age.Value = 0; lb_age.Text = "0"; } private void AddMember(string id, string name, int age) { string[] sitems = new string[] { id, name, age.ToString() }; ListViewItem lvi = new ListViewItem(sitems); lv_member.Items.Add(lvi); } private void tbar_age_Scroll(object sender, EventArgs e) { lb_age.Text = tbar_age.Value.ToString(); } private void Form1_Load(object sender, EventArgs e) { if (File.Exists(fname) == false) { return; } FileStream fs = File.OpenRead(fname); BinaryReader br = new BinaryReader(fs); while(fs.Position< fs.Length) { string id = br.ReadString(); string name = br.ReadString(); int age = br.ReadInt32(); AddMember(id, name, age); } br.Close(); fs.Close(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { FileStream fs = File.Create(fname); BinaryWriter bw = new BinaryWriter(fs); foreach(ListViewItem lvi in lv_member.Items) { string id = lvi.SubItems[0].Text; string name = lvi.SubItems[1].Text; int age = int.Parse(lvi.SubItems[2].Text); bw.Write(id); bw.Write(name); bw.Write(age); } bw.Close(); fs.Close(); } } } |