JAVA - I.O(입출력) > 보조 스트림

보조 스트림

스트림의 기능을 향상시키거나 새로운 기능을 추가하기 위해 사용

보조 스트림은 실제 데이터를 주고 받는 스트림이 아니기 때문에 입출력 처리 불가능

무조건 기반스트림을 먼저 생성한 후 보조스트림 생성하여야한다.

 

보조 스트림 종류

1. 문자 변환 - InputStreaReader, OutputStreamWriter

2. 입출력 성능 - BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter

3. 기본 데이터 타입 출력 - DataOutputStream, DataInputStream

4. 객체 입출력 - ObjectOutputStream, ObejectInputStream;

 

이렇게 보조스트림이 존재한다.

 

사용 예시

FileInputStream fis = new FileInputStream("test.txt"); // 1. 기반 스트림 생성
BufferedInputStream bis = new BufferedInputStream(fis); // 2. 보조 스트림 생성
bis.read(); // 보조스트림 참조변수 이용하여 데이터 읽어오기

 

문자 변환 스트림

소스 스트림이 바이트 기반 스트림 이지만 데이터가 문자일 경우 사용한다

Reader와 Writer는 문자단위로 입출력을 하기 때문에 데이터가 문자인 경우

바이트 기반 스트림보다 편리하게 사용가능

 

InputStreamReader

System.in, System.out

JVM이 자동으로 스트림을 제공해줌 직접 스트림 생성없이 편하게 사용가능

 

아래 예제는 Scanner 사용과 같은 메소드이다

Scanner 클래스가 나오기전엔 아래와같이 사용했다고한다..

세상편해졌네 ..

public void input(){
	// 보조스트림은 한개만 사용가능한것이아니라 여러개 붙여서 사용가능
	InputStreamReader is = new InputSreamReader(System.in); //보조스트림
    // 한줄씩 읽어오기 위해 BufferedReader 사용
    BufferedReader br = new BufferedReader(is);
    
    try{
    	System.out.print("값 입력 : ")
        String value = br.readLine(); // 입력받은값 한줄 읽어오기 
        System.out.println("입력 받은 값 : " + value); // 
        
    }catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				// 보조 스트림을 닫으면 연결 된 기반 스트림도 닫힘
				// 표준 입출력 스트림의 경우 시스템에서 연 스트림으로
				// 닫고나서 다시 열 수 없음에 유의
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    

}

 

OutputStreamWriter

화면에 값 출력하기

public void output() {
		// 보조 스트림을 생성할 때는 매개변수로 기반 스트림 사용 -> OutputStream
		OutputStreamWriter osw = new OutputStreamWriter(System.out);
		// 보조 스트림을 하나 더 사용 -> BufferedWriter
		BufferedWriter bw = new BufferedWriter(osw);
		
		try {
			String str = "Hello";
			bw.write(str);
			// write() : 버퍼에 쌓는다.
			// flush() : 내보낸다.
//			bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

 

 

성능 향상 보조 스트림

느린 속도로 인해 입출력 성능에 영향을 미치는 입출력 소스를 이용하는 경우 사용

입출력 소스와 직접 작업하지 않고 버퍼에 데이터를 보아 한꺼번에 작업을 하여 실행 설능 향상

 

원래 Reader클래스의 read() 메소드 사용하면 한문자만 읽어오는데

BufferedReader 클래스의 readLine() << 이용하면 한줄씩 읽어오기가능하다

이래서 보조스트림을 쓰는건가 ..너무편함 ..

 

일단 Writer 로 생성하고 

Reader로 읽어와보겠습니다.

 

BufferedWriter

public void save() {
		
		// 아래 try() {} 는 스트림을 사용하다보면 close() 하는작업이있는데
		// JDK1.7부터는 아래와 같은형식으로 작성해주면 close() 작성할필요가없다.
		/*
		 * 아래 코드를 풀어써보자면
		 * FileWriter fw = new FileWriter("test.txt);
		 * BufferedWriter bw = new BufferedWriter(fw);
		 * 이런형식이라 줄여서 한줄로 작성함
		 * */
		
		try(BufferedWriter bop = new BufferedWriter(new FileWriter("test.txt"))){
			bop.write("하나둘 테스트");
			bop.write("\n"); // 엔터처리
			bop.write("둘셋 테스트");
			bop.newLine(); // 엔터처리
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

실행하게 되면 아래와같은 txt파일 생성됨

 

BufferedReader

public void read() {
		
		try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))){
			// 한줄씩 읽어오는방법
			// br.readLine(); << 보조스트림 메소드
			// 만약 읽어올 문자가없다면 null 반환
			
			//반복문으로 여러줄있을때 읽어오는 방법
			String value = ""; 
			while((value = br.readLine()) != null) { //null이 아니면 무한 반복
				System.out.println(value); //값 출력
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

출력

 

기본 타입 입출력 보조 스트림

이 보조 스트림은 기본자료형(boolean, char, byte, short, int, long, float, double) + 참조자료형(String) 총 9가지가 제공된다.

원하는형식의 데이터를 추가, 읽어오기 할수있다.

 

DataOutputStream

public void save() {
		//DataOutputStream / DataInputStream ; 데이터 입출력 보조 스트림
		try(DataOutputStream dos = new DataOutputStream(new FileOutputStream("Date.dat"))){
			// DataOutputStream 보조스트림이용하여 Date.dat 생성 
			// 확장자 .dat는 그냥 데이터만 보관하는 파일이다.
			
			// 입력메소드 
			dos.writeUTF("홍길동"); // String형식 데이터
			dos.writeInt(20); // int형식 데이터
			dos.writeChar('M'); //char형식 데이터
			dos.writeUTF("김길동"); // String형식 데이터
			dos.writeInt(21); // int형식 데이터
			dos.writeChar('F'); //char형식 데이터
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

 

 

사용되는 메소드는 아래와같다

String타입은 writeUTF 사용하면된다.

 

위의 메소드 실행시 출력

아래와 같이 영어로 입력을안하면 이상한언어로 표시된다.

굳이 ..해석할 노력은하지말자 ..!

 

 

DataInputStream

public void read() {
		
		try(DataInputStream dis = new DataInputStream(new FileInputStream("Date.dat"))){
			// 데이터를 가져올때는 순서대로의 데이터타입으로 무조건가져와야한다.
			// 그렇지않을시 이상한값이 출력된다.
			// 현재 저장된 순서는 String, int, char 형식이다.
			System.out.println(dis.readUTF());
			System.out.println(dis.readInt());
			System.out.println(dis.readChar());
			System.out.println(dis.readUTF());
			System.out.println(dis.readInt());
			System.out.println(dis.readChar());
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

 

 

객체 타입 입출력 보조스트림

객체타입으로 데이터를 주고받을수있는 스트림 

객체지향단위로 파일을 저장할때 편한다.

 

객체타입 입출력에 사용될 Student.class

public class Student {
	private String name;
	private int kor;  // 국어점수
	private int eng;  // 영어점수
	private int math; //수학점수
	
	// 기본생성자
	public Student() {}

	public Student(String name, int kor, int eng, int math) {
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.math = math;
	}

	
	//getter/setter
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	
	@Override
	public String toString() {
		return "Student [name=" + name + ", kor=" + kor + ", eng=" + eng + ", math=" + math + "]";
	}
	
	
	
	
	
	
	
}

 

ObjectOutputStream

public void save() {
		try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.dat"))){
			
			// 3개정도 데이터 입력
			// 객체타입을 입력할때는 writeObject(obj) 메소드 사용
			oos.writeObject(new Student("홍길동",80,80,80));
			oos.writeObject(new Student("김길동",50,50,50));
			oos.writeObject(new Student("강길동",60,60,60));
			
			//또는 객체 배열로 입력
			Student[] stArr = new Student[3];
			stArr[0] = new Student("파이리",10, 10, 10);
			stArr[1] = new Student("꼬부피",20, 20, 20);
			stArr[2] = new Student("피카츄",30, 30, 30);
			oos.writeObject(stArr);
			
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

이런식으로넣었을때 아마 오류가있을것이다 .

 

 

NotSerializableException

에러가발생할것이다.

이에러는 파일에 넣엇을때 UID라는 고유번호를 지정하지않아생기는 오류이다.

 

간단하게 해결할려면 현재 Student 클래스 이용하여 하고있으니깐 

Student 클래스 파일 오픈하고 아래와같이 implements Seriallizable 추가해주면된다.

 

데이터 출력 성공

 

 

ObjectInputStream

public void read() {
		try(ObjectInputStream dis = new ObjectInputStream(new FileInputStream("student.dat"))){
			// 데이터 한개씩 뽑아오기
			Student st1 = (Student) dis.readObject(); //형변환 하는이유  Object형식으로 넘어오기때문에 원하는형식으로 강제형변환 필요
			Student st2 = (Student) dis.readObject();
			Student st3 = (Student) dis.readObject();
			System.out.println("===== 객체 타입으로 뽑아오기 =====");
			System.out.println(st1);
			System.out.println(st2);
			System.out.println(st3);
			System.out.println();
			
			// 반복문으로 뽑아오기
			System.out.println("===== 반복문으로 뽑아오기 =====");
			for(int i = 0; i < 3; i++) {
				Student st = (Student) dis.readObject();
				System.out.println(st);
			}
			System.out.println();
			
			//객체배열로 뽑아오기
			Student[] stArr = new Student[3];
			stArr = (Student[])dis.readObject(); //형변환을 배열로 한이유가 처음에 넘겨준값이 Student[] 값이기 때문에 배열로받았다.
			//향상된 for문 사용
			System.out.println("===== 객체배열로 뽑아오기 =====");
			for(Student s : stArr) {
				System.out.println(s);
			}
			
			
			
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

출력

 

 

 

너무너무 좋은기능들인것같다

지금상황에 입출력 배운것은 너무너무좋은거같다

현재 sql이나 데이터베이스쪽 배우지않을상태에서

입출력으로 약간 저장 가져오기 할수있어좋을거같다.

 

자바는뭔가 .. 갈수록좀 복잡해진다고해야하나..

뭔가 편해지고 좋은데 갈수록 외워야할게많다보니깐 ..

뭔가좀 복잡해지는느낌 ..그래서 .. 

복습복습 무조건복습이라생각한다.

너무어렵고~

 

'프로그래밍 > JAVA' 카테고리의 다른 글

JAVA - 정렬(Comparable, Comparator)  (0) 2021.06.08
JAVA - 컬렉션 프레임워크  (0) 2021.06.07
JAVA - I.O(입출력) > 기반 스트림  (2) 2021.06.03
JAVA - 예외처리  (0) 2021.06.03
JAVA - DATE, Calendar,  (0) 2021.06.02
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유