클라우드 융합 Full-stack 웹 개발자 양성과정/Java

프로그래밍 언어응용 - API(String, Math, Wrapper), IO

thesunset 2022. 9. 25. 20:22

# StringPool

package com.kh.controller;

public class A_StringPoolTest {

> String 클래스 => 불변클래스(변하지 않는 클래스)

 

 String 클래스 형태의 객체 생성방법(2가지)

 1. new키워드로 생성자 호출

 2. 대입연산자통해서 직접 값을 넣어서 생성

1. 생성자를 통해서 문자열 담기

public void method1() {

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1.toString());
System.out.println(str1); //String 클래스에서 오버라이딩되어있음.

1) String 클래스의 toString()의 경우

실제 담겨있는 문자열값을 반환하게끔 오버라이딩이 되어있음

System.out.println(str1.equals(str2));
//true => 문자열을 비교했는데 동일하다.

 2) String 클래스의 equals()의 경우

주소값 비교가 아닌 문자열 비교를 하도록 오버라이딩

 

//16진수의 주소값 => 10진수의 주소값

System.out.println(str1.hashCode());
System.out.println(str2.hashCode());// 주소값이 동일

3) String클래스의 hashCode()

주소값을 변환해주는 것이 아닌 실제 담긴 문자열을 기반으로 해시코드 값을 만들어서 반환

//진짜 주소값을 알고싶다면

//System.identityHashCode(참조형변수명)

System.out.println(System.identityHashCode(str1));​
System.out.println(System.identityHashCode(str2));

//실제 주소값의 해시코드를 출력

//str1, str2의 주소값이 다르다

System.out.println(str1 == str2); //false

2. 문자열을 리터럴로 생성 => 항상 1번 말고 2번을 사용해야함. 1번은 메모리 낭비가 일어날 수 있음.

public void method2() {

String str1 = "Hello";

String str2 = "Hello";

//toString()

System.out.println(str1);
System.out.println(str2); //동일​

//equals()

System.out.println(str1.equals(str2));

//hashCode()

System.out.println(str1.hashCode());​
System.out.println(str2.hashCode()); //동일

//System.identityHashCode()

System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2)); //동일
System.out.println(str1 == str2);//true

}

> String클래스의 StringPool

public void method3() {

String str = "Hello";

//리터럴 대입 시 String Pool영역에 올라감

//String Pool의 특징 : 동일한 내용의 문자열이 존재 불가능

System.out.println(System.identityHashCode(str));

str = "Goodbye"; //새롭게 대입

System.out.println(System.identityHashCode(str));

//내용물이 바뀌는 것이 아닌 주소값이 바뀌는 것 == String의 불변클래스 특징

//연결이 끊긴 문자열은 가비지콜렉터가 알아서 정리해줌

//불변이라고해서 아예 수정이 안되는 것이 아니라 매번 새로운 주소값을 참조한다는 뜻.

str += "abc";

System.out.println(System.identityHashCode(str)); //주소값이 다름

String a = "a";
String b = "a";
System.out.println("결과: " + a == b); //우선순위때문에 false
System.out.println("결과: " + (a == b)); //true
}

public void method4() {

> Buffer: 임시 저장공간

1. StringBuffer

//문자열은 안에 내용물이 변경될 때 마다 새로운 공간을 할당하고 새로 집어 넣는다.

//이를 막기 위해 임시공간(Buffer)을 하나 준비하여

//임시공간에 차곡차곡 담아두었다가 한 번에 처리해주는 클래스

//StringBuffer(동시제어o) / StringBuilder(동시제어 x)

StringBuffer sb = new StringBuffer();

1) append() : 문자열 입력 시 

sb.append("Hello"); //문자열을 받아주는 메소드호출

System.out.println(sb.hashCode()); // 366712642

System.out.println("Hello".hashCode()); // 69609650

sb.append(" World!");

System.out.println(sb.hashCode()); // 366712642 

System.out.println("Hello World".hashCode()); -862545276

System.out.println("결과: " + sb);

//StringBuffer는 동시제어기능(Thread Safe)기능을 가진다. (StringBuilder은 없음)

//간단한 프로그램 구현이나, 동시제어를 다른 프로그램이 제공하는 경우

//동시제어를 구현할 필요는 없다(속도가 느려짐)

//이 기능을 제외한 클래스가 바로 StringBuilder

}

public void method5() {

2. StringBuilder

StringBuilder sb = new StringBuilder();

sb.append("Hello");
System.out.println(sb.hashCode()); // 366712642
System.out.println("Hello".hashCode()); // 69609650

sb.append(" World!");
System.out.println(sb.hashCode()); //366712642
System.out.println("Hello World".hashCode()); //-862545276

sb.append("Hi");
System.out.println(sb.hashCode()); // 366712642
System.out.println("Hello World Hi".hashCode());//703047741

System.out.println("결과: " + sb); //결과: Hello World!Hi​
	}
}

# StringMethod

package com.kh.controller;

import java.util.Scanner;

public class B_StringMethodTest {

> 문자열과 관련된 메소드들

public void method1() {

String str1 = "Hello World";

 

[형태] 메소드명(매개변수) : 반환형

1. 문자열.CharAt(int index) : char

=> 문자열의 인덱스 출력 

char ch = str1.charAt(4);
System.out.println("ch: " + ch); //ch: o

2. 문자열.concat(String str) : String

=> 문자열과 전달받은 또 다른 문자열을 하나로 합쳐서 반환

=> 문자열 + 전달받은문자형

String str2 = str1.concat("!!!!!!!!!");
System.out.println("str2: " + str2); //str2: Hello World!!!!!!!!!

3. 문자열.length() : int

=> 문자열길이를 반환(공백도 포함)

System.out.println("str1의 길이: " + str1.length()); //str1의 길이: 11

4. 문자열.substring(int beginindex) : String

 문자열.substring(int beginindex, int endindex) : String

=> 문자열의 beginindex의 위치에서 endindex까지의 문자열을 추출해서 리턴

System.out.println(str1.substring(6)); //World
System.out.println(str1.substring(0,6));// Hello

5. 문자열.replace(char old, char new) : String

문자열에서 old문자를 new문자로 변환한 문자열 리턴

str1.replace('1', 'x');
System.out.println(str1);// 인자값이 없기 때문에 바뀌지 않음

String str3 = str1.replace('l', 'x');
System.out.println(str3);

6. 문자열.trim() : String

=> 문자열의 앞 뒤 공백을 제거한 문자열 리턴

String str4 = "       J a      v a          ";
System.out.println(str4.trim()); //가운데 공백은 유지, 양쪽 공백만

7. 문자열.toUpperCase() : String

모든 문자열을 대문자로 변경 후 문자열 리턴

문자열.toLowerCase() : String

모든 문자열을 소문자로 변경 후 문자열 리턴

System.out.println(str1.toUpperCase());
System.out.println(str1.toLowerCase());

8.문자열.toCharArray() : char[]

=> 문자열의 각 문자들을 char[]배열에 옮겨담은 후 해당 배열을 리턴

char[] chArr = str1.toCharArray();
for(int i = 0; i<chArr.length; i++) {
	System.out.println(chArr[i] + " ");
}

8-1. String.valueOf(배열명): String 

=>char형의 배열 각 문자들을 문자열로 변환 해 리턴 

//char[] => String

char[] arr = {'a', 'p', 'p', 'l', 'e'};
System.out.println(String.valueOf(arr));

​* 이 외 메소드는 jdk 1.8 document String에 많이 나와있음. => 많이 보기

public void method2() {

> 적용해보기 

//종료하시겠습니까? (Y/N): Y아니면 N입력받기

- 경우의 수

1. Y

2. N

3. y

4. n

5. 와이

6. 엔

... 경우의 수가 많음

Scanner sc = new Scanner(System.in);
System.out.println("종료하시겠습니까?(Y/N) : ");

char a = sc.nextLine().toUpperCase().charAt(0);

 

1. 문자열 입력

2. 문자열의 모든 알파벳을 대문자로 바꿈

3. 0번째 인덱스의 문자만 추출

=>  메소드체이닝 : 메소드를 연이어서 호출

if(a=='Y') {
	System.out.println("종료합니다.");
return;
} else if(a=='N') {
	System.out.println("종료되지 않았습니다.");
} else {System.out.println("잘못된 값입니다.");}
	}
}

# Run

package com.kh.run;

import com.kh.controller.A_StringPoolTest;
import com.kh.controller.B_StringMethodTest;
import com.kh.controller.C_StringTokenizerTest;

public class StringRun {
public static void main(String[] args) {
A_StringPoolTest a = new A_StringPoolTest();
//a.method1();
//a.method2();
//a.method3();
//a.method4();
//a.method5();

B_StringMethodTest b = new B_StringMethodTest();
//b.method1();
//b.method2();
C_StringTokenizerTest c = new C_StringTokenizerTest();
//c.method1();
c.method2();
	}
}

# MathRun

package com.kh.run;

> import java.lang.*;(전부)

- 생략이 가능

- 보이지는 않는데 항상 import

- 자바프로그래밍을 하면서 필수적인 클래스들을 모아놓은 패키지

public class MathRun {

public static void main(String[] args) {

> Math클래스(수학과 관련)

- Math 클래스에서 제공하는 유용한 기능들을 살펴보자!

* Math클래스의 특징

- java.lang 패키지 안에 존재한다.

- 모든 필드와 메소드가 다 static으로 되어있다. (객체를 만들 필요 없음)

- 객체를 생성할 필요가 없으므로 생성자가 private

//Math th = new Math(); //static이기 때문에 객체 생성할 필요가 없음

- 필드

// 파이 => Math클래스 내에 상수필드로 정의되어있음.

System.out.println("파이: " + Math.PI); //파이: 3.141592653589793

- 메소드

메소드명(매개변수타입): 반환형

1. 올림 => Math.ceil(double) : double

double num1 = 4.23353;

System.out.println("올림: " + Math.ceil(num1)); //올림: 5.0

2. 반올림 => Math.round(double) : long

System.out.println("반올림: " + Math.round(num1)); //반올림: 4

3. 버림 => Math.floor(double) : double

System.out.println("버림: " + Math.floor(num1)); //버림: 4.0

4. 절대값 => Math.abs(int/double/long/float) : int/double/long/float

int num2 = -13;
System.out.println("절대값: " + Math.abs(num2)); // 절대값: 13

5. 최소값 => Math.min(int, int) : int

System.out.println("최소값: " + Math.min(5, 10)); //최소값: 5​

6. 최대값 => Math.max(int, int) : int

System.out.println("최대값: " + Math.max(5, 10));​ //최대값: 10

7. 제곱근(루트) => Math.sqrt(double) : double

System.out.println("4의 제곱근: " + Math.sqrt(4)); //int로 인자값을 주어도 double로 자동형변환 
//4의 제곱근: 2.0

8. 제곱 => Math.pow(double, double) : double

System.out.println("2의 5제곱: " + Math.pow(2, 5)); //32.0

* 모든게 다 static이기 때문에 객체 생성을 할 필요가 없음

 => 싱글톤패턴 (프로그램 실행과 동시에 메모리 영역에 올려놓고 재사용하는 개념)

* JDBC에서 싱글톤패턴에 대해서 다룰것.

}

}


# StringTokenizer

 

package com.kh.controller;

import java.util.StringTokenizer;

public class C_StringTokenizerTest {

문자열을 분리시키는 방법

1. 구분자를 제시해서 해당 문자열을 분리시키는 방법 => 배열 이용

2. 분리된 각각의 문자열을 토큰으로 취급하는 방법 => 토큰 이용

String str = "배고프다, 졸리다, 집가고싶다, HelloWorld";

방법 1. 문자열.split(String 구분자) : String[]

public void method1() {
//문자열.split(String 구분자) : String[]

String[] arr = str.split(",");

for(int i = 0; i<arr.length; i++) {
	System.out.println(arr[i]);
}

 + 향상된 for문: 초기식, 조건식, 증감식 쓰지 않음.

[표현법] for(값을 받아줄 변수 선언:순차적으로 접근할 배열){}

for(String s : arr) {
	System.out.println(s); //arr의 주소값
}

//출력만 가능
//배열의 값 수정 불가능
}

방법2. StringTokenizer

public void method2() {

//각각의 문자열을 토큰으로 처리 (토큰으로 생긴 자료형이 있다라고 생각)

-java.util.StringTokenizer 클래스를 이용하는 방법

1.  객체생성 : StringTokenizer stn = new StringTokenizer(문자열, 구분자);

StringTokenizer stn = new StringTokenizer(str, ",");

2. 하나씩 토큰 빼기

System.out.println(stn.nextToken());//첫번째 토큰 빠짐
System.out.println(stn.nextToken());//두번째 토큰 빠짐
System.out.println(stn.nextToken());//세번째 토큰 빠짐
System.out.println(stn.nextToken());//네번째 토큰 빠짐

//그러면 이제 남아있는 토큰이 없다

//또 nextToken() 호출하면?

System.out.println(stn.nextToken());//NoSuchElementException 오류

 

 3. 남아있는 토큰 알아보기 : hasMoreTokens()

//반복문 사용하기

while(stn.hasMoreTokens()) { //정확히 초기식, 증감식 모를 때 사용

//hasMoreTokens()

//stn 남아있는 토큰이 있다면 true
//토큰이 다빠졌으면 false

System.out.println(stn.nextToken());
}

 

4. countTokens() : 분리된 문자열의 개수를 반환해주는 메소드

System.out.println("분리된 문자열의 개수: " + stn.countTokens());​

 


# Wrapper

package com.kh.run;

public class WrapperRun {

public static void main(String[] args) {

* Wrapper Class

=> 기본자료형을 객체로 포장해주는 클래스를 Wrapper class라고 함

기본자료형 Wrapper Class
boolean Boolean
char Charactor
byte Byte
short Short
int Integer
long Long
float Float
double Double

 

- 기본자료형을 객체로 취급해야하는 경우

- 메소드의 매개변수로 기본자료형이 아닌 객체타입만 요구 될 때

- 다형성을 적용시키고 싶을 때 (반복문)

int num1 = 10;

int num2 = 15;

- 만약에 num1과 num2를 동등비교 하고 싶다면?

System.out.println(num1 == num2);
//System.out.println(num1.equals(num2));

- equals = Object 소유 , 주소값비교

equals () => 주소값을 비교해서 같으면 true / 다르면 false return

//모든 클래스 전부 Object를 상속받고 있음

- 기본 자료형은 Object를 상속받고 있지 않기 때문에 사용불가능

-  int형을 Wrapping클래스 자료형 Integer로 

Integer i1 = new Integer(num1);

i1.equals(num2); // false

- 기본자료형 => Wrapper클래스 자료형

Integer i1 = num1;
Integer i2 = num2;

//autoBoxing이라고도 함

System.out.println(i1.equals(i2)); //false
System.out.println(i1.compareTo(i2)); //-1

* a.compareTo(b): a가 b보다 크면 1반환 ,a가 b보다 작으면 -1반환, 같으면 0반환

//"123" -> 숫자로써야한다면?

- 문자열을 Integer타입으로

//Integer i3 = "123";

Integer i4 = new Integer("123"); => 객체 생성해야함 
int num5 = i4.intValue();
System.out.println(num5); //123

int num3 = i1;
int num4 = i2;
System.out.println("num3 + num4: " + (num3 + num4));

- 기본자료형 <-->String

String str1 = "10"; //int형으로 쓰고 싶고

String str2 = "15.0"; //double형으로 쓰고 싶을때

1. String형을 기본자료형으로 parsing (비슷한 말로 번역)

[표현법]

해당 Wrapper클래스이름.parseXXX(변환할문자열);

int i = Integer.parseInt(str1); //"10" => 10 ***********기억해두기
double d = Double.parseDouble(str2); //"15.0" => 15.0

System.out.println(i+d);//25.0

2. 기본자료형을 String으로

=>String.valueOf(변환할 자료형값) : String

String strI = String.valueOf(i); //valueOf => 이탤릭체 = static
String strD = String.valueOf(d);
System.out.println(strI+strD);//1015.0
	}
}

# File

package com.kh.chap01_file.run;

import java.io.File;

import java.io.IOException;

public class FileRun {

public static void main(String[] args) {

//입력과 출력은 기준을 잡아야함. 내가 만드는 프로그램이 기준, 기준으로 외부에 생기면 출력, 외부에 있는 걸 나한테 가져오면 입력

//간단하게 파일을 만드는 과정

//File 클래스를 가지고 작업

//java.io 패키지에 존재 -> import

> 파일 클래스 객체 생성

1. 별도의 경로지정하지 않고 파일명만 제시해서 생성

=> File file1 = new File("test.txt"); //파일이름입력(String)

//현재 이 프로젝트 폴더 내에 파일이 생성됨

//createNewFile(): 파일을 생성해주는 메소드 => 예외처리해주어야 함.

try {file1.createNewFile();

2. 경로지정을 해서 파일명을 제시해서 생성

=> 실제 존재하는 경로를 제시해야함.

//C:\file를 미리 만들고 이 폴더에 저장한다고 하면, 

File file2 = new File("C:\\file\\test.txt");
file2.createNewFile();

**\은 개행문자 때문에 2번씩 입력해주어야 함.

 

3. 폴더 생성하고 안에 파일도 생성 : mkdir() 폴더를 생성해주는 메소드 

File forder = new File("newforder");
forder.mkdir();

//mkdir(): 폴더를 생성해주는 메소드

File file3 = new File("newforder\\test.txt");
file3.createNewFile();

4. 경로지정 후 폴더 생성 후 파일생성

File fileforder = new File("C:\\file\\fff");
fileforder.mkdir();

File file4 = new File("C:\\file\\fff\\test.txt");
file4.createNewFile();

>  File클래스에서 제공하는 메소드들

 

1. 파일객체이름.isfile(): 파일이면 true, 폴더면 false

System.out.println("파일이세요? " + file4.isFile()); //true
System.out.println("파일이세요? " + fileforder.isFile()); //false

 

​2. 파일객체이름.getName(): 파일명 추출

System.out.println("파일이름: " + file4.getName());//파일명 추출​

3. 파일객체이름.getParent() : 상위폴더명 추출

System.out.println("상위폴더: " + file4.getParent());//상위폴더명 추출​

4. 파일객체이름. length() : 파일용량 추출

System.out.println("파일용량: " + file4.length());//파일크기​

5. 파일객체이름.getAbsolutePath() : 절대 경로 추출

System.out.println("절대경로: " + file4.getAbsolutePath());//절대경로​

}catch(IOException e){

e.printStackTrace();//출력

}

}

* 프로그램 상의 데이터를 외부매체(모니터, 스피커, "파일")로 출력하거나

                    입력장치(키보드, 마우스, 카메라, 마이크, "파일")로 입력받는 과정 = 입출력(IO)

=> IO(Input & Output), 입출력

 

* IO가 되는 원리

- IO를 진행하고 싶으면, 우선적으로 "반드시"프로그램과 외부매체와의 "통로"를 만들어야 한다

 => "스트림" (Stream) - 통로

 

*  스트림의 특징

 - 단방향 :입력이면 입력, 출력이면 출력

 입력용 스트림따로, 출력용스트림 따로 존재 // 동시에 XX 하나의 스트림으론 절대XX

- 선입선출(FIFO) : 먼저 전달한 값이 먼저 나오게 됨 => 큐(Queue)

- 시간지연문제가 발생할 수 있다.

 

* 스트림의 구분

- 통로의 사이즈

1) 바이트스트림(작): 1Byte가 이동할 수 있는 좁은 통로

 => 입력(XXXInputStream) //출력(XXXOutputStream)

 

2) 문자스트림(큰) : 2Byte가 이동할 수 있는 넓은 통로

=> 입력(XXXReader)/출력(XXXWriter)

 

 - 외부매체와의 직접적인 연결 여부

 

1)  기반스트림: 외부매체와 직접적으로 연결되는 통로

 

2) 보조스트림: 기반스트림만으로 부족한 성능을 향상시켜주는 용도로 만들어진 스트림

=> 단독사용불가(기반스트림을 만들고 추가해주는 용도)

=> 속도향상, 자료형에 맞춰서 변환, 객체단위로 입출력하게 도움

 

}


# Byte

package com.kh.chap02_byte.model.dao;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

DAO(Data Access Object) : 데이터가 보관되어있는 공간에 직접 접근해서 데이터를 입출력하는 메소드들을 모아둔 클래스(dao)

public class FileByteDao {

public void fileSave() {

- 바이트 스트림 실습

- 출력: 프로그램 --> 외부매체(파일)

//출력: 프로그램 내의 데이터를 파일로 내보내기(파일에 기록하겠다)

-> FileOutputStream : "파일"로 데이터를 출력하되, 1Byte단위로 출력하겠다.

1. FileOutputStream객체 생성

=> 해당파일과 직접 연결되는 통로를 만들겠다.

- 해당파일이 존재하지 않는 경우: 해당파일이 생성되면서 통로도 연결된다.

- 해당파일이 존재하는 경우: 그냥 통로만 연결된다. =>옵션지정가능

- true를 작성할 시 => 해당파일에 내용이 있을 경우 이어서 작성("a_byte.txt", true);

- true를 작성하지 않을 시에는 => 덮어쓰기가 됨("a_byte.txt");

FileOutputStream fout = null; // 객체생성 

try {
fout = new FileOutputStream("a_byte.txt"); //파일과 연결

2. 연결통로(파일)로 데이터 출력 : write() 호출

- 1Byte의 범위: -128 ~ 127까지의 숫자가 출력가능함

- 0~127까지의 숫자만 사용 => 아스키코드표 참조(음수는 절대 불가)

//데이터 출력

fout.write(97); //a
fout.write(98); //b
fout.write(99); //c
fout.write(100); //d

byte[] arr = {101, 102, 103}; //한번에 보내야 함
fout.write(arr);
//efg
fout.write(arr, 1, 2); //슬라이싱 가능
//arr배열로부터 1번인덱스에서 2개만 쓰고 싶다.
//fg

//abcdefgfg

//write함수의 오버로딩 적용

fout.write('A');

fout.write('B');

fout.write('C');

fout.write('박');

fout.write('혜');

fout.write('진');

//한글은 2Byte

//못 지나가지는 않지만 Stream크기보다 커서 깨져서 저장됨

//Byte Stream은 불가능

//문자스트림을 쓰면 가능

3. 스트림을 다 사용했다면 *****꼭*****해줘야하는 작업이 있음.

다 썼으면 반드시 **자원 반납**을 해줘야 함 = 개발자들 간 약속

fout.close(); //무조건*************

//=> 이 위치에 있으면 오류 발생시 바로 Catch문으로 가서 실행되지 않음.

} catch(FileNotFoundException e) {
	e.printStackTrace();
} catch(IOException e) {
	e.printStackTrace();
} finally { //어떤 예외가 발생했든 반드시 실행할 구문을 finally블록 안에 넣어준다. (catch문, try문 모두 거친 후)
try {
	fout.close(); //무조건*************반납
} catch(IOException e) {
	e.printStackTrace();
		}
	}
}

프로그램 <-- 외부매체(파일)

//입력: 파일로부터 데이터를 가지고 오겠다.

public void fileRead() {

//FileInputSteam

//파일로부터 데이터를 가져와서 입력받을건데, 1Byte단위로 입력받겠다.

FileInputStream fis = null; //통로 생성

try {

1. 객체생성 파일(외부매체)와 통로를 연결하겠다.

fis = new FileInputStream("a_byte.txt");

2. 통로로부터 데이터 입력받기

//read()이용

//1Byte단위로 하나씩 읽어옴(토큰과 비슷)

fis.read();

System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read()); // -1
//파일이 끝을 만나는 순간 fis.read()를 호출하면?
// => -1을 반환한다.

//만약 문자가 1000개면?

//반복문사용

​- 주의할 점

while(fis.read() != -1) { //조건문에서도 읽은 것으로 침. => 퐁당퐁당으로 출력됨.
System.out.println(fis.read());
}

 => 변수활용해 해결하기

int value = 0;
while((value = fis.read()) != -1) {
	System.out.println(value);
}

3. 마지막으로 해야 할 일 //close() 호출

} catch(FileNotFoundException e) {
	e.printStackTrace();
} catch(IOException e) {
	e.printStackTrace();
} finally {
		try {fis.close();
		}catch(IOException e) {
			e.printStackTrace();
					}
			}
	}
}

# Byte_Run

package com.kh.chap02_byte.run;
import com.kh.chap02_byte.model.dao.FileByteDao;

public class ByteRun {

public static void main(String[] args) {

FileByteDao fbd = new FileByteDao();
//fbd.fileSave();
fbd.fileRead();
}
}

 

# Char

package com.kh.chap03_char.model.dao;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class FileCharDao {

//프로그램 --> 외부매체(파일)

//출력

public void failSave() {

//FileWriter: 파일로 데이터를 2Byte단위로 출력하는 스트림

FileWriter fw = null;

 

1.객체 생성 => 파일과 연결된 통로를 만들겠다.

try {

fw = new FileWriter("b_char.txt");

2. 파일에 쓰기 => write()

fw.write("IO 출력 테스트");//줄바꿈을 하고 싶을 경우 \n개행문자를 통해 (문자이기때문에 가능)
fw.write("B");
char[] arr = {'a', 'b', 'c', 'd'};
fw.write(arr);
}catch(IOException e ) {
	e.printStackTrace();
} finally {
try {
//3. 자원반납 => close()통로를 닫아주겠다.
fw.close(); //***꼭***
} catch(IOException e) {
e.printStackTrace();
		}
	}
}

//프로그램 <--외부매체(파일)

//입력

public void fileRead() {

//FileReader : 파일로 데이터를 2Byte단위로 입력하는 스트림

0. 객체선언

FileReader fr = null;

try {

//1. 객체생성

fr = new FileReader("b_char.txt");

//2. 읽어들이기 => read()

System.out.println(fr.read()); //I
System.out.println(fr.read()); //O
System.out.println(fr.read()); //
System.out.println(fr.read()); //출
int value = 0;
while((value = fr.read()) != -1) {
	System.out.print((char)value);
} //=> 반복문 사용
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {
	try {
	fr.close();
	} catch (IOException e) {
	e.printStackTrace();
			}
		}
	}
}

# Char_ Run

package com.kh.chap03_char.run;
import com.kh.chap03_char.model.dao.FileCharDao;
public class Run {
public static void main(String[] args) {
FileCharDao fcd = new FileCharDao();
//fcd.failSave();
fcd.fileRead();
}
}

# Buffered

package com.kh.chap04_assist.part01_befferd.model.dao;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class BufferedDao {

//BufferedReader / BufferedWriter

//=> 속도 향상 목적의 보조 스트림(BuffferedXXX)

//=> 버퍼공간을 제공해서 한 번에 모아뒀다가 한 번에 입출력 진행

//[표현법]

//보조스트림클래스이름 객체이름 = new 보조스트림클래스이름(기반스트림객체);

// => 보조스트림은 단독으로 존재할 수 없음

//프로그램 --> 외부매체(파일)

//출력

public void fileSave() {

//BufferesWriter : 버퍼공간을 제공해서 한 번에 출력을 진행하겠다.

- 기반스트림이 Input/Output계열일 경우

  보조스트림도 Input/Output계열을 사용

- 기반스트림이 Reader/Writer계열일 경우

  보조스트림이 Reader/Writer계열을 사용

FileWriter fw = null;
BufferedWriter bw = null;

1. 기반스트림 객체 생성 => 연결통로 만들겠다.

try {
	fw = new FileWriter("c_buffer.txt");

2. 보조 스트림 객체 생성

bw = new BufferedWriter(fw);
//bw2 = new BufferedWriter(new FileWriter("c_buffer.txt")); //객체생성 동시에 가능

3. 파일에 쓰기 => write()

bw.write("안녕하세요");
bw.newLine();
bw.write("반갑습니다.");
bw.newLine(); //개행
bw.write("안녕히가세요.");
} catch (IOException e) {
	e.printStackTrace();
} finally {
//4. 자원반납 => close()
//자원 반납 시에는 반드시 생성된 자원의 역순으로 반납함.
try {
	bw.close();
	fw.close();
	} catch (IOException e) {
	e.printStackTrace();
		}	
	}
}

 

public void readFile() {

//입력

//BufferedReader()

/*

FileReader fr = null;

BufferedReader br = null;

try {

1.기반스트림 객체

fr = new FileReader("C_buffer.txt");

2.보조스트림 객체

br = new BufferedReader(fr);

3. 읽어오기 => br.read()

String result = null;
while((result = br.readLine()) != null) {
	System.out.println(result); }
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {
try {

4. 자원 반납 => close()

br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}

- 실수로 자원반납을 잊어버린다면?

* try ~ with ~ resource 구문

[표현법]

 try(스트림객체생성;){

 예외가 발생할 법한 구문

 } catch(예외클래스이름 e){

 해당예외가 발생했을 때 실행할 구문

 }

 -스트림 객체를 try(이곳)에 넣어버리면 스트림 객체 생성 후 해당블록의 구문이 실행완료되었을 때 알아서 자원 반납이 된다.

* JDK 7버전 이상부터 가능

String result = null;
try(FileReader fr = new FileReader("c_buffer.txt"); BufferedReader br = new BufferedReader(fr))
	{ while((result = br.readLine()) != null) {
	System.out.println(result); }
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
				}
			}
	}
}

# Buffered_Run

package com.kh.chap04_assist.part01_befferd.run;

import com.kh.chap04_assist.part01_befferd.model.dao.BufferedDao;

public class Run {

public static void main(String[] args) {

BufferedDao bd = new BufferedDao();
//bd.fileSave();
bd.readFile();
}
}