프로그래밍을 하다 보면, 이진 파일을 읽거나 써야할 때가 생깁니다.
이럴 때 System.IO 네임스페이스에 있는 스트림 클래스를 사용하면 아주 쉽게 해결이 가능합니다.
System.IO 네임스페이스에 있는 클래스 중 Writer 으로 끝나는 것들은 모두 쓰기를 지원하는 스트림입니다.
예외적으로, BufferedStream 이나 MemoryStream의 경우엔 스트림에 쓴 값을 배열로 바꾸고 쓰기 가능한 스트림에
배열을 복사함으로써 쓰기가 가능하게 됩니다.
일단.. 이 글에서는 FileStream 만을 다루려고 합니다.
FileStream 을 사용하는 것은 매우 간단합니다.
System.IO 네임스페이스를 임포트 한다음, FileStream 클래스에 대한 개체 생성. 그리고 쓰기 작업
이게 끝입니다. 어때요? 참 쉽죠??
FileStream 클래스에 대한 개체는 어떻게 생성하느냐?
FileStream fs = new FileStream(@"C:\testfile.bin", FileMode.Create);
Byte[] asciiBytes = System.Text.Encoding.ASCII.GetBytes("Hello world!");
Byte[] uniBytes = System.Text.Encoding.Unicode.GetBytes("안녕 세상!");
그럼 한번 실전으로 가보죠.
예제에 사용된 코드입니다.
using System;
using System.IO;
using System.Text;
namespace BinaryWriting {
class Program {
public static void Main(string[] args) {
Console.WriteLine("파일이 저장될 위치를 입력하세요:");
String path = Console.ReadLine();
try {
FileStream fs = new FileStream(path, FileMode.Create);
// 단일 바이트 쓰기
fs.WriteByte(0x01);
fs.WriteByte(0x23);
fs.WriteByte(0x45);
fs.WriteByte(0x67);
fs.WriteByte(0x89);
fs.WriteByte(0xAB);
fs.WriteByte(0xCD);
fs.WriteByte(0xEF);
Byte[] asciiByte = Encoding.ASCII.GetBytes("ASCII string to byte!");
Byte[] uniByte = Encoding.Unicode.GetBytes("유니코드 문자열을 바이트로 변환!");
// ASCII 바이트 쓰기
fs.Write(asciiByte, 0, asciiByte.Length);
// 줄바꿈 (\r\n)
fs.WriteByte(13);
fs.WriteByte(10);
// UNICODE 바이트 쓰기
fs.Write(uniByte, 0, uniByte.Length);
// 위치를 처음으로!
fs.Position = 0;
// 단일 바이트를 총 8회 읽습니다.
for ( Int32 i = 0; i < 8; i++ ) {
Byte readSingleByte = (Byte) fs.ReadByte();
Console.WriteLine("읽은 바이트 (0x{0:X4}): {1:X2}", fs.Position, readSingleByte);
}
Byte[] dummyAsciiByte = new Byte[asciiByte.Length];
Byte[] dummyUniByte = new Byte[uniByte.Length];
// 쓴 ASCII 바이트를 읽고 출력해보자!
fs.Read(dummyAsciiByte, 0, dummyAsciiByte.Length);
Console.WriteLine("읽은 ASCII 바이트: {0}", Encoding.ASCII.GetString(dummyAsciiByte));
// 줄바꿈 문자(\r\n)는 건너뛴다.
fs.ReadByte();
fs.ReadByte();
// 쓴 UNICODE 바이트를 읽고 출력해보자!
fs.Read(dummyUniByte, 0, dummyUniByte.Length);
Console.WriteLine("읽은 UNICODE 바이트: {0}", Encoding.Unicode.GetString(dummyUniByte));
// 작업이 끝났으니 파일을 저장하고 닫는다!
fs.Close();
} catch (Exception ex) {
Console.WriteLine("작업 도중 예외가 발생했습니다!\n예외 메세지: {0}", ex.Message);
}
Console.WriteLine("아무 키나 누르면 종료합니다!");
Console.ReadKey(true);
}
}
}
그리고! 예제의 실행 결과는 이렇습니다.
c:\testfile.bin 파일의 내용은 어떨까요?
각각 메모장에서 연 것과 16진수로 본 파일의 내용은 이렇습니다.
메모장 내용:
줄바꿈이 된 것을 확인하실 수 있습니다.
16진수 내용:
사진을 보시면 아시겠지만, 0x0 ~0x7 부분은 단일 바이트를 01, 23, 45, 67, 89, AB, CD, EF 를 8개 썼는데
정말로 8바이트가 정확하게 들어가 있는것을 알 수 있습니다.
ASCII 문자열의 경우 그대로 들어가 있는 것을 확인할 수 있고, UNICODE 문자열의 경우 깨져서 나오네요.
하지만! 저건 바이트대로 쓴 것이기 때문에 2바이트 문자는 깨질 수 밖에 없지요.
그래서 Encoding 클래스를 이용하여 바이트를 문자로 변환하면! 깔끔한 한국어가 나오게 되는 거랍니다.
그리고 예제에 사용된 소스 코드입니다.
추가로, 궁금한 점이 있다면 댓글 남겨놔주시기 바랍니다~!
'.NET > C#' 카테고리의 다른 글
현재 호출되고 있는 메서드의 정보를 구하는 방법 (0) | 2014.10.19 |
---|---|
private, public, protected 그리고 internal?? 접근 한정자에 대해 알아보자. (3) | 2014.10.13 |
C#을 이용한 파일 다운로더 만들기! (5) | 2014.10.09 |
C#을 이용하여 간단한 1:1 비동기 채팅 프로그램을 만들어보자 - 클라이언트편 (26) | 2014.10.03 |
C#을 이용하여 간단한 1:1 비동기 채팅 프로그램을 만들어보자 - 서버편 (21) | 2014.09.25 |