gwooden_코린이

java_입출력스트림_221207(13일차) 본문

java/13일차

java_입출력스트림_221207(13일차)

gwooden22 2022. 12. 7. 09:46
728x90

1. 입출력 스트림  

(입출력을 한번에 처리해주는 스트림이 없어서 따로 처리해줘야 된다.)

 

큐 -> FIFO

먼저 들어간게 먼저 나오는 형식

 

스택 -> FILO 또는 LIFO

먼저 들어간게 제일 마지막에 나오는 형식

 

단향방 : 한쪽 방향으로만 처리가 가능한 방식 (입력 밖에 못함)

              출력을 하고 싶으면 출력 스트림이 따로 있어야 됨

반이중 : 하나의 통로로 입출력이 가능하지만 동시에 처리 불가 (대표적인 예 : 무전기)

전이중 : 주고 받고 다 되는 방식 (대표적이 예 : 인터넷, 채팅 등)

입력
ex)
키보드, 마우스
입력 스트림
--------->
->(도착치)
프로그램
(출발지)->
출력 스트림
--------->
출력
ex)
모니터, 프린터

 

바이트 기반 처리 : 영상, 음악, 그림, 사진

InputStream, OutpurStream

문자 기반 처리 : 문자열 (글자를 처리할 때 사용)

Reader, Writer

 


.read()는 1byte 정수를 가지고 온다.


.read(byte[] b) : 배열 b의 크기만큼 읽어오다가 데이터 -1이 됐을때 리턴

(앞에서 부터 순차적으로 채워주는 방식)

 

.read(byte[] b, int off, int len) : 최대 len만큼 바이트를 읽음 배열 b[off]에서 부터 저장

(int off에 넣어줄 위치를 설정할 수 있다)

 

.close() : 스트림 닫아주는 메서드

데이터가 열려있으면 메모리 관리가 어려워 열려있는 데이터를 닫은 상태로 다른 코드가 이루어져야 메모리 관리에 효율적이다.

 

- 인풋

package kjh221207;

import java.io.FileInputStream;

public class Sample02 {

	public static void main(String[] args) {
		
		try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
			FileInputStream fis = new FileInputStream("src/kjh221207/Sample01.java");
					
				int data = 0; //종료시키게 하기 위한 변수 하나 선언
				
				//.available() <-- 경로가 담긴 변수를 배열을 설정한 [] 괄호안에 넣은수 해당 메서드를 붙이면 변수안에 있는 데이터만큼 배열방이 자동으로 설정됨
				byte[] buf = new byte[fis.available()]; 
				
				//.read() <-- 괄호안에 자료형 타입, 변수를 넣어서 할수도 있다.
				while((data=fis.read(buf)) != -1) {
					//new String(buf, 0, data) <-- 몇번째 배열방 부터 읽어올건지 지정
					System.out.print(new String(buf, 0, data));
				}
		} catch(Exception e) {
			
		}

	}

}

package kjh221207;

import java.io.FileInputStream;

public class Sample02 {

	public static void main(String[] args) {
		
		try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
			FileInputStream fis = new FileInputStream("src/kjh221207/Sample01.java");
					
				int data = 0; //종료시키게 하기 위한 변수 하나 선언
				
				
				//.available() <-- 해당 메서드는 경로가 담긴 변수에 배열방을 자동으로 설정해줌
				byte[] buf = new byte[fis.available()]; 
				
				System.out.println("크기 : " + fis.available());
				
				//.read() <-- 괄호안에 자료형 타입, 변수를 넣어서 할수도 있다.
				//.read(buf, 0, buf.length) <-- (배열변수에서, 몇번째 방부터 , 몇번째 방까지 불러오는 설정)
				while((data=fis.read(buf, 0, buf.length)) != -1) {
					//new String(buf, 0, data) <-- 몇번째 배열방 부터 읽어올건지 지정
					System.out.print(new String(buf, 0, data));
				}
		} catch(Exception e) {
			
		}

	}

}

.read()

.read(char[] c) 문자를 저장하는 배열을 만들때

.read(char[] c, int off, int len)


package kjh221207;

import java.io.FileInputStream;

public class Sample02 {

	public static void main(String[] args) {
		
		// <-- fis를 만들어서 쓸건데 아직 뭐에 쓸지 미정상태
		// 이런 미정상태에서는 null 값으로 비워두는게 좋다.
		FileInputStream fis = null;
		
		try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
			//위에서 객체를 만들어둘 준비를 
			fis = new FileInputStream("src/kjh221207/Sample01.java");
					
				int data = 0; //종료시키게 하기 위한 변수 하나 선언
				
				
				//.available() <-- 해당 메서드는 경로가 담긴 변수에 배열방을 자동으로 설정해줌
				byte[] buf = new byte[fis.available()]; 
				
				System.out.println("크기 : " + fis.available());
				
				//.read() <-- 괄호안에 자료형 타입, 변수를 넣어서 할수도 있다.
				//.read(buf, 0, buf.length) <-- (배열변수에서, 몇번째 방부터 , 몇번째 방까지 불러오는 설정)
				while((data=fis.read(buf, 0, buf.length)) != -1) {
					//new String(buf, 0, data) <-- 몇번째 배열방 부터 읽어올건지 지정
					System.out.print(new String(buf, 0, data)); //new String <-- 한글깨진걸 임시방편으로 해결해놓은거
				}
		} catch(Exception e) {
			
			//무조건 실행시켜주는 기능 finally
		} finally {
				//.close()를 사용하려면 무조건 try|catch를 같이 사용해야 된다.
			try {
					//메모리 관리를 위해서 위에 데이터 입력이 끝난 겨우 닫아줘야 되기 때문에 사용
				fis.close();
			}catch(Exception e) {
				
			}
		}

	}

}

.close를 하는 이유

변수나 instance(자원)들은 memory에 있는 value(값)와 address(주소)를 제어하는 것인데
입출력할 File 또는 데이터는 저장 장치 공간에 존재하는것 이므로 외부에 있는 자원이고
이 자원을 사용하려면 외부 자원을 열어야 되는데 이때
메모리로 가지고 와야하며 메모리에 남은 공간을 차지하고 있기 때문에
다 사용하고 나면 다시 연결을 해제 해줘야 한다.

2. 문자(바이트 출력)스트림

Reader - 2byte

package kjh221207;

import java.io.FileReader;

public class Sample03 {

	//tharows Exception <-- try | catch가 귀찮을 경우 하지만 단점도 존재 예외처리를 따로 해주고 싶을때 불가능
	public static void main(String[] args) { 
		
		FileReader fr = null;
		
		try {
			fr = new FileReader("src/kjh221207/Sample01.java");
			
			int data = 0;
			
			while((data = fr.read()) != -1) {
				System.out.print((char)data);
			}
		} catch(Exception e) {
			
		} finally {
			try {
				fr.close();
			} catch(Exception e) {
				
			}
		}
				
				

	}

}

package kjh221207;

import java.io.BufferedReader;
import java.io.FileReader;

public class Sample04 {

	public static void main(String[] args) {
		
		//순수하게 스트림만 사용하게 되면 속도가 느린 단점이 생기거나 데이터가 순차적으로 안가는 단점 등이 있다.
		//메인 스트림 안에 보조 스트림을 끼우는것 (덮여씌우는 느낌)
		
		FileReader fr = null;
		BufferedReader br = null; //보조 스트림 (단독으로는 사용 불가)
		//BufferedReade <-- 한글자씩 처리하는게 아닌 줄 단위로 처리해서 속도 향상
		
		
		try {
			fr = new FileReader("src/kjh221207/Sample01.java");
			br = new BufferedReader(fr); //메인 스트림 fr에 들어있는 경로는 br값에도 가져오기
					
			//줄 단위로 읽어와서 자료형 타입은 String 사용
			String txt = null; 
			
			//.readLine() <-- 줄단위로 읽어와야 되기 때문에 read가 아닌 readLine
			while((txt = br.readLine())!= null) {
				System.out.println(txt);
			} 
		} catch (Exception e) {
			
		} finally {
			try { //스트림을 닫을려면 연결한 역순으로 닫아야 된다.
				  //연결 순으로 처리하게 되면 단점으로는 메모리 누수가 생길 수 있다. (불필요한 찌꺼기 데이터 발생 위험)
				br.close();
				fr.close();
			} catch(Exception e) {
				
			}
		}

	}

}

- 아웃풋

바이트 출력 스트림 - OutputStream

XXXOutputStream

package kjh221207;

import java.io.FileOutputStream;

//아웃풋

public class Sample05 {

	public static void main(String[] args) {
		
		FileOutputStream fos = null;
		
		try {//, true <-- 해당 코드를 넣으면 출력할 데이터 값이 계속해서 누적되어 저장된다.
			fos = new FileOutputStream("test.txt", true);
			
            //단순히 값을 내보낼때
			fos.write(65);
			fos.write(66);
			fos.write(67);
					
		} catch (Exception e) {
			
		} finally {
			try {
				fos.flush(); //스트림에 남아있는 내용(찌꺼기)을 다 내보낸 후
				fos.close(); //스트림을 닫아준다.
			} catch(Exception e) {
				
			}
		}

	}

}

해당 프로젝트 파일 -> 마우스 우 클릭 -> 새로고침 시 출력한 파일 확인 가능


package kjh221207;

import java.io.FileOutputStream;

//아웃풋

public class Sample05 {

	public static void main(String[] args) {
		
		FileOutputStream fos = null;
		
		try { //, true <-- 해당 코드를 넣으면 출력할 데이터 값이 계속해서 누적되어 저장된다.
			fos = new FileOutputStream("test.txt", true);
			
			//배열방 내보내기
			byte[] b =new byte[26];
			
			byte data = 65;
			
			for(int i = 0; i<26; i++) {
				b[i] = data;
				data++;
			}
			
			//배열에 있는 모든 값을 내보낸다.
			fos.write(b);
					
		} catch (Exception e) {
			
		} finally {
			try {
				fos.flush(); //스트림에 남아있는 내용(찌꺼기)을 다 내보낸 후
				fos.close(); //스트림을 닫아준다.
			} catch(Exception e) {
				
			}
		}

	}

}
			//배열에 있는 모든 값을에서 0번방 부터 시작해서 5개만 내보낸다
			fos.write(b, 0, 5);

package kjh221207;

import java.io.FileOutputStream;
import java.io.PrintStream;

//아웃풋

public class Sample05 {

	public static void main(String[] args) {
		
		FileOutputStream fos = null;
		PrintStream ps = null;
		
		try {
			fos = new FileOutputStream("test.txt", true);
			ps = new PrintStream(fos); //보조 스트림, 보조할 대상을 소괄호안에 넣는다.
            
			//프린트스트림을 이용하며 원하는 스타일로 편하게 내보낼 수 있다.
			ps.println("가나다");
			ps.print(123);
			ps.println(true);
			ps.print(3.14);

					
		} catch (Exception e) {
			
		} finally {
			try {
				fos.flush(); //스트림에 남아있는 내용(찌꺼기)을 다 내보낸 후
				fos.close(); //스트림을 닫아준다.
			} catch(Exception e) {
				
			}
		}

	}

}

3. 문자 출력 시스템 - Writer

OutputStream(바이트 byte)

- write(int i); 정수를 보낼때

- write(byte[] b); 배열을 보낼 때

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

 

Wirter(문자)

- write(int i);

- write(char[] c); 위와 비교했을때 byte가 아닌 자료형 타입이 바뀜

- write(char[] b, int off, int len);

- write(String str);

- write(String str, int off, int len);

 

package kjh221207;

import java.io.FileWriter;

public class Sample06 {

	public static void main(String[] args) {
		
		//문자 출력 스트림 - Writer
		
		FileWriter fw = null;
		
		
		try {
			fw = new FileWriter("test2.txt");
			
			fw.write('A'); //문자
			
			char[] buf = {'B', 'C', 'D'}; //배열방 생성
			fw.write(buf); //배열전체
			
			fw.write(buf, 1, 2); //배열방, 1번 방 부터 해서, 2개만
			
			fw.write("가나다"); //문자열
			
			String str = "가나다라"; //문자열 변수 선언 값은 "가나다라"
			fw.write(str); //str 변수 안에 있는 문자열
			
			fw.write(str, 2, 2); //str 문자열 값에 두 번째 부터해서 2개만
			
			
		} catch(Exception e) {
			
		} finally {
			try {
				fw.flush(); //찌꺼기 깔끔띠 하기
				fw.close(); //청소된 후 스트림 종료시키기
			} catch(Exception e) {
				
			}
		}
		

	}

}

package 속도비교;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Sample01 {

	public static void main(String[] args) throws Exception { //예외처리 떠넘기기
		
		/** ======버퍼 사용 전======= **/
		
		
		/** 인풋, 아웃풋 메인스트림 */
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		/** 인풋, 아웃풋 보조스트림 */
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		int data = 0;
		long start = 0;
		long end = 0;
		
		fis = new FileInputStream("src/속도비교/apple.jpg"); //내보내기
		fos = new FileOutputStream("src/apple.jpg"); //들여보내기
		
		start = System.currentTimeMillis(); //시작 시간
		
		while((data=fis.read()) != -1 ) { //읽어오고
			fos.write(data); //내보내고
		}
		fos.flush(); //찌꺽스 처리
		end = System.currentTimeMillis();
		fos.close();
		fis.close();
		
		System.out.println("버퍼 사용 X : " + (end - start));
		
		/** =========버퍼 사용 후======= **/
		
		fis = new FileInputStream("src/속도비교/apple.jpg");
		bis = new BufferedInputStream(fis); //인풋 보조스트림 사용
		
		fos = new FileOutputStream("src/apple.jpg");
		bos = new BufferedOutputStream(fos); //아웃풋 보조스트림 사용
		
		start = System.currentTimeMillis(); //시작 시간
		
		//버퍼 사용 부터는 읽어오는 것하고 내보내는 건 버퍼인 보조 스트림 변수 사용
		while((data=bis.read()) != -1 ) { //읽어오고
			bos.write(data); //내보내고
		}
		bos.flush(); //퍼버 찌꺽스 처리
		end = System.currentTimeMillis();
		bis.close();
		bos.close();
		fos.close();
		fis.close();
		
		
		System.out.println("버퍼 사용 O : " + (end - start));
		

	}

}


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

바이트 스트림 -> 입출력 단위 : 바이트 -> 기본타입 : int, char, double, long

(기본 데이터 타입을 거들어 주어 입출력해주는 방식)

 

- DataInputStream dis = new DataInputStream(바이트 스트림)

ex) read 뒤에 자료형 타입을 붙여준다.

.readInt() 정수형을 읽어올때

.readDouble() 실수형을 읽어올때

.readUTF() 문자열을 읽어올때

 

- DataOutputStream dos = new DataOutputStream(바이트 스트림)

ex) write 뒤에 자료형 타입을 붙여준다.

.writeInt() 정수형을 내보낼때

.writeDouble() 실수형을 내보낼때

.writeUTF() 문자열을 내보낼때

 

package 보조시스템;

import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class Sample01 {

	public static void main(String[] args) throws Exception{
		
		FileOutputStream fos = new FileOutputStream("test3.txt");
		DataOutputStream dos = new DataOutputStream(fos);
		
		dos.writeUTF("가나다");
		dos.writeDouble(12.5);
		dos.writeInt(5);
		dos.writeBoolean(true);
		
		dos.flush();
		dos.close();
		fos.close();

	}

}
		FileInputStream fis = new FileInputStream("test3.txt");
		DataInputStream dis = new DataInputStream(fis);
		
		//아웃풋에 입력한 값과 인풋에 입력한 값 순서가 똑같아야 된다.
		System.out.println(dis.readUTF());
		System.out.println(dis.readDouble());
		System.out.println(dis.readInt());
		System.out.println(dis.readBoolean());

5. 객체 입출력 보조 시스템

객체 -> 바이트 기반 스트림 사용

 

객체 출력 -> 객체를 일렬로 바이트로 변경 : 직렬화

객체 입력 -> 바이트 일렬로 객체를  가져와야 함 :역직렬화

 

- ObjectInputStream

 

 

- ObjectOutputStream

 

package 객체입출력;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Sample01 {

	public static void main(String[] args) throws Exception {
		/** 메인  */
		
		/** 단순 내보내는 기능 */
		writeList(); //호출 (맨 하단에 있는 writeList 값이 불러와진다.)
		
		//readList를 호출해서 list에 넣는다.
		List<Board> list = readList();
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		for(Board b : list) {
			System.out.println(b.getBno() + "\t" + b.getTitle() + "\t" +
					b.getContent() + "\t" + b.getWriter() +
					"\t" + sdf.format(b.getDate()) );
		}

	}
	/** 출력 관련 작업 */
	public static void writeList() throws Exception {
		/** 컬렉션 프레임워크 */
		//순서가 있는 list를 사용해 여러개 객체를 담는다.
		List<Board> list = new ArrayList<>();
		
		/** 컬렉션 프레임 워크 내부에 객체를 채워넣기*/
		//.add 매서드로 Board 객체 타입에 맞춰 값을 설정
		//새로운 객체 생성 후 list배열방에 객체의 값이 각 방에 들어간다.
		list.add(new Board(1, "java", "객체지향", "김자가", new Date() ));
		list.add(new Board(2, "js", "절차향", "제이씨", new Date() ));
		list.add(new Board(3, "jsp", "음향", "호섭이", new Date() ));
		
		
		/** 출력 스트림 작업 */
		FileOutputStream fos = new FileOutputStream("board.db");
		/** 오브젝트 객체 출력 보조 스트림 */
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		
		/** 리스트에 있는 값을 내보내기 */
		oos.writeObject(list);
		
		
		/** 마무리 작업 */
		oos.flush();
		oos.close();
		fos.close();
		
		
	}
	
	/** 입력 관련 작업 */
	public static List<Board> readList() throws Exception {
		
		/** 입력 스트림 */
		FileInputStream fis = new FileInputStream("board.db");
		/** 오브젝트 객체 입력 보조 스트림 */
		ObjectInputStream ois = new ObjectInputStream(fis);
		// (List<Board>) <-- 형변환 시켜준후 ois안에 "board.db를 list에 보관
		List<Board> list = (List<Board>) ois.readObject();
		
		ois.close();
		fis.close();
		
		return list;
	}

}

package 객체입출력;

import java.io.Serializable;
import java.util.Date;

public class Board implements Serializable { //직렬화 사용하려면 직렬화 인터페이스 구현 필수

	/**
	 * 해당 클래스에 고유번호를 넣어준것
	 * 직렬화 역직렬화 할때 클래스 이름과 상관없이 시리얼넘버로 체킹하여 실행된다.
	 * 동일한 클래스인지 판단하기 위해
	 * 추가된 데이터가 다른 곳으로 가지지 않기 위해 방지하는 차원에서 해당 시리얼넘버가 필요
	 */
	private static final long serialVersionUID = 1L;
	
	//접근제한자가 없어도 직렬화 포함 or 있어도 직렬화 포함
	private int bno; 
	private String title;
	private String content;
	private String writer;
	private Date date;
	
	//ClassA c =new ClassA(); <-- 이것도 직렬화 포함됨
	
	//Static String content; <--직렬화 제외
	//transient String writer; <--직렬화 제외
	
	
	public Board(int bno, String title, String content, String writer, Date date) {
		this.bno = bno;
		this.title = title;
		this.content = content;
		this.writer = writer;
		this.date = date;
	}
	
	

	public int getBno() {
		return bno;
	}

	public void setBno(int bno) {
		this.bno = bno;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	
		
	
}

6. File 클래스 -> 파일의 정보

 

package 파일클래스;

import java.io.File;

public class Sample01 {

	public static void main(String[] args) {
		
		//절대경로
		File f = new File("test.txt");
		
		//상대경로
//		File f = new File("src/kjh221207/apple.jpg");
		
		//.isFile 메서드는 파일인지 아닌지 true/false로 리턴
		System.out.println(f.isFile());
		
		//.isDirectory 폴더인지 확인해주는 메서드
		System.out.println(f.isDirectory());
		
		//.getName 파일명 확인해주는 메서드
		System.out.println(f.getName());
		
		//.getAbsolutePath 경로 알려주는 메서드
		System.out.println(f.getAbsolutePath());
		
		//.canRead 읽기 권한에 대한 메서드
		System.out.println(f.canRead());
		
		//.canWrite 쓰기 권한에 대한 메서드
		System.out.println(f.canWrite());
		
		//.length byte 크기 알려주는 메서드
		System.out.println(f.length() + "byte");
	

	}

}


입출력을 이용해서

RESULT.TXT에

 

TEST.TXT에 있는 값을 거꾸로 해서 

 

package 문제;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;

public class Kjh01 {

	 public static void main(String[] args) throws Exception {
	      ArrayList<String> lines = new ArrayList<>();
	      
	      FileReader fr = new FileReader("test.txt");
	      BufferedReader br = new BufferedReader(fr);
	      
	      while(true){
	         String line = br.readLine();
	         if(line == null)
	            break;
	         lines.add(line);
	      }
	      
	      br.close();
	      fr.close();
	      
	      lines.sort(Comparator.reverseOrder());
	      
	      
	      PrintWriter pw = new PrintWriter("result.txt");
	      
	      for(String line : lines) {
	         pw.println(line);
	      }
	      
	      pw.close();

	      
	   }
	   
	   

	}


package 문제;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;

public class Kjh01 {

	 public static void main(String[] args) throws Exception {
	      ArrayList<String> lines = new ArrayList<>();
	      
	      int sum = 0;
	      double avg;
	      
	      FileReader fr = new FileReader("test2.txt");
	      BufferedReader br = new BufferedReader(fr);
	      
	      while(true){
	         String line = br.readLine();
	         if(line == null)
	            break;
	         lines.add(line);
	      }
	      
	      for(String line : lines) {
	    	  sum = sum + Integer.parseInt(line); //형변환! 문자열을 불러와서 정수로 바꿔준다.
	      }
	      
	      avg = (double)sum / lines.size();
	      
	      System.out.println("합 : " + sum + " 평균 : " + avg);
	      
	      


	      
	   }
	   
	   

	}

728x90
Comments