메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

닷넷 스트림(.NET Stream)

한빛미디어

|

2003-08-25

|

by HANBIT

15,350

저자: 워이밍 리(Wei-Meng Lee), 역 한동훈

처음 닷넷을 접하는 개발자들의 공통된 문제는 닷넷 클래스 라이브러리의 수가 너무 많다는 것이다. 근래에 필자는 파일 액세스와 관련된 프로젝트를 진행하게 되면서 파일 처리에 대한 올바른 클래스를 찾아보았다. 파일 관련 클래스의 대부분은 System.IO 네임 스페이스에 있으며, 각각의 클래스들은 서로 비슷한 점이 많으므로 일반적인 파일 처리를 수행하는데 사용하는 클래스들을 정리해 보기로 마음먹었다. 본 기사에서 소개할 예제가 좀 어렵게 느껴질 수도 있겠지만 여러분이 적절한 클래스를 선택하는데 도움이 될 것은 확실하다.

Stream 클래스

스트림은 바이트 순서를 추상화한 것이다. 파일, TCP/IP 소켓, 메모리로부터 오는 것들은 모두 바이트 순서라 할 수 있다. 닷넷에서는 이러한 스트림을 Stream 클래스로 표현한다. Stream 클래스는 바이트 순서의 일반적인 뷰를 제공한다. 또한 Stream 클래스는 다른 모든 스트림의 추상 클래스이므로 Stream 클래스의 인스턴스를 직접 생성할 수 없다. 대신에 Stream 클래스는 다음과 같은 클래스로 구현된다.
  1. BufferedStream: 성능 향상을 위해 다른 스트림에 대한 버퍼링 레이어를 제공한다
  2. FileStream: 파일을 읽기/쓰기 기능을 제공한다
  3. MemoryStream: 보조 저장 수단으로서 메모리를 사용하는 스트림을 제공한다
  4. NetworkStream: 네트워크 데이터를 액세스할 수 있는 스트림을 제공한다
  5. CryptoStream: 데이터를 암호화 전송할 수 있는 스트림을 제공한다
스트림 클래스들은 기본적으로 다음과 같은 작업을 수행한다.
  1. 읽기(Reading)
  2. 쓰기(Writing)
  3. 찾기(Seeking)
본 기사에서는 파일 입출력에서 빈번하게 사용되는 클래스들을 예제를 통해 살펴볼 생각이다. 비주얼 스튜디오 닷넷과 함께 제공되는 MSDN에는 각 클래스에 대한 문서화가 잘 되어 있기 때문에 여기에서는 각 클래스를 일일이 설명하는 대신 FileStream과 MemoryStream에 대해서만 살펴보고 파일 생성, 읽기, 쓰기에는 File 클래스를 사용할 것이다. 소제목을 수행할 작업에 따라 나누고, 그에 대한 예제를 설명하였다.

여기에 등장한 모든 예제는 다음 상수와 변수들을 사용한다.
Dim fs, s1, s2 As FileStream
Dim sr As StreamReader
Dim sw As StreamWriter
Dim br As BinaryReader
Dim bw As BinaryWriter
Dim ms As MemoryStream

Const FILE_NAME = "c:\textFile.txt"
Const BAK_FILE_NAME = "c:\textFile_bak.txt"
Const FILE_NAME_IMAGE = "c:\iMac.jpg"
Const FILE_NAME_BIN = "c:\bin.jpg"
Dim bytes(10) As Byte
지금까지 언급한 클래스들은 모두 System.IO 네임 스페이스에 있으므로 이 네임 스페이스를 임포트한다.
Imports System.IO
FileStreamMemoryStream 외에 바이너리 데이터의 읽기/쓰기를 위해 BinaryReaderBinaryWriter 클래스를 사용하며, 텍스트 데이터의 읽기/쓰기에는 StreamReaderStreamWriter 클래스를 사용할 것이다.


VB.NET Core Classes in a Nutshell

참고 도서

VB.NET Core Classes in a Nutshell
Budi Kurniawan, Ted Neward




파일 관리

파일 생성, 삭제, 복사, 이름 변경, 지정된 파일이 있는지를 확인하기 위해 File 클래스를 사용한다. 다음 예제는 파일이 있는지 확인한 후, 파일을 복사하고 원본을 삭제한다.
"---Copy and Delete the file
If File.Exists(FILE_NAME) Then
	File.Copy(FILE_NAME, BAK_FILE_NAME, True)
	File.Delete(FILE_NAME)
End If
파일 생성

파일 읽기 외에 파일 생성에도 File 클래스를 사용한다. 다음 예제는 파일을 생성하고 FileStream 객체를 반환한다. 그 다음 코드는 새로운 텍스트 파일을 생성하고 StreamWriter 객체를 반환한다. 마지막으로 파일의 읽기/쓰기를 위해 File 클래스의 Open() 메소드를 사용한다.
fs = File.Create(FILE_NAME_BIN)
fs.Close()

sw = File.CreateText(FILE_NAME)
sw.Close()

fs = File.Open(FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.Read)
fs.Close()
FileStream 클래스를 사용하여 바이너리 데이터 쓰기

바이너리 데이터를 파일에 저장하기 위해 FileStream 클래스를 사용한다. 다음 예제는 FileStream 클래스를 사용하여 새로운 파일을 생성하고 데이터를 바이너리로 저장한다. 모두 11바이트를 파일에 저장한 후 파일을 닫는다.
"---create a file and write some bytes to it
fs = New FileStream(FILE_NAME, FileMode.CreateNew, FileAccess.Write)
bytes(0) = 72 "H"
bytes(1) = 101 "e"
bytes(2) = 108 "l"
bytes(3) = 108 "l"
bytes(4) = 111 "o"
bytes(5) = 13 "CR"
bytes(6) = 87 "W"
bytes(7) = 111 "o"
bytes(8) = 114 "r"
bytes(9) = 108 "l"
bytes(10) = 100 "d"

fs.Write(bytes, 0, bytes.Length)
fs.Close()
StreamWriter 클래스를 사용하여 텍스트 쓰기

텍스트를 파일에 저장할 때는 다른 클래스를 사용하는 것 보다 StreamWriter 클래스를 사용하는 것이 더 쉽다. 다음 예제는 파일에 텍스트 문자열을 저장하기 위해 StreamWriter 클래스를 사용한다.
"---Using a streamWriter to write to a file
sw = New StreamWriter(FILE_NAME, True, System.Text.Encoding.ASCII)
sw.WriteLine("Welcome to VB.NET")
sw.Close()
FileStream 클래스를 사용하여 바이너리 데이터 읽기

파일에서 바이너리 데이터를 읽어오려면 FileStream 클래스를 사용해야 한다. 다음 예제는 파일을 열고 바이너리 데이터를 읽어온다. 읽어온 바이트를 ASCII 문자로 변환한 다음에 화면에 출력한다.
"---open a file and read the byte(s) out
fs = New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read)
fs.Read(bytes, 0, bytes.Length)
Dim i As Short
For i = 0 To bytes.Length - 1
		Console.Write(Chr(bytes(i)))
Next
찾기(Seeking)

스트림 객체는 찾기를 지원한다. 다음 예제는 FilStream 객체를 사용하여 현재 위치에서 11번째 바이트로 이동한 후에 6 바이트를 읽어온다.
"---seeking
fs.Seek(11, SeekOrigin.Current)
fs.Read(bytes, 0, 6)
For i = 0 To 5
		Console.Write(Chr(bytes(i)))
Next
fs.Close()
※ 역자주: Read 함수들은 데이터를 읽어온 다음에 현재 위치를 다음 위치로 이동시키지만 Seek 함수들은 데이터를 읽어오기만 하며 위치를 이동시키지 않는다. 여기에 소개된 예제처럼 파일 내에서 위치를 이동하기 위해 Seek를 사용하기도 한다.

StreamReader 클래스를 사용하여 텍스트 읽기

텍스트 파일을 읽어오기 위해 StreamReader 클래스를 사용한다. 다음 예제는 StreamReader 객체를 사용하여 읽어올 파일을 연다. 파일을 줄 단위로 읽어온 다음에 각 줄을 화면에 출력한다.
"---open a file and read line by line using a streamreader
sr = New StreamReader(FILE_NAME)
Dim line As String = sr.ReadLine()

While Not line Is Nothing
	Console.Write(line)
	line = sr.ReadLine()
End While
sr.Close()
BinaryReaderBinaryWriter 클래스를 사용하여 바이너리 데이터 읽고 쓰기

바이너리 데이터의 읽기/쓰기에는 FileStream 클래스 뿐만 아니라 BinaryReaderBinaryWriter 클래스도 사용할 수 있다. 다음 예제는 하나의 파일을 읽어와서 다른 파일에 그 내용을 저장하는 것으로 결국에는 파일을 복사하는 것과 동일하다. 예제에서는 FileStream 클래스를 사용하여 두 개의 파일을 연다. 하나는 파일을 읽어오기 위한 것이며, 다른 하나는 파일을 저장하기 위한 것이다. FileStream에서 바이너리 데이터를 읽어오기 위해 BinaryReader 클래스를, 바이너리 데이터를 파일에 저장하기 위해 BinaryWriter 클래스를 사용한다.
"---read from and write to a binary file
s1 = New FileStream(FILE_NAME_IMAGE, FileMode.Open, FileAccess.Read)
s2 = New FileStream("c:\iMac_copy.jpg", FileMode.CreateNew, FileAccess.Write)

br = New BinaryReader(s1)
bw = New BinaryWriter(s2)

Dim byteRead As Byte
Dim j As Integer
For j = 0 To br.BaseStream.Length() - 1
	byteRead = br.ReadByte
	bw.Write(byteRead)
Next
br.Close()
bw.Close()
MemoryStream 클래스를 사용하여 바이너리 데이터 쓰기

특별한 용도를 위해 파일에서 읽어온 바이너리 데이터를 메모리에 저장하는 경우가 있다. 이러한 경우의 가장 좋은 예는 윈도우 폼에서 사용하는 PictureBox 컨트롤이다. 다음 예는 BinaryReader 클래스를 사용하여 파일을 바이너리 데이터로 읽어와서 MemoryStream 객체에 저장한다. 그 다음에 PictureBox 컨트롤은 MemoryStream에 비트맵 이미지로 저장된 데이터를 사용한다.
"--read from a binary stream and write into a memory stream
s1 = New FileStream(FILE_NAME_IMAGE, FileMode.Open, FileAccess.Read)
ms = New MemoryStream(s1.Length)
br = New BinaryReader(s1)
Dim bytesRead As Byte() = br.ReadBytes(s1.Length)
ms.Write(bytesRead, 0, s1.Length)
PictureBox1.Image = New Bitmap(ms)
나머지 유용한 함수들

암호화 API를 사용하는 경우와 같이 문자열을 바이트 배열로 변환하거나 그 반대로 변환할 필요가 있다. 이러한 변환을 쉽게 할 수 있는 세가지 함수를 살펴보자.
  1. stringcharToByteArray(): 문자열을 바이트 배열로 변환한다
  2. stringToByteArray(): 숫자로 구성된 문자열을 바이트 배열로 변환한다
  3. byteArrayToString(): 바이트 배열을 문자열로 변환한다
Public Function stringcharToByteArray(ByVal str As String) As Byte()
	"e.g. "abcdefg" to {a,b,c,d,e,f,g}
	Dim s As Char()
	s = str.ToCharArray
	Dim b(s.Length - 1) As Byte
	Dim i As Integer
	For i = 0 To s.Length - 1
		b(i) = Convert.ToByte(s(i))
	Next
	Return b
End Function

Public Function stringToByteArray(ByVal str As String) As Byte()
	" e.g. "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16" to 
	"{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
	Dim s As String()
	s = str.Split(" ")
	Dim b(s.Length - 1) As Byte
	Dim i As Integer
	For i = 0 To s.Length - 1
		b(i) = Convert.ToByte(s(i))
	Next
	Return b
End Function

Public Function byteArrayToString(ByVal b() As Byte) As String
	Dim i As Integer
	Dim s As New System.Text.StringBuilder()
	For i = 0 To b.Length - 1
		Console.WriteLine(b(i))
		If i <> b.Length - 1 Then
			s.Append(b(i) & " ")
		Else
			s.Append(b(i))
		End If
	Next
	Return s.ToString
End Function
※ 역자주: 위에 소개한 유틸리티 함수들은 닷넷 프레임워크의 System.Text 네임스페이스의 Encoding.GetBytes()와 Encoding.GetString()으로 이미 구현되어 있다.
TAG :
댓글 입력
자료실

최근 본 상품0