basic/java 이론

day 19 - [입출력-java.io] File, FileOutput/FileInputStream Class, Output/InputStreamReader Class, Thread

못지(Motji) 2021. 5. 20. 17:06

입출력 java.io package

io = I/O = Input/Output

File Class

📑 java api 바로가기 ▸ File

  • 크기, 생성, 삭제, 변경 등등 내용 전부 관리 가능
  • 업로드 파일, 다운로드 파일 등 가장 많이 사용되는 입출력 대상으로 파일 클래스 역할이 중요함
  • 출력 기능은 없음

👀 ex)

더보기
파일 속성 클릭했을시 나오는 내용들을 File Class에서 전체 관리 가능하다

✔ 생성자

  • File(File parent, String chiled)
    parent 디렉토리에 child이름으로 서브 디렉토리나 파일을 나타내는 객체 생성
  • File(String pathname)
    전체경로주고 그에 해당하는 객체 생성
  • File(String parent, String chiled)
    parent 디렉토리에 child이름으로 서브 디렉토리나 파일을 나타내는 객체 생성
  • File(URI uri)
    file:URI를 추상경로명으로 변환하여 객체 생성

✔ 객체 생성

* 파일명은 확장자까지 기술한다.

  • File 참조변수명 = new File("전체경로");
    File f = new File("D:\\dandico\\test.txt"); > 윈도우에서의 경로 D:\dandico\test.txt
  • File 참조변수명 = new File("디렉토리경로", "파일명");
    File f = new File("D:\\dandico", "test.txt");

✔ 주요 메소드

리턴타입 메소드명 설명
boolean makdir() 새로운 디렉토리 생성
String[] list() 디렉토리내의 파일과 서브디렉토리 리스트를 String 배열로 리턴
File[] listFiles() 디렉토리내의 파일과 서브디렉토리 리스트를 File 배열로 리턴
boolean renameTo(File dest) dest 경로명으로 파일이름 벼경
boolean delete() 파일 또는 디렉토리 삭제
long length() 파을의 크기 리턴
String getPath() 경로 문자열로 리턴
String getAbsolutePath() 절대경로를 문자열로 리턴
String getParent() 파일 이나 디렉토리의 부모 디렉토리 이름 리턴
String getName() 파일 또는 디렉토리의 이름 문자열로 리턴
boolean isFile() 일반 파일이면 true
boolean isDirectory() 디렉토리면 true
long lastModified() 마지막 변경 시간 리턴
boolean exists() 파일 또는 디렉토리가 존재하면 true
boolean createNewFile() 빈 파일 생성, 생성하려는 파일이 이미 존재하면 생성이 안됨

Stream 스트림

  • 연속적인 데이터의 흐름 데이터가 돌아다니는 통로(선)  데이터를 목적지로 I/O하기위한 방법
  • Stream은 다른 목적지로 데이터를 보낼때 가장 중요한 역할을 함
  • Stream 없으면 그냥 무작위로 던지는 방식: wifi
    Stream 있는 방식 : LAN선
  • Stream은 단방향 (input과 output을 따로따로 진행해야함)
    서로 대화 하려면 양측 모두 I/O 쌍으로 있어야 함
    읽기 쓰기가 동시에 안됨
  • Stream을 안써도 되지만 쓰면 안정성이 높고 안쓰면 응용프로그램 작성이 매우 어려우며
    하드웨어 구조나 제어가 다양한 입출력 장치를 모두 수용할 수 없게됨
  • 자바 응용프로그램은 입력스트림과 출력스트림과만 연결하고,
    입출력장치 제어하고 실질적인 입출력을 담당하는 것은 입출력 스트림
    ✍🏻 ex)
    입력장치 or 파일 ------▸ 입력 스트림 -----▸ 자바 응용프로그램
    출력장치 or 파일 ◂------ 출력 스트림 -----▸ 자바 응용프로그램
  • Stream을 통해 흘러가는 기본단위는 바이트나 문자이다
    자바 스트림 객체는 바이트 단위로 입출력하는 바이트 스트림과
    문자단위로 입출력하는 문자 스트림으로 나뉜다.
    바이트 스트림을 다루는 클래스는 공통적으로 뒤에 Stream이 붙고,
    문자 스트림을 다루는 클래스는 뒤에 Reader/Writer가 붙어 구분 가능
  • close(): 스트림을 열었으면 사용 후 반드시 닫아줘야 메모리 누수가 안됨

💡 FIFO First In First Out, Queue: 선입선출
💡 LIFO Lask In First Out, Stack: 후입선출

✔ 바이트 스트림

  • 바이트 단위로 데이터 전송 ▹ 1byte (데이터만 보자면 1byte > 이것의 정보 이것저것 해서 +1byte 약2byte )
  • 다양한 클래스 제공으로 용도에 맞게 골라서 사용
  • 이미지, 동영상 전송 가능

InputStream, OutputStream Class

추상 클래스 바이트 입출력 처리를 위한 공통기능을 가진 수퍼클래스

FileOutputStream Class

📑 java api 바로가기 ▸ FileOutputStream

  • 파일에 출력을 하기 위한 클래스
  • 파일에 바이너리 데이터를 저장할 수 있다.
  • 바이너리 파일은 사람이 읽고 해석하는 것이 거의 불가능

생성자 (java api문서 참고)

  • FileOutputStream(File file): file이 지정하는 파일에 출력하는 스트림 생성
  • FileOutputStream(String name): name이 지정하는 파일에 출력하는 스트림 생성
  • FileOutputStream(File file, boolean append): file이 지정하는 파일에 출력하는 스트림 생성 append가 true이면 파일 마지막부터 데이터 저장 (이어서 출력)

주요 메소드

리런타입 메소드명 설명
void write(int b) int형으로 넘겨진 한 바이트 출력
void write(byte[] b) 배열 b의 바이트를 모두 출력
void write(byte[] b, int off, int lne) len의 크기만큼 off부터 배열 b를 출력
void flush() 출력스트림에 남아있는 바이너리 데이터 모두 출력
void close() 스트림닫고 관련된 시스템 자원 해제

FileInputStream Class

📑 java api 바로가기 ▸ FileInputStream

  • 바이트 스트림으로 파일 읽는 스트림 클래스

 생성자 (java api문서 참고)

 주요 메소드

리턴타입 메소드명 설명
int read() 입력스트림에서 한바이트를 읽어 int형으로 리턴
int read(byte[] b) 최대 배열b의 크기만큼 바이트를 읽음
읽는도중 EOF를 만나면 실제 읽은 바이트수 리턴
int read(byte[] b, int off, int lne) 최대 len개의 바이트를 읽어 b배열의 off 위치부터 저장
int available() 현재 읽을 수 잇는 바이트수 리턴
void close() 스트림 닫고 관련된 시스템 자원 해제

💡 EOF : End Of File 파일의 끝▸read() 할때 EOF를 만나면 -1을 리턴함

❔❓read() 의 리턴이 int형인 이유

  1. read()는 한 바이트나 한 문자를 리턴하므로 리턴타입이 byte 혹은 char인것이 합당한데
    왜 int?
  2. read()가 스트림의 끝 혹은 파일의 끝을 만나면 -1을 리턴하는데
    스트림이나 파일에 -1값이 있다면 이둘을 어떻게 구분하나?
  3. 스트림이나 파일에 -1(0xFF)ㅇ 있다고 하면 read() 0xFF를 리턴한다
    byte의 -1을 int 타입으로 리턴하면 0xff우ㅏ 32비트 0x000000FF를 리턴
    EOF를 알리는 리턴값인 int의 -1은 0xFFFFFFFF이다
    두개의 값이 다르기 때문에 차이가 명확해진다

DataOutputStream Class

📑 java api 바로가기 ▸ DataOutputStream

  • boolean, char, byte, short... 기본 타입의 값을 바이너리 형태로 출력

DataIntputStream Class

📑 java api 바로가기 ▸ DataInputStream

  • 바이너리 형태를 기본타입으로 읽어옴
  • 각 자료형의 크기가 다르므로 출력한 데이터를 다시 읽어올때는 순서가 바뀌면 안됨
  • readXXX() : 더 이상 읽을 값이 없으면 EOFExceptionkfrod

ObjectOutputStream/ObjectInputStream Class

객체를 출력/입력하는데 사용하는 클래스

 문자스트림

  • 자바에서는 char형이 2byte이기 때문에 한글과 같은 2byte문자는 바이트 스트림으로 전송시 깨지는 경우가 있다.
    이러한 점을 보완하기 위해 문자 스트림이 제공됨
  • 2byte의 유니코드 문자를 단위로 입출력하는 스트림
  • 문자화되지 않는 바이너리 바이트값들을 처리 불가 ▸ 이미지같은것 처리 불가 
  • InputSTream  "Reader" / OutputStream ▸"Writer"
  • method를 잘보면 byte[] 대신 char[]를 사용하는 것을 볼 수 있음
  • 바이크 스트림과 이름과 다를뿐 활용법은 거의 같음

Reader / Writer Class

추상클래스 문자 스트림들의 부모

InputStreamReader Class

📑 java api 바로가기 ▸ InputStreamReader

  • 바이트 스트림을 문자 스트림으로 연결시켜주는 역할을 하는 보조 클래스
  • 바이트 스트림의 데이터를 지정된 인코딩의 문자 데이터로 변화해즌

✔ 생성자

  • InputStreamReader (InputStream in)
    in == 바이트스트림계열 객체, OS에서 사용하는 기본 인코딩의 문자로 변환하는 스트림 생성
  • InputStreamReader (InputStream in, String charset)
    지정된 인코딩을 사용하는 스트림 생성

✔ 주요 메소드

리턴타입 메소드명 설명
String getEncoding() 스트림의 인코딩을 리턴

📝 윈도우에서 기본으로 사용하는 인코딩

MS949 : 1987년 한글 국가 표준 코드로 지정된 KSC5601 마이크로소프트사에서 확장하여 MS949라고 불리는 코드체계를 만들고 윈도우에 기본코드로 사용하고 있다.

OutputStreamWriter Class

📑 java api 바로가기 ▸ OutputStreamWriter

  • 파일에 텍스트 데이터를 저장할 때 인코딩 지정하며 저장처리 가능

💡 OS : 운영체제, 하나의 소프트 웨어로, 소프트 웨어들을 관리하는 소프트웨어 (App)

Windoes, Android, macOS, iOS, Linux

자바 플랫폼 > JVM : 자바 App을 관리하는 소프트웨어


📌 프로세스 process

  • 현재 실행중인 프로그램
  • 프로세스 = 데이터와 메모리등의 자원 + 스레드
  • 싱글 프로세스 : 하나의 프로그램을 돌리기 위해 1개의 프로세스가 실행
  • 멀티 프로세스 : 하나의 프로그램을 돌리기 위해 여러개의 프로세스가 실행되는 것
    eclipse.exe, javaw.exe

📌 멀티 태스킹 (multitasking)

  • 태스크 tesk : 프로세스가 하는일
  • 태스킹 : 프로세스가 일을 하는것
  • 멀티태스킹 : 하나의 프로세스가 여러일을 하는것, 작업을 동시에 여러개 하는것

📌 thread 스레드

  • 하나의 태스크를 수행하는 아이
  • 프로세스 = 공장(자원+일꾼), 스레드 = 일꾼
    싱글스레드 = 자원 + 일꾼(스레드)
    멀티스레드 = 자원 + 일꾼 + 일꾼 + ⋯
  • 현재 사용하는 OS는 멀티태스킹을 지원하므로 여러개의 스레드가 동시 실행될 수 있음

📌 멀티태스킹과 멀티스레딩

멀티 태스킹을 실현하기 위한 두가지 방법

  • 멀티 프로세싱 : 하나의 응용프로그램을 여러개의 프로세스로 구성
    ▹ 각 프로세스가 하나의 작업을 처리하도록
    ▹ 단점 : 프로세스간 변수 공유X 프로세스사이 통신 어렵고 문맥교환에 따른 과도한 작업량
  • 멀티 스레딩 : 하나의 응용프로그램을 동시 처리가능하게 작업을 분할하고 작업의 개수만큼 스레드를 생성
    ▹ 스레드 하나당 하나의 작업처리하게 함
    ▹ 자원과 메모리 공유, 문맥교환 빠름

멀티 스레딩 활용 분야

  • 웹서버 시스템
  • 워드

📌 자바의 멀티스레딩

  • 멀티 스레드와 JVM
    ▹ JVM은 멀티스레딩만 지원
  • 자바 스레드와 JVM
  • 응용프로그램과 스레드 관련된 것들의 관계
    ▹TCB

Thread 스레드 만들기

  • 개발자가 할일
    스레드 코드 작성
    JVM에게 스레드 생성하고 코드 실행하도록 요청
  • 구현방법
    Thread 클래스 상속 : 많이 사용
    Runnable 인터페이스 구현

Thread 클래스 상속받아 스레드 만들기

📑 java api 바로가기 ▸ Thread

✔ 생성자 java api 문서 참고

✔ 주요메소드

void run() JVM에 의해 호출 (핵심메소드)
개발자는 반드시 이 메소드를 오버라이딩하여 스레드 코드 작성해야함
메소드가 종료하면 스레드가 종료
void start() JVM에게 스레드 실행하도록 요청
void interrupt() 스레드 강제종료
static void yield() 다른 스레드에게 실행을 양보
이때 JVM은 스레드 스케줄링을 실행하며 다른 스레드를 선택하여 실행시킴
void join() 스레드 종료할 때까지 기다림
long getId() 스레드의 id값 리턴
String getName() 스레드의 이름 리턴
int getPriority() 1~10 스레드의 우선순위값 리턴
void setPriority(Int n) n값으로 스레드 우선순위 바꿔줌
Thread.State getState() 스레드의 상태값 리턴
기다리고 있는중인지 실행중인지
static void sleep(long millis) millis 시간동안 스레드 잔다
static Thread curruntThread() 지금 돌아가는 스레드가 뭔지 알려줌 리턴해줌

✔ 사용법

#1) 스레드 클래스 작성

class 클래스명 exrends Thread{
	@Override
    public void run(){
    	#2) 스레드 코드 작성
        ...
    }
}

❗ run 오버라이딩 안하면 기본메소드가 실행되어 아무일도 안함.

#3) 스레드 객체 생성

클래스명 참조변수명 = new 클래스명();

#4) 스레드 시작

참조변수명.start();

start() 메소드는 오버라이딩 금지

Runnable 인터페이스로 스레드 만들기

📑 java api 바로가기 ▸ Runnable

  • 추상메소드 run()한개만 가지고 있음

✔ 사용법

#1)  스레드 클래스 선언 : Runnable 인터페이스 구현

class 클래스명 implements Runnable{
	#2. 스레드 코드 작성 : run 오버라이딩
    @Override
    public void run(){
    	///
    }
}

#3) 스레드 객체 생성

Thread th = new Thread(new 클래스명());

#4)  스레드 시작

th.start();