일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 배열복사
- wan
- 배열빈도수
- 모래시계출력
- dbeaver
- 배열최소값최대값
- 네트워크모델
- javax.management.instancenotfoundexception: org.springframework.boot:type=admin
- 백준1946
- 디비버
- name=springapplication
- 리눅스환경
- 포트포워딩
- 브로드캐스트
- Decapsulation
- 도커
- 도커권한설정
- SpringApplication
- 우분투
- 유니캐스트
- ubuntu
- 페이로드
- 오름차순
- instancenotfoundexception
- docker
- 리눅스계열
- 백준
- 포트포워딩 안될때
- springboot
- jmx
- Today
- Total
다잘하고싶어
자바 파일 입출력 본문
목차
☑️ I/O와 Stream
I/O
- 데이터의 입력(input)과 출력(output)
- 데이터는 한쪽에서 주고 한쪽으로 받는 구조 ( 일방통행 )
스트림
- 바이트가 흘러가는 통로
✅ I/O 처리 단위
byte ( 바이트 스트림) | Char(문자 스트림) | |
입력 | InputStream | Reader |
출력 | OutputStream | Writer |
⇒ 4가지 모두 추상클래스
⇒ 실제 사용하는 입출력 객체들은 위의 4가지의 하위 클래스 이다.
☑️ 바이트 스트림
⇒ 바이트가 흘러가는 통로
☑️ 문자 스트림
⇒ 문자가 흘러가는 통로
☑️ InputStream 의 주요메서드 (입력스트림 _ 바이트)
✅ read()
public abstract int read() throws IOException
⇒ 매개변수 없음
⇒ byte 하나를 읽어서 int 로 반환. 더이상 읽을 값이 없으면 -1 반환.
public int read(byte b[]) throws IOException
⇒ 매개변수 바이트배열 ( 하나씩 읽어오면 비효율적, 한방에 여러개씩 보내기)
⇒ 데이터를 읽어서 b를 채우고, 읽은 바이트의 개수를 리턴.
⇒ 0 이 되면 더이상 읽을 값이 없는 상황.
public int read(byte b[], int offset, int len) throws IOException
⇒ 최대 len 만큼 데이터를 읽어서, b의 offset 부터 b에 저장하고 읽은 바이트 개수를 리턴.
⇒ len + offset 은 b의 크기 이하여야 함.
☑️ Reader 의 주요메서드 (입력스트림 _ 문자)
public int read() throws IOException
⇒ char 하나를 읽어서 int 로 반환. 더이상 읽을 값 없으면 -1 리턴
public int read(char cbuf[]) throws IOException
⇒ 데이터를 읽어서 cbuf를 채우고, 읽은 문자의 개수를 리턴.
☑️OutputStream 의 주요메서드(출력스트림 _ 바이트)
✅ write()
⇒ 바이트를 다루는 메서드지만, 묵시적 형변환에 의해 int 로 다룰 수 있다.
☑️ Writer의 주요메서드(출력스트림 _ 문자)
✅ OutputStream 과 Writer의 flush ()
⇒ 버퍼가 있는 스트림에서 버퍼의 내용을 출력하고 버퍼를 비운다
✉️ File
⇒ 가장 기본적인 입출력 장치 중 하나로 파일과 디렉터리를 다루는 클래스
⇒ “input.txt” ⇒ new File(”input.txt”)
☑️ FileInputStream, FileOutputStream, FileReader, FileWriter
❗입출력에는 항상 자원이 소모되므로 사용 후 닫아주는 과정 필수❗
실습코드(1) 파일 복사
- try finally 문을 사용한다
- 왜? finally 는 언제나 실행되므로 사용중인 자원을 반납할 때( 입출력 스트림 사용 시) 사용
- 따라서 아래 코드는 예외처리의 과정이 아님.
빨간줄 → throws 로 처리
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("newjeans.jpg"); // 파일이름
out = new FileOutputStream("newjeans-copy.jpg");// 복사하기
int b;// byte 를 int형으로 저장해도 됨
while ((b = in.read()) != 1) {
out.write(b);
}
System.out.println("복사를 완료했습니다.");
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
System.out.println("모든 리소스를 닫고 종료합니다.");
}
}
}
⇒ 복사된 파일 생성된 것 확인가능
실습코드(2) try with resources사용
try with resources
- try 다음에 ( ) ( ) … 가 옴
- ( ) 안에 필요한 리소스를 정의
- 구분은 ; 로 함
- close 할 필요 없이 알아서 close 해줌
public class Test3 {
public static void main(String[] args) throws IOException {
try (FileInputStream in = new FileInputStream("newjeans.jpg");
FileOutputStream out = new FileOutputStream("newjeans-copy22.jpg");){
int b;//byte 를 int형으로 저장해도 됨/
while( (b = in.read()) != 1) {
out.write(b);
}
System.out.println("복사를 완료했습니다.");
System.out.println("알아서 스트림을 닫아줍니다. 종료합니다.");
}
}
}
실습코드(3) buffer 사용
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class Test2 {
public static void main(String[] args) throws IOException {
try (FileInputStream in = new FileInputStream("newjeans.jpg");
FileOutputStream out = new FileOutputStream("newjeans-copy33.jpg");
){
//버퍼를 사용하기
byte[] buffer = new byte[10];
int read; //byte 를 int 형으로 저장해도 됨.
while( (read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
System.out.println(Arrays.toString(buffer) + " , "+ read);
}
System.out.println("복사를 완료했습니다.");
System.out.println("알아서 스트림을 닫아줍니다. 종료합니다.");
}
}
}
⇒ 매번 .read(buffer) 할 때마다 알아서 읽어오면서 buffer 에 바이트를 채워줌.
( buffer 는 배열이름)
⇒ read : 어디까지 읽으면 되는지 저장, 더이상 읽을 게 없다면 -1 반환
⇒ out.write(buffer, 0, read);//버퍼를 어디서부터 어디까지 사용하는지?
Q. 위의 코드에서 왜 마지막 3개의 값이 같을까? (feat. write() 메서드 이해하기)
코드에서 길이를 표현하는 변수를 read 로 선언하고, 버퍼배열 출력 후 출력되도록 했다.
맨 마지막에 출력된 read (길이) 의 값은 7개임 ( while문에서 더이상 읽을 게 없어 -1 반환된 것)
즉, 마지막의 3개의 값은 새롭게 채워지지 않았으므로(그 전에 다 읽어서 while문 멈춤), 그 직전의 미리 채워져있던 버퍼 배열 안의 값이 그대로 유지된 것이다.
실습코드 (4) _ 문자스트림
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) throws IOException {
try(FileReader reader = new FileReader("big_input.txt");
FileWriter writer = new FileWriter("big_input_copy.txt")){
int c ; //character 를 int 에 담아도(묵시적)
while((c=reader.read())!= -1) {
writer.write(c);
}
System.out.println("복사를 완료했습니다");
System.out.println("try with resource 구문 사용 - 알아서 정리");
}
}
}
☑️ 보조스트림
✅ 보조스트림 : Filter Stream, Processing Stream
- 다른 스트림에 부가적인 기능을 제공하는 스트림
- 문자를 set 으로 변환
- Buffering 기능 추가
- 기본 데이터 형으로 변형 ( byte → 정수, 실수로 변환)
✅ 보조 스트림의 종류
✅ 생성 (보조스트림 사용법)
→ 이전 스트림을 생성자의 파라미터에 연결
✅ 종료 :
→ 보조 스트림의 close() 를 호출하면 노트스트림의 close() 까지 호출
✅ 사용할 스트림 결정 과정
1️⃣ 노드가 무엇인지 확인 2️⃣ 타입이 문자열인지 바이트인지 확인 (노트 스트림 구성) 3️⃣ 방향이 무엇인가 4️⃣ 추가 기능이 필요한가( 보조스트림 구성)
예시 1
예시 2
예시 3
☑️ Buffered 계열 → 버퍼기능이 추가된것
과연 시간이 더 빠를까?
✅ [ FileReader & FileWriter ] VS [ BufferedReader& BufferedWriter ]
예외 처리 안해서 빨간줄 뜸. throws 로 넘기기
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) throws IOException {
//FileReader, FileWriter
test1(" FileReader & FileWriter ");
//BufferedReader, BufferedWriter
test1("BufferedReader & BufferedWriter");
}
//FileReader, FileWriter 사용
public static void test1(String testname) throws IOException {
try(FileReader reader = new FileReader("big_input.txt");
FileWriter writer = new FileWriter("big_input_copy3.txt")){
long start = System.nanoTime();
int c;
while((c = reader.read()) != -1) {
writer.write(c);
}
long end = System.nanoTime();
System.out.printf("%s - %15d ns. \\n", testname, end-start);
}
}
//보조스트림 BufferedReader,BufferedWriter 사용
public static void test2(String testname) throws IOException {
try(BufferedReader reader = new BufferedReader(new FileReader("big_input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("big_input_copy2.txt"))){
long start = System.nanoTime();
String line;
while((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
long end = System.nanoTime();
System.out.printf("%s - %15d ns. \\n", testname, end-start);
}
}
}
BufferedReader, BufferedWriter 는 character 하나씩 읽어오지않고 line 단위로 읽어온다.
결과
⇒ 보통은 10배정도 차이가 난다.
✅ Scanner vs BufferedReader
package test04;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) throws IOException {
//Scanner vs BufferedReader
//big_input.txt 에서 한 줄 씩 읽어와서 정수형으로 바꾸기
test1(" Scanner : ");
test2("BufferedReader : ");
}
//Scanner
public static void test1(String testname) throws IOException {
try(Scanner scan = new Scanner(new FileInputStream("big_input.txt"))){
long start = System.nanoTime();
while(scan.hasNext()) {
int num = scan.nextInt();
}
long end = System.nanoTime();
System.out.printf("%s - %15d ns. \\n", testname, end-start);
}
}
// BufferedReader
public static void test2(String testname) throws IOException {
try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("big_input.txt")))){
long start = System.nanoTime();
String l;
while((l=br.readLine())!=null) {
int num = Integer.parseInt(l);
}
long end = System.nanoTime();
System.out.printf("%s - %15d ns. \\n", testname, end-start);
}
}
}
결과
⇒ FileInputStream 은 character, 이걸 byte 로 읽어야 한다 → 필요한 것? InputStreamReader 라는 보조스트림 필요.
⇒ 즉, 파일을 FileInputStream 으로 받아와서, BufferedReader로 읽기 위해서 InputStreamReader 스트림을 통해 가져온다.
inputstream 을 fileReader 로 가져올 거임
표준입출력 → 알고리즘
System.in ← InputStream
System.out ← OutputStream
ex. 키보드에서 입력받을 때
BufferedReader in = new BufferedReader( new InputStreamReader(System.in));
✅ 파일클래스의 메소드
public class Test1 {
public static void main(String[] args) {
//File 클래스
//file 또는 directory의 객체 생성
File f = new File("big_input.txt");
System.out.println("이름 : "+ f.getName());
System.out.println("경로 : "+ f.getPath());
System.out.println("디렉토리 여부 : "+ f.isDirectory());
System.out.println("파일 여부 : "+ f.isFile());
System.out.println(f.toString());
}
}