본문 바로가기

웹_프론트_백엔드/JAVA프레임윅기반_풀스택

2020.03.30

1. Thread
 : 실제 프로그램이 수행되는 작업의 최소 단위
   (하나의 프로세스는 하나 이상의 Thread를 가지게 됨)

 


2. Process 
 : 실행중인 프로그램

   (OS로부터 메모리를 할당 받음)

 


3. Context Switching
 : 두 개의 쓰레드가 한 개의 쓰레드보다 느릴 수도 있다.
   왜? 작업전환(Context Switching)이 발생하기 때문이다.

 


4. Dead Lock(교착상태)
 : 한정된 자원을 여러 곳에서 사용하려고 할 때 발생할 수 있다.
   대기 상태로 들어간 프로세스들이 실행상태로 변경 될 수 없을때 이러한 상황을 교착상태라고 함

 


5. 엔디언(Endianness)

 : 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며,

   바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.

 

 

6. 엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과

   작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있으며,

   두 경우에 속하지 않거나 둘을 모두 지원하는 것을 미들 엔디언(Middle-endian)이라 부르기도 한다.

 

[실습코드]

 

1. [과제] 문서(문자열) 안의 단어의 빈도수를 계수해서 출력하기

package practice.wordcount;
/* 1] 문서(문자열) 안의 단어의 빈도수를 계수해서 출력하기
 * 	- 대소문자 구분하지 않기 :   The 와 the 는 같은 단어
 *  - 2글자 이상만 계수하기
 *  - 구두점/기호 ",.\"\'`!?;:-()" 잘라내기
 *  - 공백 짤라내기
 * ex)
 * 	an : 234
 * 	the : 314
 * ...
 * 
 * hint]
 * 	split("\\s+")  --> String[]   
 * 	--> StringTokenizer  (혹은 정규표현식)
 *  	  --> HashMap<String, Integer>   <단어, 빈도수>  사용
 * ───────────────────────────────────────────────────────   
 * 2] 빈도수 내림차순으로 정렬하여 출력하기
 * 	ex)
 *	1 the:113개
 *	2 she:95개
 *	3 to:85개
 *	...   
 *
 * hint]
 *  토큰나이저 사용해서 잘라내기
 */

// TODO : 필요한 객체들 작성
// hint> 빈도수 담을 객체, Comparator<> ..

// Ctrl + H : Search 창 뜨고 File Search 탭에서 
//            Containing text에 검색어 기입 > Search 클릭 
public class AliceInWonderland {
	
	public static void main(String[] args) {		
		
		AlicelnWonderlandField AlicelnWonder = new AlicelnWonderlandField();
		AlicelnWonder.view();
		
		System.out.println("\n프로그램 종료");
	} // end main()

} // end class

 

package practice.wordcount;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AlicelnWonderlandField {
	
	// method name : textLengthJudge
	// return : boolean
	// arguments : String words
	// 기능 : 두 글자 이상인지 검사하기
	// 전달받은 글자가 두 개 이상이면 참, 두개 미만이면  거짓리턴
	public boolean textLengthJudge(String words) {
		boolean check = false;
		String regex = "^[a-zA-Z]{2,}$";
		
		// Pattern 클래스의 pattern의 객체 생성
		// Regex(조건)을 coupon(입력 받은 문장)에서 컴파일(찾아서)하여 Pattern 객체로 생성
		Matcher matcher = Pattern.compile(regex).matcher(words);

		// find() : 패턴이 일치하면 true를 반환
		// matches() : 패턴이 전체 문자열과 일치할 경우 true 반환
		if (matcher.matches()) {
			check = true;
		} else {
			check = false;
		}

		// 2글자 이상인지 확인, 판정한 결과를 메인에 넘겨줘야 함
		return check;
	} // end textLengthJudge()
	
	
	// method name : wordFrequent
	// return : void
	// 기능 : 단어별 발생 빈도를 계산하여 
	//       hmap에 값을 넣는다
	public void wordFrequent(HashMap<String, Integer> hmap, String[] words) {
		for (int i = 0; i < words.length; i++) {
			int count = 0;
			for (int j = 0; j < words.length; j++) {
				if(words[i].equals(words[j])){
					count++;
				}
			}
			hmap.put(words[i], count);
		}
	} // end wordFrequent()
	
	
	// method name : twoOverCount
	// return : int count
	// arguments : String[] words
	// 기능 : 두 글자 이상의 단어가 몇개인지 파악한다
	//       파악하는 이유는 그 만큼의 배열 방을 만들기 위해서..!!
	public int twoOverCount(String[] words) {
		int count = 0;
		for (int i = 0; i < words.length; i++) {
			if(textLengthJudge(words[i])) {
				count++;
			}
		}
		return count;
	} // end twoOverCount()
	
	
	// method name : twoWordInput
	// return : void
	// 기능 : 2개 이상 단어들만 모아서 넣기..!!
	public void twoWordInput(String[] words, String[] words2) {
		int j = 0;
		for (int i = 0; i < words.length; i++) {
			if(textLengthJudge(words[i])) {
				words2[j] = words[i];
				j++;
			}
		}
	} // end twoWordInput()
	
	
	// method name : descSortPrint 
	// return : void
	// arguments : HashMap<String, Integer> hmap
	// 기능: 내림차순 정렬한 뒤 최종 결과 값을 출력한다.
	public void descSortPrint(HashMap<String, Integer> hmap) {
		System.out.println("단어\t:\t빈도수");
		System.out.println("--------------------------");
		TreeMap<String, Integer> treeMapReverse = new TreeMap<String, Integer>(Collections.reverseOrder());
		treeMapReverse.putAll(hmap);
 
		Iterator<String> treeMapReverseIter = treeMapReverse.keySet().iterator();
 
		while(treeMapReverseIter.hasNext()) {
			String key = treeMapReverseIter.next();
			int value = treeMapReverse.get(key);
 
			System.out.println(key + " 단어 : " + value + "번");
		}
	} // end descSort()
	
	
	// method name : view
	// return : void
	// arguments : 없음
	// 기능 : 화면 출력한다.
	public void view() {
		System.out.println("실습\t:\t단어 발생 빈도");
		HashMap<String, Integer> hmap = new HashMap<String, Integer>();
		
		// 공백 제거, 대소문자 구분하지 않기
		String [] words = C.ALICE30.trim().toLowerCase().split("\\s+");
		
		// 구두점/기호 ",.\"\'`!?;:-()" 잘라내기
		for (int i = 0; i < words.length; i++) {
			StringTokenizer tokenizer = new StringTokenizer(words[i], ",.\\\"\\'`!?;:-()");
			words[i] = tokenizer.nextToken();
		}
		
		// 2글자 이상만 계수하기
		int count = twoOverCount(words);

		// 2개 이상의 단어를 넣기 위한 배열 선언
		String[] words2 = new String[count];
		
		// 2개 이상의 단어를 words2에 넣는다..!!
		twoWordInput(words, words2);
		
		// 발생빈도 계산하여 hmap로 단어별 발생빈도 값 넣기
		// 이때 단어는 key값, 발생빈도는 value값
		wordFrequent(hmap, words2);
		
		// 내림차순 정렬, 결과 출력
		descSortPrint(hmap);
	} // end view()
	
} // end class

 

package practice.wordcount;

public class C {
	public static final String ALICE30 = "                ALICE'S ADVENTURES IN WONDERLAND\r\n" + 
			"\r\n" + 
			"                          Lewis Carroll\r\n" + 
			"\r\n" + 
			"               THE MILLENNIUM FULCRUM EDITION 3.0\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"                            CHAPTER I\r\n" + 
			"\r\n" + 
			"                      Down the Rabbit-Hole\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"  Alice was beginning to get very tired of sitting by her sister\r\n" + 
			"on the bank, and of having nothing to do:  once or twice she had\r\n" + 
			"peeped into the book her sister was reading, but it had no\r\n" + 
			"pictures or conversations in it, `and what is the use of a book,'\r\n" + 
			"thought Alice `without pictures or conversation?'\r\n" + 
			"\r\n" + 
			"  So she was considering in her own mind (as well as she could,\r\n" + 
			"for the hot day made her feel very sleepy and stupid), whether\r\n" + 
			"the pleasure of making a daisy-chain would be worth the trouble\r\n" + 
			"of getting up and picking the daisies, when suddenly a White\r\n" + 
			"Rabbit with pink eyes ran close by her.\r\n" + 
			"\r\n" + 
			"  There was nothing so VERY remarkable in that; nor did Alice\r\n" + 
			"think it so VERY much out of the way to hear the Rabbit say to\r\n" + 
			"itself, `Oh dear!  Oh dear!  I shall be late!'  (when she thought\r\n" + 
			"it over afterwards, it occurred to her that she ought to have\r\n" + 
			"wondered at this, but at the time it all seemed quite natural);\r\n" + 
			"but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-\r\n" + 
			"POCKET, and looked at it, and then hurried on, Alice started to\r\n" + 
			"her feet, for it flashed across her mind that she had never\r\n" + 
			"before seen a rabbit with either a waistcoat-pocket, or a watch to\r\n" + 
			"take out of it, and burning with curiosity, she ran across the\r\n" + 
			"field after it, and fortunately was just in time to see it pop\r\n" + 
			"down a large rabbit-hole under the hedge.\r\n" + 
			"\r\n" + 
			"  In another moment down went Alice after it, never once\r\n" + 
			"considering how in the world she was to get out again.\r\n" + 
			"\r\n" + 
			"  The rabbit-hole went straight on like a tunnel for some way,\r\n" + 
			"and then dipped suddenly down, so suddenly that Alice had not a\r\n" + 
			"moment to think about stopping herself before she found herself\r\n" + 
			"falling down a very deep well.\r\n" + 
			"\r\n" + 
			"  Either the well was very deep, or she fell very slowly, for she\r\n" + 
			"had plenty of time as she went down to look about her and to\r\n" + 
			"wonder what was going to happen next.  First, she tried to look\r\n" + 
			"down and make out what she was coming to, but it was too dark to\r\n" + 
			"see anything; then she looked at the sides of the well, and\r\n" + 
			"noticed that they were filled with cupboards and book-shelves;\r\n" + 
			"here and there she saw maps and pictures hung upon pegs.  She\r\n" + 
			"took down a jar from one of the shelves as she passed; it was\r\n" + 
			"labelled `ORANGE MARMALADE', but to her great disappointment it\r\n" + 
			"was empty:  she did not like to drop the jar for fear of killing\r\n" + 
			"somebody, so managed to put it into one of the cupboards as she\r\n" + 
			"fell past it.\r\n" + 
			"\r\n" + 
			"  `Well!' thought Alice to herself, `after such a fall as this, I\r\n" + 
			"shall think nothing of tumbling down stairs!  How brave they'll\r\n" + 
			"all think me at home!  Why, I wouldn't say anything about it,\r\n" + 
			"even if I fell off the top of the house!' (Which was very likely\r\n" + 
			"true.)\r\n" + 
			"\r\n" + 
			"  Down, down, down.  Would the fall NEVER come to an end!  `I\r\n" + 
			"wonder how many miles I've fallen by this time?' she said aloud.\r\n" + 
			"`I must be getting somewhere near the centre of the earth.  Let\r\n" + 
			"me see:  that would be four thousand miles down, I think--' (for,\r\n" + 
			"you see, Alice had learnt several things of this sort in her\r\n" + 
			"lessons in the schoolroom, and though this was not a VERY good\r\n" + 
			"opportunity for showing off her knowledge, as there was no one to\r\n" + 
			"listen to her, still it was good practice to say it over) `--yes,\r\n" + 
			"that's about the right distance--but then I wonder what Latitude\r\n" + 
			"or Longitude I've got to?'  (Alice had no idea what Latitude was,\r\n" + 
			"or Longitude either, but thought they were nice grand words to\r\n" + 
			"say.)\r\n" + 
			"\r\n" + 
			"  Presently she began again.  `I wonder if I shall fall right\r\n" + 
			"THROUGH the earth!  How funny it'll seem to come out among the\r\n" + 
			"people that walk with their heads downward!  The Antipathies, I\r\n" + 
			"think--' (she was rather glad there WAS no one listening, this\r\n" + 
			"time, as it didn't sound at all the right word) `--but I shall\r\n" + 
			"have to ask them what the name of the country is, you know.\r\n" + 
			"Please, Ma'am, is this New Zealand or Australia?' (and she tried\r\n" + 
			"to curtsey as she spoke--fancy CURTSEYING as you're falling\r\n" + 
			"through the air!  Do you think you could manage it?)  `And what\r\n" + 
			"an ignorant little girl she'll think me for asking!  No, it'll\r\n" + 
			"never do to ask:  perhaps I shall see it written up somewhere.'\r\n" + 
			"\r\n" + 
			"  Down, down, down.  There was nothing else to do, so Alice soon\r\n" + 
			"began talking again.  `Dinah'll miss me very much to-night, I\r\n" + 
			"should think!'  (Dinah was the cat.)  `I hope they'll remember\r\n" + 
			"her saucer of milk at tea-time.  Dinah my dear!  I wish you were\r\n" + 
			"down here with me!  There are no mice in the air, I'm afraid, but\r\n" + 
			"you might catch a bat, and that's very like a mouse, you know.\r\n" + 
			"But do cats eat bats, I wonder?'  And here Alice began to get\r\n" + 
			"rather sleepy, and went on saying to herself, in a dreamy sort of\r\n" + 
			"way, `Do cats eat bats?  Do cats eat bats?' and sometimes, `Do\r\n" + 
			"bats eat cats?' for, you see, as she couldn't answer either\r\n" + 
			"question, it didn't much matter which way she put it.  She felt\r\n" + 
			"that she was dozing off, and had just begun to dream that she\r\n" + 
			"was walking hand in hand with Dinah, and saying to her very\r\n" + 
			"earnestly, `Now, Dinah, tell me the truth:  did you ever eat a\r\n" + 
			"bat?' when suddenly, thump! thump! down she came upon a heap of\r\n" + 
			"sticks and dry leaves, and the fall was over.\r\n" + 
			"\r\n" + 
			"  Alice was not a bit hurt, and she jumped up on to her feet in a\r\n" + 
			"moment:  she looked up, but it was all dark overhead; before her\r\n" + 
			"was another long passage, and the White Rabbit was still in\r\n" + 
			"sight, hurrying down it.  There was not a moment to be lost:\r\n" + 
			"away went Alice like the wind, and was just in time to hear it\r\n" + 
			"say, as it turned a corner, `Oh my ears and whiskers, how late\r\n" + 
			"it's getting!'  She was close behind it when she turned the\r\n" + 
			"corner, but the Rabbit was no longer to be seen:  she found\r\n" + 
			"herself in a long, low hall, which was lit up by a row of lamps\r\n" + 
			"hanging from the roof.\r\n" + 
			"\r\n" + 
			"  There were doors all round the hall, but they were all locked;\r\n" + 
			"and when Alice had been all the way down one side and up the\r\n" + 
			"other, trying every door, she walked sadly down the middle,\r\n" + 
			"wondering how she was ever to get out again.\r\n" + 
			"\r\n" + 
			"  Suddenly she came upon a little three-legged table, all made of\r\n" + 
			"solid glass; there was nothing on it except a tiny golden key,\r\n" + 
			"and Alice's first thought was that it might belong to one of the\r\n" + 
			"doors of the hall; but, alas! either the locks were too large, or\r\n" + 
			"the key was too small, but at any rate it would not open any of\r\n" + 
			"them.  However, on the second time round, she came upon a low\r\n" + 
			"curtain she had not noticed before, and behind it was a little\r\n" + 
			"door about fifteen inches high:  she tried the little golden key\r\n" + 
			"in the lock, and to her great delight it fitted!\r\n" + 
			"\r\n" + 
			"  Alice opened the door and found that it led into a small\r\n" + 
			"passage, not much larger than a rat-hole:  she knelt down and\r\n" + 
			"looked along the passage into the loveliest garden you ever saw.\r\n" + 
			"How she longed to get out of that dark hall, and wander about\r\n" + 
			"among those beds of bright flowers and those cool fountains, but\r\n" + 
			"she could not even get her head though the doorway; `and even if\r\n" + 
			"my head would go through,' thought poor Alice, `it would be of\r\n" + 
			"very little use without my shoulders.  Oh, how I wish\r\n" + 
			"I could shut up like a telescope!  I think I could, if I only\r\n" + 
			"know how to begin.'  For, you see, so many out-of-the-way things\r\n" + 
			"had happened lately, that Alice had begun to think that very few\r\n" + 
			"things indeed were really impossible.\r\n" + 
			"\r\n" + 
			"  There seemed to be no use in waiting by the little door, so she\r\n" + 
			"went back to the table, half hoping she might find another key on\r\n" + 
			"it, or at any rate a book of rules for shutting people up like\r\n" + 
			"telescopes:  this time she found a little bottle on it, (`which\r\n" + 
			"certainly was not here before,' said Alice,) and round the neck\r\n" + 
			"of the bottle was a paper label, with the words `DRINK ME'\r\n" + 
			"beautifully printed on it in large letters.\r\n" + 
			"\r\n" + 
			"  It was all very well to say `Drink me,' but the wise little\r\n" + 
			"Alice was not going to do THAT in a hurry.  `No, I'll look\r\n" + 
			"first,' she said, `and see whether it's marked \"poison\" or not';\r\n" + 
			"for she had read several nice little histories about children who\r\n" + 
			"had got burnt, and eaten up by wild beasts and other unpleasant\r\n" + 
			"things, all because they WOULD not remember the simple rules\r\n" + 
			"their friends had taught them:  such as, that a red-hot poker\r\n" + 
			"will burn you if you hold it too long; and that if you cut your\r\n" + 
			"finger VERY deeply with a knife, it usually bleeds; and she had\r\n" + 
			"never forgotten that, if you drink much from a bottle marked\r\n" + 
			"`poison,' it is almost certain to disagree with you, sooner or\r\n" + 
			"later.\r\n" + 
			"\r\n" + 
			"  However, this bottle was NOT marked `poison,' so Alice ventured\r\n" + 
			"to taste it, and finding it very nice, (it had, in fact, a sort\r\n" + 
			"of mixed flavour of cherry-tart, custard, pine-apple, roast\r\n" + 
			"turkey, toffee, and hot buttered toast,) she very soon finished\r\n" + 
			"it off.\r\n" + 
			"\r\n" + 
			"     *       *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"         *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"     *       *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"  `What a curious feeling!' said Alice; `I must be shutting up\r\n" + 
			"like a telescope.'\r\n" + 
			"\r\n" + 
			"  And so it was indeed:  she was now only ten inches high, and\r\n" + 
			"her face brightened up at the thought that she was now the right\r\n" + 
			"size for going through the little door into that lovely garden.\r\n" + 
			"First, however, she waited for a few minutes to see if she was\r\n" + 
			"going to shrink any further:  she felt a little nervous about\r\n" + 
			"this; `for it might end, you know,' said Alice to herself, `in my\r\n" + 
			"going out altogether, like a candle.  I wonder what I should be\r\n" + 
			"like then?'  And she tried to fancy what the flame of a candle is\r\n" + 
			"like after the candle is blown out, for she could not remember\r\n" + 
			"ever having seen such a thing.\r\n" + 
			"\r\n" + 
			"  After a while, finding that nothing more happened, she decided\r\n" + 
			"on going into the garden at once; but, alas for poor Alice!\r\n" + 
			"when she got to the door, she found she had forgotten the\r\n" + 
			"little golden key, and when she went back to the table for it,\r\n" + 
			"she found she could not possibly reach it:  she could see it\r\n" + 
			"quite plainly through the glass, and she tried her best to climb\r\n" + 
			"up one of the legs of the table, but it was too slippery;\r\n" + 
			"and when she had tired herself out with trying,\r\n" + 
			"the poor little thing sat down and cried.\r\n" + 
			"\r\n" + 
			"  `Come, there's no use in crying like that!' said Alice to\r\n" + 
			"herself, rather sharply; `I advise you to leave off this minute!'\r\n" + 
			"She generally gave herself very good advice, (though she very\r\n" + 
			"seldom followed it), and sometimes she scolded herself so\r\n" + 
			"severely as to bring tears into her eyes; and once she remembered\r\n" + 
			"trying to box her own ears for having cheated herself in a game\r\n" + 
			"of croquet she was playing against herself, for this curious\r\n" + 
			"child was very fond of pretending to be two people.  `But it's no\r\n" + 
			"use now,' thought poor Alice, `to pretend to be two people!  Why,\r\n" + 
			"there's hardly enough of me left to make ONE respectable\r\n" + 
			"person!'\r\n" + 
			"\r\n" + 
			"  Soon her eye fell on a little glass box that was lying under\r\n" + 
			"the table:  she opened it, and found in it a very small cake, on\r\n" + 
			"which the words `EAT ME' were beautifully marked in currants.\r\n" + 
			"`Well, I'll eat it,' said Alice, `and if it makes me grow larger,\r\n" + 
			"I can reach the key; and if it makes me grow smaller, I can creep\r\n" + 
			"under the door; so either way I'll get into the garden, and I\r\n" + 
			"don't care which happens!'\r\n" + 
			"\r\n" + 
			"  She ate a little bit, and said anxiously to herself, `Which\r\n" + 
			"way?  Which way?', holding her hand on the top of her head to\r\n" + 
			"feel which way it was growing, and she was quite surprised to\r\n" + 
			"find that she remained the same size:  to be sure, this generally\r\n" + 
			"happens when one eats cake, but Alice had got so much into the\r\n" + 
			"way of expecting nothing but out-of-the-way things to happen,\r\n" + 
			"that it seemed quite dull and stupid for life to go on in the\r\n" + 
			"common way.\r\n" + 
			"\r\n" + 
			"  So she set to work, and very soon finished off the cake.\r\n" + 
			"\r\n" + 
			"     *       *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"         *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"     *       *       *       *       *       *       *\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"                           CHAPTER II\r\n" + 
			"\r\n" + 
			"                        The Pool of Tears\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"  `Curiouser and curiouser!' cried Alice (she was so much\r\n" + 
			"surprised, that for the moment she quite forgot how to speak good\r\n" + 
			"English); `now I'm opening out like the largest telescope that\r\n" + 
			"ever was!  Good-bye, feet!' (for when she looked down at her\r\n" + 
			"feet, they seemed to be almost out of sight, they were getting so\r\n" + 
			"far off).  `Oh, my poor little feet, I wonder who will put on\r\n" + 
			"your shoes and stockings for you now, dears?  I'm sure _I_ shan't\r\n" + 
			"be able!  I shall be a great deal too far off to trouble myself\r\n" + 
			"about you:  you must manage the best way you can; --but I must be\r\n" + 
			"kind to them,' thought Alice, `or perhaps they won't walk the\r\n" + 
			"way I want to go!  Let me see:  I'll give them a new pair of\r\n" + 
			"boots every Christmas.'\r\n" + 
			"\r\n" + 
			"  And she went on planning to herself how she would manage it.\r\n" + 
			"`They must go by the carrier,' she thought; `and how funny it'll\r\n" + 
			"seem, sending presents to one's own feet!  And how odd the\r\n" + 
			"directions will look!\r\n" + 
			"\r\n" + 
			"            ALICE'S RIGHT FOOT, ESQ.\r\n" + 
			"                HEARTHRUG,\r\n" + 
			"                    NEAR THE FENDER,\r\n" + 
			"                        (WITH ALICE'S LOVE).\r\n" + 
			"\r\n" + 
			"Oh dear, what nonsense I'm talking!'\r\n" + 
			"\r\n" + 
			"  Just then her head struck against the roof of the hall:  in\r\n" + 
			"fact she was now more than nine feet high, and she at once took\r\n" + 
			"up the little golden key and hurried off to the garden door.\r\n" + 
			"\r\n" + 
			"  `I suppose so,' said Alice.\r\n" + 
			"\r\n" + 
			"  `Well, then,' the Cat went on, `you see, a dog growls when it's\r\n" + 
			"angry, and wags its tail when it's pleased.  Now I growl when I'm\r\n" + 
			"pleased, and wag my tail when I'm angry.  Therefore I'm mad.'\r\n" + 
			"\r\n" + 
			"  `I call it purring, not growling,' said Alice.\r\n" + 
			"\r\n" + 
			"  `Call it what you like,' said the Cat.  `Do you play croquet\r\n" + 
			"with the Queen to-day?'\r\n" + 
			"\r\n" + 
			"  `I should like it very much,' said Alice, `but I haven't been\r\n" + 
			"invited yet.'\r\n" + 
			"\r\n" + 
			"  Lastly, she pictured to herself how this same little sister of\r\n" + 
			"hers would, in the after-time, be herself a grown woman; and how\r\n" + 
			"she would keep, through all her riper years, the simple and\r\n" + 
			"loving heart of her childhood:  and how she would gather about\r\n" + 
			"her other little children, and make THEIR eyes bright and eager\r\n" + 
			"with many a strange tale, perhaps even with the dream of\r\n" + 
			"Wonderland of long ago:  and how she would feel with all their\r\n" + 
			"simple sorrows, and find a pleasure in all their simple joys,\r\n" + 
			"remembering her own child-life, and the happy summer days.\r\n" + 
			"\r\n" + 
			"                             THE END\r\n" + 
			"\r\n" + 
			"";

}

 

[내 코드의 문제점] 빈도수로 내림차순 해야 하는데 단어별로 내림차순 함
                         the 113 she 92 나와야 하는데 이유를 알 수 없지만 the 111 she 92가 나옴

 

** 쌤이 선택한 학생의 코드..!!

package practice.wordcount;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/* 1] 문서(문자열) 안의 단어의 빈도수를 계수해서 출력하기
 * 	- 대소문자 구분하지 않기 :   The 와 the 는 같은 단어
 *  - 2글자 이상만 계수하기
 *  - 구두점/기호 ",.\"\'`!?;:-()" 잘라내기
 *  - 공백 짤라내기
 * ex)
 * 	an : 234
 * 	the : 314
 * ...
 * 
 * hint]
 * 	split("\\s+")  --> String[]   
 * 	--> StringTokenizer  (혹은 정규표현식)
 *  	  --> HashMap<String, Integer>   <단어, 빈도수>  사용
 * ─────────────────────────────────────────────────────────   
 * 2] 빈도수 내림차순으로 정렬하여 출력하기
 * 	ex)
 *	1 the:113개
 *	2 she:95개
 *	3 to:85개
 *	...   
 *
 * hint]
 * 	Comparable<> 이나 Comparator<> 적용
 */

public class AliceInWonderland {

	public static void main(String[] args) {
		System.out.println("실습: 단어 발생 빈도 (내림차순) ");
		String[] words = C.ALICE30.trim().toLowerCase().split("\\W+|\\_|\\t|\\n|\\d+|\\s+|\\r");

		HashMap<String, Integer> hmap = new HashMap<String, Integer>();
		List<word> word = new ArrayList<word>();
		// 발생빈도 작성
		for (int i = 0; i < words.length; i++) {
			Integer v = hmap.get(words[i]); // words[i] 가 key
			if (words[i].length() > 1) {
				// 기존에 해당 key 값이 없었다면 ( 즉 첫 등장이면)
				if (v == null) {
					hmap.put(words[i], 1);
				} else {// 기존 등장횟수에 +1 증가
					hmap.put(words[i], v + 1);
				}

			}
		}
		for (Map.Entry<String, Integer> e : hmap.entrySet()) {
			word.add(new word(e.getKey(), e.getValue()));
		}
		Collections.sort(word);
		for (word words1 : word) {
			System.out.println(words1.word + " : " + words1.count + "개" );
		}
			
		
		System.out.println("\n프로그램 종료");


	} // end main()

	 

} // end class

class word implements Comparable<word> {
	String word;
	int count;

	public word() {
		super();
	}

	public word(String word, int count) {
		super();
		this.word = word;
		this.count = count;
	}

	@Override
	public int compareTo(word o) {

		// 점수 내림차순
		if (o.count < this.count)
			return -1; // 내가 더 작으면 음수
		if (this.count < o.count)
			return 1; // 내가 더 크면 양수
		return 0; // 같으면 0

	}

}

 

 

2. Lec24_Lambda
1) com.lec.java.lambda01 패키지, Lambda01Main 클래스

package com.lec.java.lambda01;
/* 람다 표현식: lambda-expression
 	Java8 부터 도입:
		(매개변수 리스트) -> 리턴값
		(매개변수 리스트) -> {...}  수행코드

	추상메소드가 하나인 인터페이스 구현, 즉 익명클래스사용 더 간략화한 표현식
 */
public class Lambda01Main {

	public static void main(String[] args) {
		System.out.println("인터페이스, 익명 클래스, 람다 표현식");
		
		System.out.println();
		System.out.println("[1] 인터페이스를 구현하는 클래스");
		Addable myAdder = new AdderImple();
		double result = myAdder.add(1.11, 2.22);
		System.out.println("result = " + result);
		
		System.out.println();
		System.out.println("[2] 익명 클래스 사용");
		Addable myAdder2 = new Addable() {
			@Override
			public double add(double x, double y) {
				return x + y;
			}
		};
		result = myAdder2.add(1.11, 2.22);
		System.out.println("result = " + result);
		
		System.out.println();
		System.out.println("[3] 람다 표현식(lambda expression) 사용");
		// 추상메소드가 하나인 인터페이스 구현, 익명클래스사용 더 간략화한 표현식이다..!!
		Addable myAdder3 = (x, y) -> x + y;
		result = myAdder3.add(1.11, 2.22);
		System.out.println("result = " + result);
		
		System.out.println("\n프로그램 종료");
	} // end main()
	
} // end class

//인터페이스 정의
interface Addable {
	public abstract double add(double x, double y);
}

//인터페이스를 구현하는 클래스를 정의
class AdderImple implements Addable {
	@Override
	public double add(double x, double y) {
		return x + y;
	}
}


2) com.lec.java.lambda02 패키지, Lambda02Main 클래스, Test01, Test02, Test03, Test04, Test05 인터페이스

** Lambda02Main 클래스

package com.lec.java.lambda02;
/*	람다 표현식 (lambda - expression): 
	 	() -> 수행코드
	 	() -> 리턴값
	 	(매개변수..) -> 수행코드
	 	(매개변수..) -> 리턴값
	 	
	 매개변수의 타입은 생략해서 표현이 가능
	 매개변수가 여러개 있을 경우,
		 모든 매개변수의 타입을 생략해서 표현하거나,
		 모든 매개변수의 타입을 모두 다 표현해야 함. 
*/
public class Lambda02Main {

	public static void main(String[] args) {
		System.out.println("익명 클래스, 람다 표현식 연습");
		
		// 매개변수 없고, 리턴값도 없는 경우
		System.out.println("1) 매개변수 없고, 리턴값도 없는 경우");
		Test01 lambda01 = () -> System.out.println("안녕하세요");
		lambda01.testPrint();
		
		// 매개변수 한개, 리턴값은 없는 경우
		System.out.println();
		System.out.println("2) 매개변수 한개, 리턴값은 없는 경우");
		Test02 lambda02 = (x) -> System.out.println("num = " + x);
		lambda02.testPrint(55);
		
		// 매개변수 여러개, 리턴값이 있음.
		System.out.println();
		System.out.println("3) 매개변수 여러개, 리턴값이 있음.");
		Test03 lambda03 = (x, y) -> (x > y) ? x : y;
		System.out.println("result = " + lambda03.max(10, 20));
				
		// 매개변수 한개, 내부 수행코드 여러줄.., 리턴값.
		System.out.println();
		System.out.println("4) 매개변수 한개, 내부 수행코드 여러줄.., 리턴값.");
		Test04 lambda04 = (x) -> {
			System.out.println(x);
			return x.length();
		};
		System.out.println("result = " + lambda04.myStrLen("Java"));
		
		// Test05 인터페이스 만들기
		// void printMax(double x, double y)
		// [출력양식 예제]
		// x = 3.14
		// y = 1.2
		// 3.14 > 1.2
		Test05 lamTest05 = (x, y) -> {
			System.out.println("x = " + x);
			System.out.println("y = " + y);
			if(x > y) {
				System.out.println(x + " > " + y);
			} else {
				System.out.println(x + "<=" + y);
			}
		};
		lamTest05.printMax(3.14, 1.2);
		
		System.out.println("\n프로그램 종료");
	} // end main()

} // end class

 

** Test01, Test02, Test03, Test04, Test05 인터페이스

package com.lec.java.lambda02;

interface Test01 {
	// 매개변수도 없고, 리턴값도 없는 추상메소드
	public abstract void testPrint();
	
} // end interface Test01
package com.lec.java.lambda02;

interface Test02 {
	// 매개변수 있고, 리턴값 없는 추상메소드
	public abstract void testPrint(int num);
	
} // end interface Test02
package com.lec.java.lambda02;

interface Test03 {
	// 매개변수 있고, 리턴값 있는 추상메소드
	public abstract int max(int n1, int n2);
	
} // end interface Test03
package com.lec.java.lambda02;

interface Test04 {
	public abstract int myStrLen(String str);
	
} // end interface Test04
package com.lec.java.lambda02;

interface Test05 {
	public abstract void printMax(double x, double y);
	
} // end interface Test05

 

3) com.lec.java.lambda03 패키지, Lambda03Main 클래스

package com.lec.java.lambda03;
/*
	 세가지 방법으로 자유자재로 구현할수 있어야 합니다.
	 방법 1) 클래스 implements 인터페이스 + 오버라이딩.
	 방법 2) 익명클래스
	 방법 3) 람다 표현식 lambda expression
*/
public class Lambda03Main {

	public static void main(String[] args) {
		System.out.println("익명 클래스, 람다 표현식 연습");
		
		// 1) 클래스 implements 인터페이스 + 오버라이딩.
		System.out.println("1) 클래스 implements 인터페이스 + 오버라이딩을 이용하여 덧셈 연산하기");
		Add Test01 = new Add();
		double result = Test01.operate(20, 10);
		System.out.println("reslut = " + result);
		
		// 2) 익명클래스
		System.out.println();
		System.out.println("2) 익명클래스를 이용하여 뺄셈 연산");
		Operable Test02 = new Operable() {
			@Override
			public double operate(double x, double y) {
				return x - y;
			}
		};
		result = Test02.operate(20, 10);
		System.out.println("reslut = " + result);
		
		// 3) 람다 표현식 lambda expression
		System.out.println();
		System.out.println("3) 람다 표현식 lambda expression을 이용한 제곱연산");
		Operable Test03 = (x, y) -> Math.pow(x, y);
		result = Test03.operate(2, 3);
		System.out.println("result = " + result);
		
		System.out.println("\n프로그램 종료");
	} // end main()
	
} // end class

// public은 항상 파일이름과 일치해야함
// 그러므로 interface에 public 붙이면 안됨
interface Operable {
	public abstract double operate(double x, double y);
}

class Add implements Operable {
	@Override
	public double operate(double x, double y) {
		return x + y;
	}
}

 

 

3. Lec25_Thread
1) com.lec.java.thread01 패키지, Thread01Main 클래스

package com.lec.java.thread01;
/*	쓰레드 Thread
 *  동일 프로세스 내에 '독립'적인 다중 수행하는 프로그램 단위
 *  병행성 증진. 처리율 향상, 응답속도 향상 목적
 * 
 *  자바에서 쓰레드를 만들어서 사용하는 방법1:
 *   1. Thread 클래스를 상속받는 클래스를 정의
 *   2. 정의한 클래스에서 run() 메소드를 override - 쓰레드에서 할 일을 구현
 *   3. Thread 클래스의 인스턴스를 생성
 *   4. 생성된 인스턴스에서 start() 메소드를 호출
 */
public class Thread01Main {

	public static void main(String[] args) {
		System.out.println("쓰레드 생성 1");
		
		// 3. Thread 클래스의 인스턴스를 생성
		Thread th1 = new MyThread("Hello Java");
		Thread th2 = new MyThread("안녕하세요");
		
		// 4. 생성된 인스턴스에서 start() 메소드를 호출
		th1.start();
		th2.start();
		
		// Thread 클래스의 start() 메소드를 호출하면,
		// 내부적으로 run() 메소드가 호출됨
		// start() 메소드가 호출되어야 OS에 의해서 쓰레드로 동작을 하게 됨
		
		// run() 메소드를 직접 호출하는 경우는 쓰레드로 동작하는 것이 아니라,
		// 단순히 run() 메소드만 실행이 되는 것임.
		
		// 이때 발생하는 호출스택 관계도는 '자바의 정석' p626 그림 참조.   p628,629 예제
		
		System.out.println("=======================");
		System.out.println("여기는 언제 출력될까요?");
		System.out.println("=======================");
		
		
		// 하나의 쓰레드는 start() 가 딱 한번만 호출될수 있다.
		// 만약 아래와 같이 다시 start() 하면 IllegalThreadStateException 발생
		//th1.start();
		
		// 아래와 같이 새로 생성해서 사용하면 가능
		th1 = new MyThread("Heollo, Java2020!!");
		th1.start();
		
	} // end main()

} // end class


// 1. Thread 클래스를 상속받는 클래스를 정의
class MyThread extends Thread {
	
	private String msg;
	private int count;
	
	public MyThread() {}
	public MyThread(String msg) {
		this.msg = msg;
		count = 0;
	}
	
	// 2. 정의한 클래스에서 run() 메소드를 override
	// 쓰레드에서 할 일을 구현
	@Override
	public void run() {
		for(int i = 0; i < 100; i++) {
			System.out.println(getName() + " " + count + " : " + msg);
			count++;
		}
	}
	
} // end class MyThread

 

[추가] 하나의 쓰레드는 start() 가 딱 한번만 호출될수 있다.
         만약 아래와 같이 다시 start() 하면 IllegalThreadStateException 발생

2) com.lec.java.thread02 패키지, Thread02Main 클래스

package com.lec.java.thread02;
/* Runnable 인터페이스로 쓰레드 구현
 자바는 다중 상속을 지원하지 않음
 -> 다른 클래스를 상속받고 있는 경우에는, 
 Thread 클래스를 상속받을 수 없는 문제가 발생
 -> 인터페이스를 구현해서 쓰레드를 생성할 수 있는 방법을 제공

 쓰레드 사용 방법 2:
 1. Runnable 인터페이스를 구현하는 클래스를 정의
 2. 정의한 클래스에서 run() 메소드를 override
 3. Runnable을 구현하는 클래스의 인스턴스를 생성
 4. 만들어진 인스턴스를 Thread 생성자의 매개변수로 주면서, Thread 인스턴스를 생성
 5. 생성된 Thread 인스턴스의 start() 메소드를 호출
*/
// 메인에서 뽑아 냈던 모든 쓰레드가 종료되어야 프로그램이 종료된 것임..!!
public class Thread02Main {

	public static void main(String[] args) {
		System.out.println("쓰레드 생성 2");
		
		// 3. Runnable을 구현하는 클래스의 인스턴스를 생성
		Runnable runnable1 = new MyRunnable("안녕, 자바 프레임윅");
		Runnable runnable2 = new MyRunnable("Hello, HTML!!");
		Runnable runnable3 = new MyRunnable("멀티 쓰레드!!");

		// 4. Runnable을 이용해서 Thread 인스턴스를 생성
		Thread th1 = new Thread(runnable1);
		Thread th2 = new Thread(runnable2);
		
		// 5. Thread 인스턴스의 start() 메소드를 호출
		th1.start();
		th2.start();
		
		new Thread(runnable3).start();
		new Thread(new MyRunnable("Java Thread")).start();
		
		
		// Anonymous class 로 생성
		//System.out.println();
		//System.out.println("Anonymous class 으로 Runnable 구현");
		new Thread(new Runnable() {
			
			int count = 0;
			String msg = "풀스택 과정";
			
			@Override
			public void run() {
				for(int i = 0; i < 100; i++) {
					// Thread.currentThread() - 현재 이 코드를 실행중인 Thread 객체 리턴
					System.out.println(Thread.currentThread().getName() + " : " 
						+ count + " : " + msg);
					count++;
				}	
			}
		}).start();
		
		// Runnable 인터페이스는 run() 가상메소드 하나만 가지고 있는 인터페이스 이기 때문에
		// Lambda-expression 으로도  구현 가능.
		//System.out.println();
		//System.out.println("Lambda-expression 으로 Runnable 구현");
		new Thread(()-> {
			for(int i = 0; i < 100; i++) {
				// Thread.currentThread() - 현재 이 코드를 실행중인 Thread 객체 리턴
				System.out.println(Thread.currentThread().getName() + " : " 
					+ i + " : " + "쉬는시간이다..!!");
			}	
		}).start();
		
		System.out.println("-- main() 종료  -- ");
	} // end main()

} // end class


// 1. Runnable 인터페이스를 구현하는 클래스를 정의
class MyRunnable implements Runnable {
	private String msg;
	private int count;
	
	public MyRunnable() {}
	public MyRunnable(String msg) {
		this.msg = msg;
		count = 0;
	}	
	
	// 2. 정의한 클래스에서 run() 메소드를 override - 쓰레드 할 일
	@Override
	public void run() {
		for(int i = 0; i < 100; i++) {
			// Thread.currentThread() - 현재 이 코드를 실행중인 Thread 객체 리턴
			System.out.println(Thread.currentThread().getName() + " : " 
				+ count + " : " + msg);
			count++;
		}		
	}
	
} // end class MyRunnable

 

3) com.lec.java.thread03 패키지, Thread03Main 클래스

package com.lec.java.thread03;
/* 쓰레드와 익명클래스
 */
public class Thread03Main {

	public static void main(String[] args) {
		System.out.println("쓰레드와 익명 클래스");
		
		// 이미 정의된 MyRunnable 클래스의 인스턴스 사용
		new Thread(new MyRunnable()).start();
		
		// 익명 클래스를 사용해서 Runnable 인스턴스를 생성
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i = 0; i < 10; i++) {
					System.out.println("3 x " + i + " = " + (3 * i));

					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		for(int i = 0; i < 10; i++) {
			System.out.println("4 x " + i + " = " + (4 * i));
			
			try {
				Thread.sleep(800);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println("\n프로그램 종료");
	} // end main()

} // end class Thread03Main


class MyRunnable implements Runnable {

	@Override
	public void run() {
		for(int i = 0; i < 10; i++) {
			System.out.println("2 x " + i + " = " + (2 * i));
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	
} // end class MyRunnable

 

[추가] 메인쪽 쓰레드가 끝나더라도 다른 쪽 쓰레드가 끝나지 않아서 프로그램이 계속 실행될 수 있다

 

 

4. Lec26_FileIO
1) com.lec.java.file01 패키지, File01Main 클래스

package com.lec.java.file01;

import java.util.Scanner;

/* 스트림 (stream)
	[도착지]							[출발지]
	Program <--- InputStream <--- Source(Keyboard, Mouse, File, Network)
	
	[출발지]							[도착지]
	Program ---> OutputStream ---> Destination(Monitor, Beam, File, Network)


java.io 패키지의 주요 클래스

1) 바이트(byte) 단위 입출력 스트림 클래스
	java.io.InputStream: 프로그램이 '바이트 단위' 데이터를 읽어들이는(read) 통로
	java.io.OutputStream: 프로그램이 '바이트 단위' 데이터를 쓰는(write) 통로
		** 위 두개 클래스는 '추상클래스' 다
	
2) 문자(character) 단위 입출력 스트림 클래스
	java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
	java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로

3) java.io.File : 파일 시스템의 파일정보를 얻기 위한 클래스
	
4) java.io.Console : 콘솔로부터 문자을 입출력하기 위한 클래스
*/
public class File01Main {

	public static void main(String[] args) {
		System.out.println("IO(Input/Output)");
		
		// InputStream 객체 in을 가지고 읽어들일 수 있는 스캐너 객체 생성
		Scanner sc = new Scanner(System.in);
		sc.close();
		
		// 외부장치(콘솔, 키보드)로부터 데이터를 읽음
		
		// OutpustStream 객체인 out이 가지고 있는 println() 메소드를 사용
		// 외부장치(콘솔, 모니터)에 데이터를 씀
		System.out.println("hello");
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

 

[선행학습] 파일 복사 실습을 위해 big_eng, big_txt 파일을 준비

2) com.lec.java.file02 패키지, File02Main 클래스

package com.lec.java.file02;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* FileIO
 Program <=== InputStream <=== Source
 Program ===> OutputStream ===> Source
 Program <=== FileInputStream <=== File
 Program ===> FileOutputStream ===> File

 java.io.InputStream
  |__ java.io.FileInputStream: 파일로부터 데이터를 읽어오는 통로
 java.io.OutputStream
  |__ java.io.FileOutputStream: 파일로 데이터를 쓰는 통로
*/

// Stream은 1byte 단위로 읽는다!
public class File02Main {

	public static void main(String[] args) {
		System.out.println("File IO");

		InputStream in = null;		// InputStream 변수 선언
		OutputStream out = null;	// OutputStream 변수 선언
		
		try {
			// FileInputStream 인스턴스 생성
			in = new FileInputStream("temp/big_text.txt");
			
			// FileOutputStream 인스턴스 생성
			out = new FileOutputStream("temp/copy_big_text.txt");
				// 위 파일이 없으면 새로 생성
				//	   있으면 기존 파일 삭제 후 새로 생성
			
			int dataRead;
			int bytesCopied = 0;
			
			long StartTime = System.currentTimeMillis();	// 현재시간 저장
			
			// 파일복사 : 읽기 -> 쓰기
			while(true) {
				// 데이터 읽기: InputStream에 있는 read() 메소드 사용
				// read()는 InputStream 으로부터 
				// 1byte 씩 읽어서 int(4byte) 에 담아 리턴한다
				// [ ... ][ ... ][ ... ][ 1byte ]
				dataRead = in.read();
				if(dataRead == -1) {	// 더 이상 읽을 것이 없으면 read()는 -1 리턴
					break;
					
				}
				
				// 데이터 쓰기: OutputStream에 있는 write() 메소드 사용
				// write() 는 
				// int(4byte)에 1byte씩 담아 OutputStream에 쓴다
				// [ ... ][ ... ][ ... ][ 1byte ]
				out.write(dataRead);
				bytesCopied++;
			}
            
			long endTime = System.currentTimeMillis();	// 끝난 시간 저장
			long elapsedTime = endTime - StartTime;		// 경과시간
			
			System.out.println("읽고 쓴 바이트: " + bytesCopied);
			System.out.println("경과 시간(ms): " + elapsedTime);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 리소스 해제
			// 파일은 무조건 리소스 해제 해야함!!!
			try {
				if(out != null) {out.close();}
				if(in != null) {in.close();}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		
		System.out.println("\n프로그램 종료");
	} // end main()

} // end class

 

[추가] copy_big_text.txt 파일 복사(읽기 -> 쓰기)

         InputStream(FileInputStream), OutputStream(FileOutputStream)
         입출력 스트림으로부터 한 번에 한 바이트씩 read / write 하기 때문에 매~우 느리다

[추가] IOException, FileNotFoundException

3) com.lec.java.file03 패키지, File03Main 클래스

package com.lec.java.file03;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*
 java.io.InputStream
  |__ java.io.FileInputStream
 java.io.OutputStream
  |__ java.io.FileOutputStream
*/

public class File03Main {

	public static void main(String[] args) {
		System.out.println("File IO 2");
		
		// Java 7부터 도입된 try-with-resource
		// try (리소스 생성) { ... }
		// catch (exception ) { ... }
		// 리소스를 close하는 코드가 없어도 자동으로 close가 실행
		//
		// java.lang.AutoCloseable 나 
		//  └─ java.io.Closeable 을 상속받은 어떠한 객체라도 
		//  try(리소스 생성) 안에 '선언' 되어 있으면
		//  try~catch 가 끝나기 전에 close() 됨.
		
		// InputStream, OutputStream 둘다 Closeable 을 상속(implements) 한다
		
        
		try (
				// try-with-resource
				// try (리소스 생성) { ... }
				// catch (exception ) { ... }
				// 리소스를 close하는 코드가 없어도 자동으로 close가 실행
				InputStream in = new FileInputStream("temp/big_text.txt");
				OutputStream out = new FileOutputStream("temp/copy_big_text.txt");
				){
			
			byte [] buff = new byte[1024];   // 버퍼 준비
			int lengthRead = 0;  // 버퍼에 읽어드린 바이트수
			int byteCopied = 0;
			
			long startTime = System.currentTimeMillis();
			
			// 파일복사
			while(true) {
				// 데이터 읽기
				// 매개변수로 주어진 byte[] 배열의 길이 만큼 read한다.
				// 실제 읽어 들인 데이터는 매개변수 byte[] 에 담김.
				// 읽어들인 바이트 리턴,  읽어들인게 없으면 -1 리턴.
				lengthRead = in.read(buff);
				if(lengthRead == -1) {break;}
				
				// 데이터쓰기
				out.write(buff, 0, lengthRead);   // 직전에 읽어들인 데이터만큼 write
				byteCopied += lengthRead;
			}
			
			long endTime = System.currentTimeMillis();
			long elapsedTime = endTime - startTime;
			
			System.out.println("전체 복사한 바이트: " + byteCopied);
			System.out.println("경과 시간: " + elapsedTime);
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

 

[추가] 입출력 스트림으로부터 한번에 1024 바이트씩 read / write 하니까 빨라짐. 

4) com.lec.java.file04 패키지, File04Main 클래스

package com.lec.java.file04;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* 보조스트림 (filter stream)
Program <=== FilterInputStream <=== InputStream <=== Source
		   ↓ 상속		  ↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File

Program ===> FilterOutputStream ===> OutputStream ===> Source
		   ↓ 상속		  ↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File

java.io.InputStream
 |__ java.io.FilterInputStream
      |__ java.io.BufferedInputStream

java.io.OutputStream
 |__ java.io.FilterOutputStream
      |__ java.io.BufferedOutputStream

참고 ) 보조스트림 (filter stream)
보조스트림(filter stream) 이란 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림
*/

public class File04Main {

	public static void main(String[] args) {
		System.out.println("BufferedInputStream, BufferedOutputStream");

		InputStream in = null;		// InputStream 변수 선언
		BufferedInputStream bin = null;
        
		OutputStream out = null;	// OutputStream 변수 선언
		BufferedOutputStream bout = null;
		
		try {
			in = new FileInputStream("temp/big_text.txt");
			bin = new BufferedInputStream(in);	// 장착!
            
			out = new FileOutputStream("temp/copy_big_text.txt");
			bout = new BufferedOutputStream(out);	// 장착!
		
		int dataRead;
		int bytesCopied = 0;
		
		long StartTime = System.currentTimeMillis();	// 현재시간 저장
		
		// 파일복사 : 읽기 -> 쓰기
		while(true) {
			dataRead = bin.read();
            
			if(dataRead == -1) {		// 더 이상 읽을 것이 없으면 read()는 -1 리턴
				break;
			}
			
			bout.write(dataRead);
			bytesCopied++;
		}
        
		long endTime = System.currentTimeMillis();	// 끝난 시간 저장
		long elapsedTime = endTime - StartTime;		// 경과시간
		
		System.out.println("읽고 쓴 바이트: " + bytesCopied);
		System.out.println("경과 시간(ms): " + elapsedTime);
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
    
		try {
			if(bout != null) {bout.close();}
			if(bin != null) {bin.close();}
			// bin을 close 하면, bin을 만든 in도 같이 close됨
			// bout을 close 하면, bout을 만든 out도 같이 close됨
		} catch (IOException e) {
			e.printStackTrace();
		}
        
	}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

 

[추가] Buffered I/O Stream 을 기존의 I/O Stream 에 장착하면, 자체적으로 버퍼링하여,  입출력의 속도가 향상. 

5) com.lec.java.file05 패키지, File05Main 클래스

package com.lec.java.file05;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* Buffered Stream + Buffer 예제
Program <=== FilterInputStream <=== InputStream <=== Source
		  ↓ 상속		  ↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File

Program ===> FilterOutputStream ===> OutputStream ===> Source
		  ↓ 상속		  ↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File

java.io.InputStream
 |__ java.io.FilterInputStream
      |__ java.io.BufferedInputStream

java.io.OutputStream
 |__ java.io.FilterOutputStream
      |__ java.io.BufferedOutputStream
*/

public class File05Main {

	public static void main(String[] args) {
		System.out.println("Buffered Stream + Buffer");
		
		// file03 패키지 참조
		// try with resource 구문으로 작성
		// in.read(buff) --> bin.read(buff);
		// out.write( , , ) --> bout.write( , , ); 사용
		// finally 필요 없음
		
		
		try (
				InputStream in = new FileInputStream("temp/big_text.txt");
				BufferedInputStream bin = new BufferedInputStream(in);		// 장착!
				
				OutputStream out = new FileOutputStream("temp/copy_big_text.txt");
				BufferedOutputStream bout = new BufferedOutputStream(out);	// 장착!
				){
			
			byte [] buff = new byte[1024];   // 버퍼 준비
			int lengthRead = 0; 		 // 버퍼에 읽어드린 바이트수
			int byteCopied = 0;
			
			long startTime = System.currentTimeMillis();
			
			// 파일복사
			while(true) {
				// 데이터 읽기
				// 매개변수로 주어진 byte[] 배열의 길이 만큼 read한다.
				// 실제 읽어 들인 데이터는 매개변수 byte[] 에 담김.
				// 읽어들인 바이트 리턴, 읽어들인게 없으면 -1 리턴.
				lengthRead = bin.read(buff);
				if(lengthRead == -1) {break;}
				
				// 데이터쓰기
				bout.write(buff, 0, lengthRead);   // 직전에 읽어들인 데이터만큼 write
				byteCopied += lengthRead;
			}
			
			long endTime = System.currentTimeMillis();
			long elapsedTime = endTime - startTime;
			
			System.out.println("전체 복사한 바이트: " + byteCopied);
			System.out.println("경과 시간: " + elapsedTime);
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");

	} // end main()

} // end class File05Main

 

[추가] Buffered I/O Stream 에다가 버퍼 까지 제공하면 비약적으로 I/O 속도 향상. 

6) com.lec.java.file06 패키지, File06Main 클래스

package com.lec.java.file06;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*  Data Filter Stream
 Program <=== DataInputStream <=== FileInputStream <=== File
 Program ===> DataOutputStream ===> FileOutputStream ===> File

java.io.InputStream
|__ java.io.FilterInputStream
   |__ java.io.DataInputStream  

java.io.OutputStream
|__ java.io.FilterOutputStream
   |__ java.io.DataOutputStream
*/

public class File06Main {

	public static void main(String[] args) {
		System.out.println("Data Filter Stream");
		
		try(
				OutputStream out = new FileOutputStream("temp/data.bin");
				DataOutputStream dout = new DataOutputStream(out);	// 장착!!
				
				InputStream in = new FileInputStream("temp/data.bin");
				DataInputStream din = new DataInputStream(in);		// 장착!!
				){
			
			dout.writeBoolean(true);	// 1byte
			dout.writeInt(100);		// 4byte
			dout.writeDouble(3.14);		// 8byte
			dout.writeChar('A');		// 2byte
			
			boolean b = din.readBoolean();
			System.out.println("boolean: " + b);
			
			int num1 = din.readInt();
			System.out.println("int: " + num1);
			
			double num2 = din.readDouble();
			System.out.println("double: " + num2);
			
			char ch = din.readChar();
			System.out.println("char: " + ch);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

 

[추가] 콘솔창 출력 (DataInputStream, FileInputStream)
         File -> FileInputStream -> DataInputStream -> Program

[추가] data.bin 파일 출력 (DataOutputStream, FileOutputStream)

         Program -> DataOutputStream -> FileOutputStream -> File

7) com.lec.java.file08 패키지, File08Main 클래스, Serializable 인터페이스 받은 Member 클래스

** File08Main 클래스

package com.lec.java.file08;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

/* Object Filter Stream
 Program <=== ObjectInputStream <=== FileInputStream <=== File
 Program ===> ObjectOutputStream ===> FileOutputStream ===> File

java.lang.Object
 └─ java.io.OutputStream
    └─ java.io.ObjectOutputStream
 
java.lang.Object
 └─ java.io.InputStream
     └─ java.io.ObjectInputStream


 Object Stream: 객체의 입출력을 위한 스트림
 사용법은 다른 Filter Stream(Buffered I/O, Data I/O)과 비슷
 Object 스트림의 입출력 대상이 되는 클래스는 Serializable 인터페이스를 구현
 클래스의 일부 멤버 변수를 직렬화(Serialization)의 대상에서 제외시키려면,
 transient 키워드를 사용
*/

public class File08Main {
	
	public static final String FILEPATH  = "temp/member.dat";

	public static void main(String[] args) {
		System.out.println("Object Filter Stream");
		
		try(
				OutputStream out = new FileOutputStream(FILEPATH);
				ObjectOutputStream oout = new ObjectOutputStream(out);
				
				InputStream in = new FileInputStream(FILEPATH);
				ObjectInputStream oin = new ObjectInputStream(in);
				){
			
			Member m1 = new Member("root", "root1234");
			Member m2 = new Member("guest", "guest");
			Member m3 = new Member("admin", "admin123456");
			
			oout.writeObject(m1);
			oout.writeObject(m2);
			oout.writeObject(m3);
			
			// 파일에서 Object 타입으로 읽기
			Member dataRead;

			// 읽는 방법 1) 매번 readObject() 호출
//			dataRead = (Member)oin.readObject();
//			dataRead.displayInfo();
//			
//			dataRead = (Member)oin.readObject();
//			dataRead.displayInfo();
//			
//			dataRead = (Member)oin.readObject();
//			dataRead.displayInfo();
			
			// 읽는 방법 2) 무한루프로 readObject() 호출
			//  EOFException 으로 잡기
			//  EOF : End Of File
			while(true) {
				dataRead = (Member)oin.readObject();
				dataRead.displayInfo();
			}
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (EOFException e) {	// EOFException는 IOException을 상속 받음 
			System.out.println("파일 끝까지 읽었습니다!");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 

		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

 

** Serializable 인터페이스 받은 Member 클래스

package com.lec.java.file08;

import java.io.Serializable;

public class Member implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String id;
	private String pw;
	transient private int num;
	transient private boolean isExist;
	
	// transient로 선언된 변수는 serialization(직렬화) 대상에서 제외됨.
	// (파일에 write되지 않는다)
	//	de-serialization(역직렬화, 파일에서 읽기)를 할 때는 
	// 해당 타입의 기본값(0, false, null)으로 초기화됨
	
	public Member() {}
	public Member(String id, String pw) {
		this.id = id;
		this.pw = pw;
		this.num = 123;
		this.isExist = true;
	}
	
	public void displayInfo() {
		System.out.println("--- 회원 정보 ---");
		System.out.println("아이디: " + id);
		System.out.println("비밀번호: " + pw);
		System.out.println("번호: " + num);
		System.out.println("Exist? " + isExist);
	}
	
} // end class Member 

 

 

** Object Stream: 객체의 입출력을 위한 스트림 **

[추가] File -> FileInputStream -> ObjectInputStream -> Program

[추가] Program -> ObjectOutputStream -> FileOutputStream -> File

8) com.lec.java.file09 패키지, File09Main, Serializable 인터페이스를 상속 받은 Member 클래스

** File09Main 클래스

package com.lec.java.file09;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import com.lec.java.file08.Member;

// Object Filter Stream + Collection

// Program <=== ObjectInputStream <=== FileInputStream <=== File
// Program ===> ObjectOutputStream ===> FileOutputStream ===> File

// ArrayList<> 와 같은 Collection 에서,
// 모든 데이터들이 Serializable 되어 있으면 ObjectInputStream / ObjectOutputStream 으로
// read/write 가능.

public class File09Main {
	
	public static final String FILEPATH  = "temp/member2.dat";

	public static void main(String[] args) {
		System.out.println("Object Filter Stream");

		try(
				OutputStream out = new FileOutputStream(FILEPATH);
				ObjectOutputStream oout = new ObjectOutputStream(out);
				
				InputStream in = new FileInputStream(FILEPATH);
				ObjectInputStream oin = new ObjectInputStream(in);
				){
			
			ArrayList<Member> list = new ArrayList<Member>();
			
			Member m1 = new Member("root", "root1234");
			Member m2 = new Member("guest", "guest");
			Member m3 = new Member("admin", "admin123456");
			
			list.add(m1);
			list.add(m2);
			list.add(m3);

			oout.writeObject(list);		// List를 한번에 저장!
			
			list = null;
			
			list = (ArrayList<Member>)oin.readObject();
			for(Member m : list) {
				m.displayInfo();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (EOFException e) {	// EOFException는 IOException을 상속 받음 
			System.out.println("파일 끝까지 읽었습니다!");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class File08Main

 

** Serializable 인터페이스를 상속 받은 Member 클래스

package com.lec.java.file09;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import com.lec.java.file08.Member;

// Object Filter Stream + Collection

// Program <=== ObjectInputStream <=== FileInputStream <=== File
// Program ===> ObjectOutputStream ===> FileOutputStream ===> File

// ArrayList<> 와 같은 Collection 에서,
// 모든 데이터들이 Serializable 되어 있으면 ObjectInputStream / ObjectOutputStream 으로
// read/write 가능.

public class File09Main {
	
	public static final String FILEPATH  = "temp/member2.dat";

	public static void main(String[] args) {
		System.out.println("Object Filter Stream");

		try(
				OutputStream out = new FileOutputStream(FILEPATH);
				ObjectOutputStream oout = new ObjectOutputStream(out);
				
				InputStream in = new FileInputStream(FILEPATH);
				ObjectInputStream oin = new ObjectInputStream(in);
				){
			
			ArrayList<Member> list = new ArrayList<Member>();
			
			Member m1 = new Member("root", "root1234");
			Member m2 = new Member("guest", "guest");
			Member m3 = new Member("admin", "admin123456");
			
			list.add(m1);
			list.add(m2);
			list.add(m3);

			oout.writeObject(list);		// List를 한번에 저장!
			
			list = null;
			
			list = (ArrayList<Member>)oin.readObject();
			for(Member m : list) {
				m.displayInfo();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (EOFException e) {	// EOFException는 IOException을 상속 받음 
			System.out.println("파일 끝까지 읽었습니다!");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class File08Main

 

[추가] ArrayList<>와 같은 Collection에서 모든 데이터들이 Serializable 되어 있으면 
         ObjectInputStream / ObjectOutputStream으로 read/write 가능.

9) com.lec.java.file11 패키지, File11Main 클래스

package com.lec.java.file11;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
문자(character) 단위 입출력 스트림 클래스
 java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
  └─ java.io.InputStreamReader
      └─ java.io.FileReader

 java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로
  └─ java.io.OutputStreamWriter
      └─ java.io.FileWriter

 FileReader / FileWriter 객체는 '텍스트파일, 즉 문자 단위' 데이터를 읽고/쓰기 할때
 사용하는 기반 스트립 입니다.   따라서 텍스트가 아닌 오디오, 비디오, 등의 파일을 다룰수 없습니다.
 주로 String 이나 char [] 내용을 입/출력 할때 사용합니다.

 텍스트 파일 (Text File) 이란
   사람이 읽을수 있는 글자들이 저장된 파일
   암호화 되지 않은 평범한 텍스트

 이진파일 (Binary File) 이란
   사람이 직접 읽을수는 없음.

   ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★	
*/


public class File11Main {
	public static void main(String[] args) {
		System.out.println("FileReader / FileWriter");
		
		String src = "temp/FileData.txt";
		String dst = src;
		
		try (
				FileWriter fw = new FileWriter(dst);
				FileReader fr = new FileReader(src);
				){
			String str = "안녕하세요";		// 한글 5글자
			char [] charArr = {'J','A','V','A'};	// 영문 4글자
			
			fw.write(str);		// 저장은 시스템 인코딩 상태에 따라 저장됨.
						// UTF-8 인코딩의 경우, 
						// 한글은 한글자당 3byte, 영문은 1byte로 저장
			fw.write(charArr);	
			fw.flush();		// write() 호출 후에는 flush()하여 
						// 출력 버퍼의 데이터가 완전히 출력되도록 한다.
			
			// 읽기
			char[] buff = new char[100];
			int charsRead = 0;		// 읽어들인 문자의 개수
			charsRead = fr.read(buff);	// 몇글자 읽어들였는지 리턴
			for(int i = 0; i < charsRead; i++) {
				System.out.println(buff[i]);
			}
			System.out.println();
			System.out.println("읽은 문자개수: " + charsRead);
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()
    
} // end class

 

[추가] java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
       └ java.io.InputStreamReader
          └ java.io.FileReader

[추가] java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로

          └ java.io.OutputStreamWriter
             └ java.io.FileWriter

10) com.lec.java.file12 패키지, File12Main 클래스

package com.lec.java.file12;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 버퍼사용 문자입출력 : BufferedReader, BufferedWriter
 * 
 * java.lang.Object
 *  └─ java.io.Reader
 *      └─ java.io.BufferedReader
 *       
 * java.lang.Object
 *  └─ java.io.Writer
 *      └─ java.io.BufferedWriter
 *      
 * ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★     
 *             
*/

/*
 * txt 는 utf-8 로 인코딩 , 영문 텍스트
 */
public class File12Main {
	
	private static final String BIG_TEXT = "temp/big_eng.txt"; 
	
	public static void main(String[] args) {
		System.out.println("FileReader / FileWriter");

		FileWriter fw = null;
		FileReader fr = null;
		
		BufferedReader br = null;
		BufferedWriter bw = null;
		
		int charRead = 0;
		int charsCopied = 0;
		long startTime, endTime, elapsedTime;
		
		System.out.println("FileReader/Writer만 사용");
		try {
			fr = new FileReader(BIG_TEXT);
			fw = new FileWriter("temp/big_eng_copy1.txt");
			
			startTime = System.currentTimeMillis();
			
			// read()는 한글자씩 읽어서 리턴.
			// 더이상 읽은 것이 없으면 -1 리턴
			while((charRead = fr.read()) != -1) {
				fw.write(charRead);
				charsCopied++;
			}
			fw.flush();	// 문자 출력시 마지막에 꼭 flush()를 하자
					// flush()를 하지 않으면 정상적으로 파일 출력이 끝나지 않는다!
			
			endTime = System.currentTimeMillis();
			elapsedTime = endTime - startTime;
			
			System.out.println("읽고 쓴 문자수: " + charsCopied);
			System.out.println("경과 시간(ms): " + elapsedTime);
			
			//-------------------------------------------------
			fw.close();
			fr.close();
			//-------------------------------------------------
			
			System.out.println();
			System.out.println("BufferdReader/Writer + 버퍼 사용");
			fr = new FileReader(BIG_TEXT);
			fw = new FileWriter("temp/big_eng_copy2.txt");
			br = new BufferedReader(fr);	// 장착
			bw = new BufferedWriter(fw);	// 장착
			
			char[] buf = new char[1024];
			
			int charsRead = 0;	// 버퍼에 몇글자 읽어들었나?
			charsCopied = 0;
			
			startTime = System.currentTimeMillis();
			
			while((charsRead = br.read(buf)) != -1) {
				bw.write(buf, 0, charsRead);
				charsCopied += charsRead;
			}
			
			endTime = System.currentTimeMillis();
			elapsedTime = endTime - startTime;
			
			System.out.println("읽고 쓴 문자수: " + charsCopied);
			System.out.println("경과 시간(ms): " + elapsedTime);
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fw != null) {bw.close();}
				if(fr != null) {br.close();}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
		System.out.println("\n프로그램 종료");		
		
	} // end main()
	
} // end class

 

[추가] java.lang.Object
       └ java.io.Reader
          └ java.io.BufferedReader

[추가] java.lang.Object
        └ java.io.Writer
           └ java.io.BufferedWriter

11) com.lec.java.file13 패키지, File13Main 클래스

package com.lec.java.file13;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

/* PrintWriter / 인코딩 
 * 
 * java.lang.Object
 *  └─ java.io.Writer
 *      └─ java.io.PrintWriter
 *  
 *  텍스트 파일 작성시는 PrintWriter 객체 편리
 *  	println(), print(), printf() ..
 *  텍스트 파일 읽을시는 BufferedReader 객체 편리
 *  	read(), read(버퍼), readLine()..
 *  
 *  PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("파일명" 혹은 File)));
 *  PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter
 *  						 (new FileOutputStream("파일명" 혹은 File))));
 *  
 *  BufferedReader br = new BufferedReader(new FileReader("파일이름" 혹은 File));
 *  BufferedReader br = new BufferedReader(new InputStreamReader
 * 						 (new FileInputStream(new File("파일이름" 혹은 File))));
 *  BufferedReader br = new BufferedReader(new InputStreamReader
 *  						 (new FileInputStream("파일이름" 혹은 File)));
 *  
 *  ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
 * 
 *  인코딩 문제 
 *  	FIleReader, FileWriter 는 파일의 인코딩을 무조건 file.encoding 값으로 간주한다.
 * 		(ex: LINUX 는  UTF-8,  MacOS 는 한글상위의 경우 euc-kr, 윈도우즈는 Java 소스코드 인코딩 영향) 
 *  	
 *  인코딩 설정하기
 *  	InputStreamReader, OutputStreamWriter 를 사용해서 인코딩 변경을 해야 한다.
 *  
 *  	BufferedReader br = new BufferedReader(new InputStreamReader
 *						(new FileInputStream("파일이름" 혹은 File),"인코딩"));
 *  	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter
 *						(new FileOutputStream("파일이름" 혹은 File), "인코딩"));
 *   
 *  인코딩 : "UTF8", "euc-kr"
 *   
*/

public class File13Main {
	
	private static final String FILE1 = "temp/PrintData.txt";
	private static final String FILE2 = "temp/PrintData_euckr.txt";
	
	public static void main(String[] args) {
		System.out.println("PrintWriter / 인코딩 ");
		
		FileWriter fw = null;
		FileReader fr = null;
		
		PrintWriter out = null;
		
		BufferedReader br = null;
		BufferedReader bw = null;
		
		try {
//			fw = new FileWriter(FILE1);
//			bw = new BufferedWriter(fw);	// 장착!
//			out = new PrintWriter(bw);
			
			// 위의 코드를 한줄로 줄이기 가능
			out = new PrintWriter(new BufferedWriter(new FileWriter(FILE1)));
			test_write(out);
			
			System.out.println();
			br = new BufferedReader(new FileReader(FILE1));
			test_read(br);
			
			//-----------------------------------------------
			out.close();
			br.close();
			//-----------------------------------------------
			
			System.out.println("현재 OS인코딩 " + System.getProperty("file.encoding"));
			// euc-kr로 인코딩 저장
			out = new PrintWriter(new BufferedWriter(new OutputStreamWriter
					(new FileOutputStream(FILE2), "euc-kr")));
			test_write(out);
			System.out.println();
			
			br = new BufferedReader(new InputStreamReader
					(new FileInputStream(FILE2), "euc-kr"));
			test_read(br);
			
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
			
			try {
				if(br != null) {br.close();}
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()
	
	
	public static void test_write(PrintWriter out) {
		out.println("안녕하세요 Java 한글이 잘 보이나요?");
		out.print((2000 + 20) + " " + 3.14);
		out.println();
		out.printf("%d-%d-%d\n", 2020, 3, 2);
		out.flush();	// flush() 까먹지 말자!
	}
	
	public static void test_read(BufferedReader br) {
		String line;
		StringBuffer sb = new StringBuffer();
		try {
			while((line = br.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(sb.toString());
	}
	
} // end class

 

[추가] 텍스트 파일 읽을시는 BufferedReader 객체 편리
         read(), read(버퍼), readLine(), ...

[추가] 텍스트 파일 작성시는 PrintWriter 객체 편리
         println(), print(), printf(), ...

'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글

2020.04.01  (0) 2020.04.01
2020.03.31  (0) 2020.03.31
2020.03.27  (0) 2020.03.27
2020.03.26  (0) 2020.03.26
2020.03.25  (0) 2020.03.25