2011년 6월 23일 목요일

자바의 입력과 출력(I/O Streams)


오늘은 자바의 기본적인 입출력 방법에 대해서 살펴보기로 하겠다. 강좌 초반에 맛배기로 자바의 입출력에 관해서 잠깐 공부한적이 있지만 보다 다양한 방법과 접근을 통해서 심층학습(?)을 해보고자 한다. 자바에서 파일 입출력 부분은 상당히 중요하다. 여러분이 어떤 프로그램을 만들던지간에 유저의 입력과 그와 관련해서 정보를 처리하고 출력하는 시스템은 아마 필수적으로 꼭 들어가는 부분 중 하나일텐데 이 부분에 대해서 자유자재로 대처하지 못한다면 프로그램 제작시 상당한 어려움에 처하는 일이 많을 것이다. 이번 강좌를 통해서 자바의 입출력에 관한한 가장 기본적인 스킬은 여러분이 쉽게 습득할수 있도록 필자가 최선을 다할 것이다. 여러분이 할일은 그저 본 강좌를 열심히 읽기만 하고 따라서 쳐보기만 하면 될것이다.^^


스트림(Stream)은 위의 그림에서 보다시피 데이터의 흐름을 거치는 과정이라 생각하면 된다. 데이터 타입은 우리가 오늘 배울 바이트나 캐릭터 같은 유용한 것들(?)이 스트림을 통해 입력 프로그램이나 아래 그림처럼 입력과 반대로 출력 프로그램도 스트림을 통해 한번에 하나씩 읽어들이면서 처리한다.


오늘은 파일 입출력 부분에서 가장 기초라 할수 있는 파일 카피에 대한 자바 소스를 만들어 보기로 하겠다. 일단 카피할 원본 파일이 있어야 할텐데 원본 파일명은 eminem.txt 라고 하고 안에다가 아래의 내용을 넣고 저장하기 바란다.ㅎㅎ

eminem.txt
====================
"Love The Way You Lie"

(feat. Rihanna)

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie

[Eminem]
I can't tell you what it really is
I can only tell you what it feels like
And right now it's a steel knife in my windpipe
I can't breathe but I still fight while I can fight
As long as the wrong feels right it's like I'm in flight
High off of love, drunk from my hate,
It's like I'm huffing paint and I love it the more I suffer, I suffocate
And right before I'm about to drown, she resuscitates me
She fucking hates me and I love it.
Wait! Where you going?
"I'm leaving you"
No you ain't. Come back we're running right back.
Here we go again
It's so insane cause when it's going good, it's going great
I'm Superman with the wind at his back, she's Lois Lane
But when it's bad it's awful, I feel so ashamed I snapped
Who's that dude? I don't even know his name
I laid hands on her, I'll never stoop so low again
I guess I don't know my own strength

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie

[Eminem]
You ever love somebody so much you can barely breathe
When you're with 'em
You meet and neither one of you even know what hit 'em
Got that warm fuzzy feeling
Yeah, them chills you used to get 'em
Now you're getting fucking sick of looking at 'em
You swore you'd never hit 'em; never do nothing to hurt 'em
Now you're in each other's face spewing venom in your words when you spit them
You push, pull each other's hair, scratch, claw, hit 'em
Throw 'em down, pin 'em
So lost in the moments when you're in them
It's the rage that took over it controls you both
So they say you're best to go your separate ways
Guess if they don't know you 'cause today that was yesterday
Yesterday is over, it's a different day
Sound like broken records playing over but you promised her
Next time you show restraint
You don't get another chance
Life is no Nintendo game
But you lied again
Now you get to watch her leave out the window
Guess that's why they call it window pane

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie

[Eminem]
Now I know we said things, did things that we didn't mean
And we fall back into the same patterns, same routine
But your temper's just as bad as mine is
You're the same as me
But when it comes to love you're just as blinded
Baby, please come back
It wasn't you, baby it was me
Maybe our relationship isn't as crazy as it seems
Maybe that's what happens when a tornado meets a volcano
All I know is I love you too much to walk away though
Come inside, pick up your bags off the sidewalk
Don't you hear sincerity in my voice when I talk
I told you this is my fault
Look me in the eyeball
Next time I'm pissed, I'll aim my fist at the drywall
Next time. There won't be no next time
I apologize even though I know its lies
I'm tired of the games I just want her back
I know I'm a liar
If she ever tries to fucking leave again
Im'a tie her to the bed and set this house on fire
I'm just gonna

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie
====================

명곡(?)이라서 그런지 생각보다 가사가 조금 길다.^^ 여러분이 오늘 배울 자바소스(Test66.java) 파일과 같은 폴더에 위의 eminem.txt 파일을 넣고 실행하면 정상적으로 작동될 것이다. 그럼 예제를 보면서 차근차근 프로그램에 대해서 풀어가겠다.


프로그램이 아주 명확하므로 주석을 달진 않았지만 이해를 돕기 위해 간략하게 설명해 보겠다. 우리의 미션(?)은 eminem.txt 파일안의 내용을 lovethewayyoulie.txt 라는 파일에다가 그대로 카피하는게 주임무이다. 아는 사람은 알겠지만 에미넘(Eminem)의 Love the way you lie 라는 노래 가사를 카피하는 자바 소스다. 에미넘이란 이 친구(?)를 모르는 이들은 이번 기회에 꼭 한번 들어보기 바란다.ㅎㅎ

오늘 쓰일 자바의 파일 입출력을 담당하는 스트림은 FileInputStream과 FileOutputStream이므로 이를 이용하기 위해 import 하였다. 그리고 이에 대한 예외처리를 하기위해 IOException을 또한 불러들였다. 메인메소드를 보면 파일인풋스트림의 인자로 input을 파일아웃풋스트림의 인자로 output을 쓰고 소스를 읽어들이는 파일을 eminem.txt에서 읽도록 FileInputStream을 이용해 객체생성을 한후 input으로 건네주었고 마찬가지로 출력하는 파일로는lovethewayyoulie.txt로 만들라고 FileOutputStream을 통해 객체생성을 하고 output으로 넘겨주었다. 출력파일(lovethewayyoulie.txt)이 없을 경우 자동으로 생성되며 있을 경우 다시 덮어씌워버리니 출력 부분은 신경쓰지 않아도 된다.

int a; 라는 명령문이 나오는데 이게 뭔지 의아해할지도 모르겠다. while문을 보면 a가 input.read( )라는 구문을 받고 있는데 FileInputStream의 read( ) 메소드의 리턴값이 int 이므로 이렇게 받는다. 쉽게 설명하자면 바이트로 즉 컴퓨터에서는 그냥 정수로 문자들을 읽어내는데 각 글자마다 고유의 숫자가 있다. 이를 읽고 파일의 내용이 다 끝났으면 -1 이라는 정수값을 리턴하므로 while 구문이 파일 내용이 끝날때까지 읽게 만들려고 조건식이 위와같이 되는 것이다. 그리고 읽은 값을 output 즉 우리가 지정한 출력파일에다가 한번에 하나씩 카피하게 된다.


글자마다 갖고 있는 고유의 값이 뭐지? 라고 궁금해하는 이들은 아래의 표를 보기 바란다. 우리가 일반적으로 쓰는 알파벳이나 그밖의 기호들은 각기 고유한 숫자 체계를 가지고 있는데 우리가 사용하는 컴퓨터는 바로 이를 기호화하여 처리하므로 문자들을 읽을수 있는 것이다.


위에서 보는 이런 문자 체계를 우리는 아스키 코드(ASCII code)라고 부른다. 아마 컴퓨터를 사용하면서 아니면 키보드를 두드리면서 한번쯤은 들어봤음직한 용어일 것이다. 이런 표를 보면 그냥 외워야되는 것인줄 알고 무작정 암기하는데 제발 그러지말고 그냥 복사해서 필요할때마다 옆에두고 쓰자. 강이의 자바강좌 회원들은 보다 현명(?)하게 이런 상황들을 넘기기 바란다.ㅎㅎ

마지막에 있는 finally 구문은 예외가 생기던 안생기던 항상 처리되는데 try 예외구문을 받는 명령으로 파일을 오픈하고 썼으면 만일에 있을지 모르는 오작동(?)을 방지하기 위해 파일을 닫아주라는 명령이다. 예외구문에 대해서 기억이 잘 안나는 이들은 예전 강좌를 뒤적거려서 보고오기 바란다. 위의 예제를 실행하면 아래와 같은 결과를 얻게 될것이다.

34
76
111
118
101
32
84
104
101
32
..
...

왜 이렇게 되는지는 필자가 족보(?)인 아스키 코드를 여러분에게 주었으니 eminem.txt안의 파일내용과 대조해보면서 왜 이런 숫자들이 찍히는지 연구해보기 바란다. 여러분이 공부하기 쉽도록 출력스트림에서 바이트를 문자로 전환하기 전에 화면에 바이트로된 숫자를 출력하라고 만들어 놓은 것이다. 그리고 예제를 실행했으면 lovethewayyoulie.txt라는 파일이 같은 폴더안에 생성되었을 것인데 잘 카피되었는지 확인해보면서 공부하기 바란다.

java.io 패키지에서 우리가 방금 이용한 FileInputStream 대신에 FileReader를 FileOutputStream 대신에 FileWriter를 쓰고 똑같은 방법으로 위와같은 결과를 도출해낼수 있다. 다른말로 하면 FileReader는 FileInputStream을 FileWriter는 FileOutputStream을 상속받기 때문에 그러하다.

느꼈을지 모르겠지만 위의 프로그램은 뭔가 아쉬운 점이 많다. 한글자 한글자씩 읽어서 옮기는데 이건 너무 답답하지 않은가? 그래서 문장을 한줄씩 읽는 방식이 보편적으로 쓰인다. 이미 예전에 필자가 선보인 방식(?)이니 특별한 설명은 따로 하지 않겠다.ㅎㅎ 그래도 궁금해하는 이들을 위해 예제를 아래와 같이 올리니 뚫어지게 보면서 공부하기 바란다.^^


실행하고 보면 알겠지만 출력결과에서 보듯이 readLine( ) 메소드를 통해 문장을 한줄씩 읽어들이면서 명령을 처리한다. BufferedReader와 PrintWriter 클래스로 이와같이 부드러운 처리가 가능해진다. 차근차근 예제를 공부하면서 오늘 배운건 꼭 여러분의 것으로 만들기 바란다.^^

댓글 6개:

  1. 최고의 자바강의!

    답글삭제
  2. 최고라는 표현밖에는..

    답글삭제
  3. 자바소스(Test66.java) 파일과 같은 폴더에 위의 eminem.txt 를 넣으라고 하셨는데 해보니까 에러가 나요(no such directory)
    봤더니 그 상위폴더 bin폴더와 src가 있는곳에 eminem.txt을 넣으니 정상 작동 하던데 제 PC가 이상한건가요

    답글삭제
  4. 자바 배우고 있는 학생인데요 잘 배워갑니다!

    답글삭제
  5. ΗOW-TO: Ϻаkе a geeκу UЅB
    fаn

    Feеl free to surf to my site philadelphia truck accident lawyer
    My website ... philadelphia personal injury lawyer

    답글삭제
  6. Awesome blog! Do you have any tips for aspiring writers?
    I'm planning to start my own site soon but I'm a little lost
    on everything. Would you advise starting with a
    free platform like Wordpress or go for a paid option?
    There are so many options out there that I'm completely confused .. Any tips? Bless you!

    My web site - http://hand795bags.cagorabiz.com

    답글삭제