이미지 같은걸 처리할땐 바이트 기반 스트림을 사용한다.
PipedInputStream : 소스값이 파이프와 필터를 거치며 필요한 값을 추출 (마치 정수기의 물의 여과과정)
Source -> [pipe1] - [filter1] - [pipe2] - [filter2] - [pipe3] - [filter3] - Result
주로 프로세스를 다룰때 사용
FilterInputStream : 보조스트림으로 용도에 따라 4가지가 있음
- BufferedInputStream
ByteArrayInputStream : 바이트로 구성된 Array를 읽어옴
StringbufferedInputStream : 문자열 읽어오는 스트림
InputStream
바이트 기반 입력스트림의 최상위 클래스로 추상클래스임
- FileInputStream
- BufferedInputStream
- DataInputStream
OutputStream
바이트 기반 출력 스트림의 최상위 클래스로 추상클래스임
- FileOutputStream
- BufferedOutputStream
- DataOutputStream
- PrintStream
flush() : DB의 commit()처럼 해당명령어를 통해 메모리에서 디스크로 내려줘야함
Reader
문자 기반 입력 스트림의 최상의 클래스, 추상 클래스
- FileReader
- InputStreamReader
- BufferedReader
Writer
문자 기반 출력 스트림의 최상의 클래스, 추상 클래스
- FileWriter
- OutputStreamWriter
- BufferedWriter
- printWriter
File Class
파일 시스템의 파일을 표현하는 클래스
File file = new File("파일 경로")
File file = new File("C:/Users....")
파일/ 디렉토리 메소드
리눅스와 유사함 (같은계열인 유닉스, 맥도 비슷)
생성 / 삭제
정보 리턴
FileInputStream / FileOutputStream
파일로 부터 바이트 단위로 읽을 때 사용
그림, 오디오, 비디오, 텍스트 파일등 모든 데이터로 파일로 저장
파일을 읽어올때 파일이 존재 하지 않으면 FileNotFoundException 오류가 뜨니 예외처리를 해주자
FileInputStream fis = new FileInputStream("C:/data/test.txt")
FileOutputStream fos = new FileOutputStream("C:/data/test.txt");
FileOutputStream fos = new FileOutputStream ("C:/data/test.txt", true); // 기존 파일에 이어서 작성
FileReader / FileWritter
텍스트 파일로 부터 문자단위로 읽을 때 사용
그림, 오디오, 비디오 등 파일은 읽기 불가능
파일을 읽어올때 파일이 존재 하지 않으면 FileNotFoundException 오류가 뜨니 예외처리를 해주자
FileReader fr = new FileReader("C:/data/test.txt");
FileReader fr = new FileReader(new File("C:/data/test.txt"));
FileWriter fw = new FileWriter("C:/data/test.txt");
FileWriter fw = new FileWriter("C:/data/test.txt", true);
보조스트림
자바의 장점!
자바가 스트림류에 특화되있어서 매우 빠름
기반 스트림을 먼저 생성한 후 이를 이용해 보조 스트림생성
( + NIO: 요즘은 잘 안쓰지만 성능을 좀더 향상시키기 위한다면 사용, 따로 공부해야함)
보조스트림의 종류
문자 변환(InputStreamReader/OutputStreamWriter),
입출력 성능(BufferedInputStream/BufferedOutputStream),
기본 데이터 타입 출력(DataInputStream, DataOutputStream),
객체 입출력(ObjectInputStream/ObjectOutputStream) 등의 기능을 제공하는 보조스트림이 있음
빨간색 하이라이트 부분만 다룰 예정..
객체 입출력은 자바의 상징적인 기능
■ 문자 변환 보조 스트림
Binary 스트림을 문자변환 보조 스트림을 통해 문자열(필요한 데이터)로 변환
■ 성능 향상 보조 스트림
입출력 소스를 그대로 사용하지않고 버퍼에 데이터 들을 모아서 한꺼번에 처리 -> 성능 향상
객체 입출력 보조 스트림
객체를 파일 or 네트워크로 입출력할수 있는 기능 제공
직렬화(Serialization) 필수!
-> 잘 안쓰는 이유.. 잘 안보인다!
Properties나 Json, XML을 사용하자
직렬화 / 역직렬화
직렬화 : Serializable 인터페이스를 implements 해서 구현
객체 직렬화 시 private 필드를 포함한 모든 필드를 바이트로 변환하지만 transient키워드를 사용한 필드는 직렬화에서 제외
◆ 자바에서 야심차게 내놨지만 잘 사용하지 않음
역직렬화: 직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스 사용 단, 클래스 이름이 같더라도 클래스 내용이 변경된 경우 역직렬화 실패
[FileBasic.java]
package com.multi.ex01.file;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
public class FileBasic {
// 파일 경로(Path)란?
// - File이 저장되어 있는 보조기억장치(HDD, SSD)의 실제 물리적인 경로(위치)
// 절대 경로 vs 상대 경로
// 1. 절대 경로 - 익숙한 것
// - Root(윈도우-'c:\', 리눅스-'\')로 부터 표기되는 절대적인 경로
// C:\dev_source\work_space_java_multi1030\13_IO\covid.txt
// c:\test\data.txt
// 빠르게 이스케이프 문자 적용하는 방법은 "" 안에 경로를 복사하는 것을 추천 ★★★★★
// 2. 상대 경로
// - 프로그램의 실행 위치(나)로부터 표기되는 상대적인 경로 '.'현재, '..'이전으로 표기되는 경로
// - os console 명령어로부터 파생된 개념
// - '.' : 현재 위치, '..' : 상위폴더(이전) 경로, './../../' 현재-상위-상위 경로
// - ex) './covid.txt', 'covid.txt', './../14_IO/covid.txt'
public static void main(String[] args) {
// 상대 경로로 열기
// File file1 = new File("./covid.txt"); // 상대 경로로 열림(open)
File file1 = new File("covid.txt"); // 파일/폴더의 경로명
// 절대 경로로 열기
// File file2 = new File("C:\\dev_source\\work_space_java_multi1030\\13_IO\\covid.txt");
File file2 = new File(file1.getAbsolutePath()); // 절대경로로 열기
// 상대, 절대 경로 출력
System.out.println(file1.getPath()); // 상대 경로
System.out.println(file2.getPath()); // 절대 경로
System.out.println(file1.getAbsolutePath()); // 상대여도 절대경로 보이는 방법
System.out.println("------------------------------------------------");
// 부모(상위 폴더)
System.out.println(file1.getParent()); // 상대경로로 읽어서 부모를 찾을수 없다.
System.out.println(file2.getParent());
System.out.println("------------------------------------------------");
// 권한 물어보기
System.out.println(file1.canRead()); // 읽기 true
System.out.println(file1.canWrite()); // 쓰기 true
System.out.println(file1.canExecute()); // 실행 true
System.out.println("------------------------------------------------");
// 권한 설정 (윈도우는 쓰기 권한만 가능)
file1.setWritable(false); // 읽기전용 만들기
System.out.println(file1.canWrite()); // 쓰기 못함
file1.setWritable(true);
System.out.println(file1.canWrite()); // 쓰기 가능!
System.out.println("------------------------------------------------");
// 파일 이름 변경
// File file = new File("./covid2.txt");
// boolean result = file1.renameTo(file);
// System.out.println(result);
// 이클립스에서 파일구조가 변경되는 경우 반드시 새로고침을 해야 반영된다. F5
// 수정된 시간 출력 -> 사용 이력
System.out.println(file1.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(sdf.format(file1.lastModified())); // 마지막 수정 시간
// 파일 길이
System.out.println(file1.length() + "byte");
System.out.println(file1.length() / 1024 + "kbyte");
System.out.println(file1.length() / 1024.0 / 1024.0 + "Mbyte");
// byte, k, M, G, T, P -> 높아짐
// 파일 삭제
// file1.delete();
// 디렉토리(폴더) 다뤄보기
File folder = new File("./");
if(folder.isDirectory()) {
System.out.println("디렉토리 입니다.");
}
// 디렉토리가 가진 자식(파일+폴더) 가져오기
System.out.println(Arrays.toString(folder.listFiles()));
System.out.println(folder.listFiles());
}
}
[StreamIO.java]
package com.multi.ex02.io_basic;
import java.io.InputStream;
import java.io.OutputStream;
public class StreamIO {
// Stream이란? - (한방향 빨대다!)
// - Binary(이진) 데이터를 다루는 Stream = 1byte씩 처리 가능
// - 활용 : 이미지나 동영상 파일, 네트워크, 프로그램간 데이터 전송 때
// IO 객체 사용시의 코딩 테크닉 - 고전 ver.
// 1. 가장 윗단에 IO객체를 선언하고, null로 초기화한다. 이름은 앞글자를 줄여서 선언한다.
// 2. try-catch문을 열고, e.printStackTrace 선언 및 finally 문 선언
// 3. IO 객체를 오픈한다. -> try안에서
// 4. 필요한 IO을 수행한다. 보통 while문으로 수행
// 5. finally에 사용한 IO객체'들'을 정리한다.
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
// is = new InputStream(); // InputStream은 abstract class라 생성 불가!
is = System.in; // open 코드를 대체하는 코드, 콘솔 입력
os = System.out; // 콘솔 출력
// 동작부
System.out.println("숫자를 입력해주세요.");
int read = is.read();
os.write(read);
// write를 강제화 하는 방법
// 1. flush : write 도중에 데이터를 강제로 밀어내는 방법, 명시적으로 사용
// 2. close : 자원을 정리하면서 flush와 동일하게 강제로 밀어내주는 기능
os.flush();
} catch (Exception e) {
e.printStackTrace(); //개발할때만 남기고 운영할땐 지우는게 좋다. 빌드버전이 되면 코딩안되게 장치해놓는게 좋음
} finally {
if(is != null) {
try {
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(os != null) {
try {
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
[StreamRW]
package com.multi.ex02.io_basic;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class StreamRW {
// reader : 문자열 단위로 읽어오는 기능
// writer : 문자열 단위로 쓰는 기능
// java에서 문자열은 2byte를 기준으로 함
// IO 객체 사용시의 코딩 테크닉 - 고전 ver.
// 1. 가장 윗단에 IO객체를 선언하고, null로 초기화한다. 이름은 앞글자를 줄여서 선언한다.
// 2. try-catch문을 열고, e.printStackTrace 선언 및 finally 문 선언
// 3. IO 객체를 오픈한다. -> try안에서
// 4. 필요한 IO을 수행한다. 보통 while문으로 수행
// 5. finally에 사용한 IO객체'들'을 정리한다.
public static void main(String[] args) {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
// open부
isr = new InputStreamReader(System.in); // InputStream를 Reader로 감싸서 연다.
osw = new OutputStreamWriter(System.out);
// System.out.println("문자열을 입력해주세요.);
osw.append("문자열을 입력해주세요.\n"); // System.out.println과 같은 스트림으로 출력한다.
osw.flush();
char[] buffer = new char[1024]; // buffer의 크기는 2의 제곱 값을 정한다. // 512, 1024 ...
int size = isr.read(buffer);
osw.append("read size : " + size +"\n");
osw.append("입력된 문자열 : " + new String(buffer) +"\n"); // char[]을 문자열로 바꾸는 방법1
osw.append("입력된 문자열 : " + String.valueOf(buffer) +"\n"); // char[]을 문자열로 바꾸는 방법2
osw.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
'자바' 카테고리의 다른 글
[Java] JDBC MVC (0) | 2023.11.30 |
---|---|
[Java] JDBC (Java DataBase Connectivity) (0) | 2023.11.29 |
[Java] Collections - Map (0) | 2023.11.23 |
[Java] Collections - List (0) | 2023.11.22 |
[Java] Colletions - Set (0) | 2023.11.22 |