본문 바로가기
언어공부/JAVA&SPRING

[패스트캠퍼스 수강 후기] 자바 인강 100% 환급 챌린지 20회차 미션

by hobbiz 2020. 8. 29.
반응형

오늘은 자바 입출력 스트림과 표준 입출력에 대해서 공부해보았다.

 

입출력 스트림이란

 

네트워크에서 자료의 흐름이 물과 같다는 의미에서 유래되었다.

 

다양한 입출력 장치에 독립적으로 일관성 있는 입출력 방식을 제공해준다.

 

입출력이 구현 되는 곳에서는 모두 I/O 스트림을 사용한다.

 

예를들면 키보드, 파일 디스크, 메모리 등이다.

 

 

 

 

 

입출력 스트림의 구분으로는

 

I/O 대상 기준 : 입력 스트림, 출력 스트림

 

자료의 종류: 바이트 스트림, 문자 스트림

 

스트림의 기능: 기반 스트림, 보조 스트림

 

이 있다.

 

 

입력 스트림은 대상으로부터 자료를 읽어들이는 스트림을 말하며,

 

출력 스트림은 대상으로 자료를 출력하는 스트림을 말한다.

 

 

바이트 단위 스트림은 바이트 단위로 자료를 읽고 쓴다. (동영상, 음악파일 등)

 

문자 단위 스트림에서 문자는 2바이트씩 처리한다.

 

 

기반 스트림은 대상에 직접 자료를 읽고 쓰는 기능의 스트림이다.

 

보조 스트림은 직접 읽고 쓰는 기능은 없지만 추가적인 기능을 제공해주는 스트림이다.

기반 스트림이나 또 다른 보조 스트림을 생성자의 매개변수로 포함한다.

 

 

Scanner 클래스는 java.util 패키지에 있는 입력 클래스이다.

 

문자 뿐 아니라 정수, 실수 등 다양한 자료형을 읽을 수 있다.

 

생성자가 다양하여 여러 소스로 부터 자료를 읽을 수 있다.

 

Console 클래스는 System.in을 사용하지 않고 콘솔에서 표준 입출력이 가능하다.

 

이클립스와는 연동되지 않는다.

 

 

<추가공부>

 

입출력 java.io 패키지

io == I/O == Input / Output

input == upload / output == download

File : java.io.File

크기, 생성, 삭제, 변경 등등 파일관련 내용을 관리 가능한 클래스

파일 관련함. File 클래스 만으로 입출력 기능 X

1) 생성자

File(String pathname) : pathname 의 완전 경로명이 나타내는 객체 생성

2) 객체 생성

File 참조변수명 = new File("파일 전체 경로");

File f = new File("c:\\Temp\\test.txt");

File 참조변수명 = new File("디렉토리경로", "파일명");

File f = new File("c:\\Temp", "test.txt");

* 파일명은 확장자까지 표기

3) 주요 메서드

리턴타입

메서드명

설명

boolean

mkdir()

새로운 디렉토리 생성

String[]

list()

디렉토리 내의 파일과 서브 디렉토리 리스트를 String 배열로 리턴

boolean

renameTo(File dest)

dest 경로명으로 파일 이름 변경

boolean

delete()

파일 또는 디렉토리 삭제

long

length()

파일의 크기 리턴

String

getPath()

파일 경로를 문자열로 리턴

String

getAbsolutePath()

절대 경로를 문자열로 리턴

String

getParent()

부모 디렉토리 이름 리턴

String

getName()

파일 또는 디렉토리 이름을 리턴

boolean

isFile()

일반 파일이면 true / 디렉토리나 다른거면 false

boolean

isDirectory()

디렉토리면 true

long

lastModified()

마지막 변경 시간 리턴

boolean

exists()

파일 또는 디렉토리가 존재하면 true

boolean

createNewFile()

빈 파일 생성. 생성하려는 파일이 이미 존재하면 생성되지 않는다.

import java.io.File; import java.io.IOException; import java.util.Date; public class IoTest01 { public static void main(String[] args) { // 경로 적을때는 역슬래시 2개 적어야 함 (이스케이프 문자 인식 방지) File f = new File("E://py//debug.log"); System.out.println(f.length()); // 파일크기 System.out.println(f.isFile()); // 파일이 맞는지 체크 System.out.println(f.getName()); // 파일명 System.out.println(f.getAbsolutePath()); //파일 전체 경로 System.out.println(f.getParent()); // 파일의 부모 디렉토리 System.out.println("숨김 속성 : " + f.isHidden()); System.out.println("읽기 속성 : " + f.canRead()); System.out.println("쓰기 속성 : " + f.canWrite()); // System.out.println(f.lastModified()); // lastModified 로 바로 출력하면 1590728734867 같이 출력됨. Date day = new Date(f.lastModified()); // Date에 해당 값을 담아서 객체 생성 후 객체를 출력하여 날짜 확인 System.out.println("마지막 수정 : " + day); // 파일 신규 생성 File f3 = new File("e:\\tmpf\\tempffff.txt"); // 만들고자 하는 파일명을 입력 try { f3.createNewFile(); //새 파일 생성. createNewFile 는 예외처리 필수 } catch (IOException e) { e.printStackTrace(); } // 폴더 내 디렉토리, 파일 리스트 가져오기 File f2 = new File("e:\\tmpf"); File[] sFiles = f2.listFiles(); for (int i = 0; i < sFiles.length; i++) { System.out.println(sFiles[i].getName()); } } }


Stream 스트림

데이터를 주고 받기 위한 통로(선) -> 데이터를 목적지로 i/o 하기 위한 방법

- 스트림은 다른 목적지로 데이터를 보낼때 가장 중요한 역할을 한다.

- 스트림은 단방향 (input과 output을 따로따로 진행해야 한다). 읽기, 쓰기가 동시에 불가능하다.

서로 대화하려면 양측 모두 i/o 쌍으로 있어야 한다

- 스트림을 안써도 되지만, 사용하면 안정성이 높아지고, 안 쓰면 응용프로그램 작성이 매우 어렵고 하드웨어 구조나 제어가 다양한 입출력 장치를 모두 수용할 수 없게 된다.

- 자바 응용프로그램은 입력스트림과 출력 스트림과만 연결하고, 입출력 장치 제어하고 실질적인 입출력을 담당하는 것은 입출력 스트림이다.

입력장치 or 파일 --> 입력 스트림 ---> 자바응용프로그램

출력장치 or 파일 <-- 출력 스트림 <--- 자바응용프로그램

- 스트림을 통해 흘러가는 기본 단위는 바이트나 문자이다.

자바 스트림 객체는 바이트 단위로 입출력하는 바이트 스트림과 문자 단위로 입출력 하는 문자 스트림으로 나뉜다.

바이트 스트림을 다루는 클래스는 공통적으로 뒤에 Stream이 붙고, 문자 스트림 클래스는 뒤에 Reader / Writer를 붙여 구분한다

- close() : 스트림을 열었으면 사용 후 반드시 닫아줘야 메모리 누수가 안된다.

- FIFO (Fisrt In First Out, Queue) 선입선출

- LIFO (Last In First Out, Stack) 후입선출


바이트 스트림

- 바이트 단위로 데이터를 전송 (바이너리 데이터가 흐르는 스트림) -> 1byte

- 다양한 클래스 제공으로 용도에 맞게 골라 사용

- 이미지, 동영상 전송 가능

1) InputStream, OutputStream

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

2) FileOutputStream

파일에 출력을 하기 위한 클래스로 파일에 바이너리 데이터를 저장 할 수 있다.

바이너리 파일은 사람이 읽고 해석하는 것이 거의 불가능하다.

프로그램 내에 변수나 배열에 들어있는 바이너리 값을 그대로 파일에 저장하는 경우로, 메모리에 있는 이미지 비트들을 그대로 이미지 파일로 저장하는 경우 등에 사용한다.

1. 생성자

FileOutputStream(File file) : file이 지정하는 파일에 출력하는 스트림을 생성함

FileOutputStream(String name) : name이 지정하는 파일에 출력하는 스트림을 생성함

FileOutputStream(File file, boolean append) : file이 지정하는 파일에 출력하는 스트림을 생성함. 스트림을 생성할때에 append가 true 이면 기존 파일 마지막부터 데이터 저장 (이어쓰기), false면 덮어 쓰기

2. 주요 메서드

리턴타입

메서드명

설명

void

write(int b)

int형으로 넘겨진 한 바이트 출력

void

write(byte[] b)

배열 b의 바이트를 모두 출력

void

write(byte[] b, int off, int len)

len의 크기만큼 off 부터 배열 b를 출력

void

flush()

출력 스트림에 남아 있는 바이너리 데이터를 모두 출력시킴

void

close()

출력 스트림을 닫고 관련된 시스템 자원 해제

import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.Scanner; public class FileOut02 { public static void main(String[] args) { String file, str; // file : 파일명, str : 저장할 내용 Date date = new Date(); Scanner sc = new Scanner(System.in); str = "파일 생성 시간 \n" + date + "\n"; System.out.println("파일 이름을 입력하세요 : "); file = sc.nextLine(); System.out.println("저장할 문자열을 입력하세요 : "); str += sc.nextLine(); // FileOutputStream은 write()에 byte 로 받기 때문에 위 저장할 문자열을 byte로 변환해서 던져줘야함. byte[] b_str = str.getBytes(); //getBytes() string을 byte[] 로 변환 // 스트림 만들기 FileOutputStream fos = null; try { // 스트림 객체 생성 fos = new FileOutputStream("e:\\tmp\\" + file); // 스트림으로 출력 fos.write(b_str); System.out.println("파일 생성 성공"); } catch (Exception e) { e.printStackTrace(); } finally { // 출력 후 스트림 닫기 if (fos != null) { //null이면 객체가 생성되지 않았으므로 굳이 닫을 필요 없다. try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } sc.close(); } } }

3) FileInputStream

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

1. 생성자

FileInputStream(File file) : file이 지정하는 파일로부터 읽는 스트림을 생성함

FileInputStream(String name) : name이 지정하는 파일로부터 읽는 스트림을 생성함

2. 주요 메서드

리턴타입

메서드명

설명

int

read()

입력스트림에서 한 바이트를 읽어 int 형으로 리턴

int

read(byte[] b)

최대 배열 b의 크기만큼 바이트를 읽음.

읽는 도중 EOF를 만나면 실제 읽은 바이트 수 리턴

int

read(byte[] b, int off, int len)

최대 len개의 바이트를 읽어 off 위치 부터 배열 b를 저장

int

available()

현재 읽을 수 있는 바이트 수 리턴

void

close()

입력 스트림을 닫고 관련된 시스템 자원 해제

* EOF : End Of File 파일의 끝 : read() 할때 EOF를 만나면 -1을 리턴한다.

read()의 EOF 시 0xFF(-1) 리턴. read 내에 읽은 값이 -1 이면 0x000000FF 으로 리턴하므로 읽기 종료인지 단순 데이터가 -1인지 구분 할 수 있다.

byte 타입 -1 0xFF, int 타입 -1 0x000000FF

import java.io.FileInputStream; import java.io.IOException; public class FileIn01 { public static void main(String[] args) { // "e:\\tmp\\test.out" byte[] b = new byte[5]; FileInputStream fin = null; try { // 1. 읽어 올 스트림 객체 생성 fin = new FileInputStream("e:\\tmp\\test.out"); // 2. 파일 읽기 // 한바이트 씩 읽기 /* int n = 0; // 배열 index로 취급할 변수 int c; // 읽은 파일 임시 저장할 변수 while ((c = fin.read()) != -1) { //읽은 값이 -1이 아닐때까지 반복 b[n] = (byte)c; n++; } */ // 한번에 읽기 fin.read(b); // 3. 결과 출력 for (int i = 0; i < b.length; i++) { System.out.print(b[i] + " "); } System.out.println(); } catch (Exception e) { e.printStackTrace(); } finally { try { fin.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

4) DataInputStream, DataOutputStream

기본 타입의 값을 출력/가져올 때 사용하는 클래스 (잘 쓰지 않는다)

기본 타입별 메서드가 존재한다.


문자 스트림

2바이트의 유니코드 문자를 단위로 입출력하는 스트림

- 자바에서는 char 형이 2byte 이기 때문에 한글과 같은 2byte 문자는 바이트 스트림으로 전송시 깨지는 경우가 있다. 이러한 점을 보안하기 위해 문자 스트림이 제공된다.

- 문자화되지 않는 바이너리 바이트 값들을 처리할 수 없다. -> 이미지, 동영상 같은 것 처리 불가

1) Reader / Writer 클래스

추상 클래스. 문자 스트림 클래스들의 조상

2) InputStreamReader

바이트 스트림을 문자 스트림으로 연결시켜주는 역할을 하는 FileInputStream의 보조 클래스. (FileInputStream이랑 같이 써야한다)

1. 생성자

InputStringReader(InputStream in) : OS에서 사용하는 기본 인코딩의 문자로 변환하는 스트림 생성

InputStringReader(InputStream in, String charsetName) : charsetName으로 지정한 인코딩의 문자로 변환하는 스트림 생성

2. 메서드

리턴타입

메서드명

설명

String

getEncoding()

스트림의 인코딩을 리턴

## 윈도우 기본 인코딩

MS949 : 1987년 한글 국가 표준 코드로 지정된 KSC5601을 마소사에서 확장하여 MS949라고 불리는 코드 체계를 만들고 윈도우에 기본코드로 사용하고 있다. 자바는 전 세계의 문자를 표현하기 위해 만들어진 유니코드를 사용하므로, 메모장 같이 윈도우에서 작성된 한글 텍스트 문서를 자바 프로그램에서 읽으려면 encoding을 MS949로 지정해야 한다.

import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class InputReader01 { public static void main(String[] args) { //Input Stream Reader : 바이트 스트림 -> 문자 스트림 FileInputStream fin = null; InputStreamReader in = null; try { // 1. 바이트 스트림 읽어 올 파일 던지며 객체 생성 fin = new FileInputStream("e:\\tmp\\nyang.out"); // 2. 문자 스트림으로 포장 in = new InputStreamReader(fin); // in = new InputStreamReader(fin, "MS949"); //인코딩 지정 System.out.println("encoding : " + in.getEncoding()); int c = 0; while( (c = in.read()) != -1) { System.out.print((char)c); } } catch (Exception e) { e.printStackTrace(); } finally { // 스트림 둘다 닫기 try { fin.close(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }

3) OutputStreamWriter

파일에 텍스트 데이터를 저장할 때 생성자 호출시 인코딩 지정하여 처리

인코딩 지정하지 않으면 os에서 사용하는 기본 인코딩으로 데이터 저장

1. 생성자 (위에랑 동일)

2. 메서드

리턴타입

메서드명

설명

String

getEncoding()

스트림의 인코딩을 리턴

void

flush()

스트림 비워주기 (닫기 전에)

 

import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.util.Date; import java.util.Scanner; public class OutWriter01 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Date date = new Date(); String str = "파일 생성시간 : " + date + "\n"; System.out.println("저장할 내용 입력 : "); str += sc.nextLine(); FileOutputStream fos = null; OutputStreamWriter out = null; try { // 바이트 아웃풋 스트림 객체 생성 fos = new FileOutputStream("e:\\tmp\\nyangi.out"); // 문자 아웃풋 스트림으로 포장 out = new OutputStreamWriter(fos, "UTF-8"); out.write(str); // String 던져서 쓰기 out.flush(); // stream 비우기 } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { // null 체크 해주는 것이 좋은 쿼리 try { fos.close(); } catch (Exception e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (Exception e) { e.printStackTrace(); } } } } }

출처:https://blog.naver.com/akilia/221986300767

 

 

패스트캠퍼스 강의 : https://bit.ly/3ilMbIO

 

Java 웹 개발 마스터 올인원 패키지 Online. | 패스트캠퍼스

자바 기초문법부터 프로젝트 실습까지 Java 문법부터 스프링/스프링부트, 트렌디한 기술인 JPA까지 모두 배우는 온라인 강의입니다.

www.fastcampus.co.kr

 

 

반응형

댓글