프린트 보조 스트림

PrintStream과 PrintWriter는 프린터와 유사하게 출력하는 print(),println() 메소드를 가지고 있는 보조 스트림이다.

PrintStream은 바이트 기반 출력 스트림과 연결되고, PrintWriter는 문자 기반 출력 스트림과 연결 된다.

System.out.println();이 바로 PrintStream 타입이다. 

 

 

package sec03.exam01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamEx {

	public static void main(String[] args) throws FileNotFoundException {
		// 바이트 기반 출력 스트림을 생성하고 printstream 보조 스트림 연결
		File file = new File("C:/Temp/printstream123.txt");
		FileOutputStream fos = new FileOutputStream(file);
		PrintStream ps = new PrintStream(fos);
		
		// 파일, 폴더 존재 여부 확인
		if(file.exists()) {
			System.out.println("있다.");
		}else {
			System.out.println("없다.");
		}
		
		// printstream123.txt 해당 파일에 데이터 입력 
		ps.println("[프린터 보조 스트림]");
		ps.print("마치");
		ps.println("프린터가 출력하는 것처럼");
		ps.println("데이터를 출력합니다.");
		
		ps.flush();
		ps.close();
	}

}

 

 

 

 

 

객체 입출력 보조 스트림

ObjectOutputStream과 ObjectInputStream 보조 스트림을 연결하면 메모르에 생성된 객체를 파일 또는 네트워크로 

출력이 가능 하다.

 

ObjectOutputStream은 객체를 직렬화하는 역할을 하고, ObjectInputStream은 객체로 역직렬화하는 역할을 한다.

직렬화란 객체를 바이트 배열로 만드는 것이고, 역직렬화란 바이트 배열을 다시 객체로 복원하는 것을 말한다.

 

 

ObjectInputStream ois = new ObjectInputStream(바이트 기반 입력 스트림);
ObjectOutputStream oos = new ObjectOutputStream(바이트 기반 입력 스트림);

두개는 다른 보조 스트림과 마찬가지로 연결할 바이트기반 입출력 스트림을 생성자의 매개값으로 받는다. 

 

 

oos.writeObject(객체);

ObjectOutputStream의 writeObject( ) 메소드는 객체를 직렬화해서 출력 스트림으로 보낸다.

 

 

 

객체타입 변수 = (객체타입) ois.readObject();

반대로 ObjectInputStream의 readObject( ) 메소드는 입력 스트림에서 읽은 바이트를 역직렬화해서

객체로 다시 복원해서 리턴한다. 리턴 타입은 Object 타입이기 때문에 원래 타입으로 위에 처럼 강제 변환

해야 한다. 

 

자바는 모든 객체를 직렬화하지 않는다. java.io.Serializable 인터페이스를 구현한 객체만 직렬화한다.

Serializable 인터페이스는 메소드 선언이 없는 인터페이스이다. 객체를 파일로 저장하거나, 네트워크로 전송할

목적이라면 개발자는 클래스를 선언할 때 implements Serializable을 추가해야 한다. 

이것은 개발자가 JVM에게 직렬화해도 좋다고 승인하는 역할을 한다고 보면 된다.

밑에 예제를 보고 확인

 

 

Serializable 인터페이스 구현

package sec03.exam03;

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

							// Serializable 인터페이스 구현
public class Board implements Serializable {
	private int bno;
	private String title;
	private String content;
	private String writer;
	private Date date;
	
	
	public Board(int bno, String title, String content, String writer, Date date) {
		super();
		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;
	}
	
	
	
	
	
	
	
	
}


실행

package sec03.exam03;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
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 ObjectStreamEx {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		writeList(); // List를 파일에 저장
		List<Board> list = readList(); // 파일에 저장된 List 읽기
		
        // List 내용을 모니터에 출력
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		for(Board board : list) {
			System.out.println(
			board.getBno() + "\t" + board.getTitle() + "\t" +
			board.getContent() + "\t" + board.getWriter() + "\t" +
			sdf.format(board.getDate())
					
					);
		}
	}
	
	public static void writeList() throws IOException {
		List<Board> list = new ArrayList<Board>();
		// list에 Board 객체 저장
		list.add(new Board(1, "제목1", "내용1", "글쓴이1", new Date()));
		list.add(new Board(1, "제목2", "내용2", "글쓴이2", new Date()));
		list.add(new Board(1, "제목3", "내용3", "글쓴이3", new Date()));
		
        // 객체 출력 스트림을 이용해서 list 출력 
		FileOutputStream fos = new FileOutputStream("c:/Temp/board.db");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(list);
		oos.flush();
		oos.close();
	}
	// 객체 입력 스트림을 이용해서 list 읽기
	public static List<Board> readList() throws IOException, ClassNotFoundException {
		FileInputStream fis = new FileInputStream("c:/Temp/board.db");
		ObjectInputStream ois = new ObjectInputStream(fis);
		List<Board> list = (List<Board>) ois.readObject();
		return list;
	}
}
<결과>
1	제목1	내용1	글쓴이1	2023-06-28
1	제목2	내용2	글쓴이2	2023-06-28
1	제목3	내용3	글쓴이3	2023-06-28

 

 

 

File  클래스

java.io 패키지에서 제공하는 File 클래스는 파일 및 폴더 정보를 제공해주는 역할을 한다.

 

package sec03.exam02;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileEx {

	public static void main(String[] args) throws IOException {
		
		File dir = new File("C:/Temp/images"); // 디렉터리 생성
		File file1 = new File("C:/Temp/file1.txt");// File 객체 생성
		File file2 = new File("C:/Temp/file2.txt");
		File file3 = new File("C:/Temp/file3.txt");
		
		// 파일 또는 폴더가 존재하지 않으면 생성
		if(dir.exists() == false) {dir.mkdirs();} 
		if(file1.exists() == false) {file1.createNewFile();}
		if(file2.exists() == false) {file2.createNewFile();}
		if(file3.exists() == false) {file3.createNewFile();}
		
		// C:/Temp 폴더의 내용 목록을 File 배열로 얻음
		File temp = new File("C:/Temp");
		File[] contents = temp.listFiles();
		
		System.out.println("시간\t\t\t형태\t\t크기\t이름");
		System.out.println("-----------------------------------");
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd a HH:mm");
		for(File file : contents) {
			// 파일 또는 폴더 정보를 출력
			System.out.println(sdf.format(new Date(file.lastModified())));
			if(file.isDirectory()) {
				System.out.println("\t<DIR>\t\t\t" + file.getName());
			}else {
				System.out.println("\t\t\t" + file.length() + "\t" + file.getName());
			}
			System.out.println();
		}
	}

}
<결과>
시간			형태		크기	이름
-----------------------------------
2023-06-28 오후 16:33
			382	board.db

2023-06-28 오전 10:13
			6	file1.txt

2023-06-28 오전 09:33
			0	file2.txt

2023-06-28 오전 09:33
			0	file3.txt

2023-06-28 오전 09:33
	<DIR>			images

2023-06-28 오후 16:17
			104	printstream123.txt

 

 

 

File 클래스를 이용한 파일 및 폴더 정보 출력

package sec03.exam02;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class FromFileEx {

	public static void main(String[] args) throws IOException {
		Path path = Paths.get("C:\\Temp\\file1.txt");// 객체 생성
		
		// Files.lines() 메서드를 사용하여 path에 지정된 파일을 열고, 각 줄을 Stream으로 읽음
		Stream<String> stream = Files.lines(path, Charset.defaultCharset());
		
		// stream 객체를 사용하여 각 줄을 반복하며, 각 줄을 콘솔에 출력
		stream.forEach(s->System.out.println(s));
		
		// 파일을 객체로 변환
		File file = path.toFile(); 
		// FileReader 객체를 사용하여 file을 읽음
		FileReader fileReader = new FileReader(file);
		// fileReader를 사용하여 파일을 읽음
		BufferedReader br = new BufferedReader(fileReader);
		// BufferedReader 객체 br을 사용하여 각 줄을 Stream으로 읽어옴
		stream = br.lines();
		//  각 줄을 반복하며, 각 줄을 콘솔에 출력
		stream.forEach(s->System.out.println(s));
		
		Path path2 = Paths.get("c:/Temp");
		// Files.list() 메서드를 사용하여 path2에 지정된 디렉토리의 파일 목록을 가져옴
		Stream<Path> stream2 = Files.list(path2);
			stream2.forEach(p->{
				System.out.println(p.getFileName());
			});
		
	}

}
<결과>
파일
파일
file1.txt
file2.txt
file3.txt
images
printstream123.txt
실행 결과에 "파일"이 두 번 나오는 이유는 "파일" 이외에도 "images"라는 이름의 디렉토리도 있기 때문입니다. 
"images"는 디렉토리이지만, "파일" 출력 후에 "images" 디렉토리의 이름이 출력되므로, "파일""images"가 연이어 나타나는 것

 

 

 

Int Stream, 배열, 일반for문, 향상된 for문,

package sec03.exam02;

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class StreamEx {
	static int sum = 0;
	public static void main(String[] args) {
		
		// 1~10 까지 출력
		IntStream st1 = IntStream.rangeClosed(1, 10);
		st1.forEach(w->System.out.print(w + ","));// 1,2,3,4,5,6,7,8,9,10
		
		System.out.println();
		
		// 1~10 합계
		IntStream st2 = IntStream.rangeClosed(1, 10);
		st2.forEach(w->{
			sum += w;
		});
		System.out.println(sum); // 55 
		
		
		// IntStream
		int[] intArray = {1,2,3,4,5};
		IntStream intStream = Arrays.stream(intArray);
		intStream.forEach(a->System.out.print(a + ","));// 1,2,3,4,5
		
		System.out.println();
		
		// 3개 다 결과는 동일	
		String[] strArray = {"김", "이", "박"};
		
		// Stream
		Stream<String> stream = Arrays.stream(strArray);
		stream.forEach(s->{
			System.out.println(s);
		});
		System.out.println("-----------------------------");
		// 일반 for문
		for(int i=0; i < strArray.length; i++) {
			System.out.println(strArray[i]);
		}
		System.out.println("-----------------------------");
		// 향상된 for문
		for(String str : strArray) {
			System.out.println(str);
		}
			
	}

}
<결과>
1,2,3,4,5,6,7,8,9,10,
55
1,2,3,4,5,
김
이
박
-----------------------------
김
이
박
-----------------------------
김이박

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-30 31일차  (0) 2023.06.30
2023-06-29 30일차  (0) 2023.06.29
2023-06-26 27일차  (0) 2023.06.26
2023-06-22 25일차  (0) 2023.06.22
2023-06-21 24일차  (0) 2023.06.21

보조 스트림

다른 스트림과 연결이 되어 여러 가지 편리한 기능을 제공해주는 스트림 

보조 스트림은 자체적으로 입출력을 수행할 수 없기 때문에 입출력 소스와 바로 연결되는 InputStream,OutStream,

Reader, Writer 등에 연결해서 입출력을 수행, 문자 변환, 입출력 성능 향상, 기본 타입 입출력 등의 기능을 제공

입력 스트림 => 보조 스트림 => 프로그램 => 보조 스트림 => 출력 스트림

 

 

보조 스트림 연결하기

보조스트림 변수 = new 보조스트림( 연결스트림 )

InputStream is = ...;
InputStreamReader reader = new InputStreamReader(is);

 

 

문자 변환 보조 스트림

소스 스트림이 바이트 기반 스트림 ( InputStream, OutputStream, FileInputStream, FileOutputStream)이면서

입출력 데이터가 문자라면 Rearder와 Writer로 변환해서 사용하는 것을 고려할 수있다. 더 편리하기 때문에

 

 

OutputStreamWriter

바이트 기반 출력 스트림에 연결되어 문자 출력 스트림인 Writer로 변환하는 보조 스트림이다.

Writer writer = new OutputStreamWriter(바이트 기반 출력 스트림);

 

 

InputStreamReader

바이트 기반 입력 스트림에 연결되어 문자 입력 스트림인 Reader로 변환하는 보조 스트림이다.

Reader reader = new InputStreamReader(바이트 기반 입력 스트림);
package sec02.exam01;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public class CharacterConvertStreamEx {

	public static void main(String[] args)throws Exception {
		write("문자 변환 스트림을 사용합니다.");
		String data = read();
		System.out.println(data);

	}
	
	public static void write(String str) throws Exception{
// 		FileOutputStream에 OutputStreamWriter 보조 스트림을 연결
		FileOutputStream fos = new FileOutputStream("C:/Temp/test1.txt");
		Writer writer = new OutputStreamWriter(fos);
		
		// OutputStreamWriter 보조 스트림을 이용해서 문자 출력 
		writer.write(str);
		writer.flush();
		writer.close();
		
	}
	
	public static String read() throws Exception{
//		FileInputStream에 InputStreamReader 보조 스트림을 연결
		FileInputStream fis = new FileInputStream("C:/Temp/test1.txt");
		Reader reader = new InputStreamReader(fis);
		
		
		char[] buffer = new char[100];
		
		int readCharNum = reader.read(buffer);
		// InputStreamReader 보조스트림을 이용해서 문자 입력
		
		reader.close();
		
		// char 배열에서 읽은 수만큼 문자열로 변환 
		String data = new String(buffer, 0, readCharNum);
		return data;
	}
}
<결과>
문자 변환 스트림을 사용합니다.

 

 

 

성능 향상 보조 스트림

BufferedOutputStream과 BUfferedWriter

 

BufferedOutputStream은 바이트 기반 출력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이고,

BUfferedWriter는 문자 기반 출력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다.

해당 두개는 프로그램에서 전송한 데이터를 내부 버퍼에 쌓아두었다가 버퍼가 꽉 차면, 버퍼의 모든 데이터를 한꺼번에

보낸다. 프로그램 입장에서 보면 메모리버퍼로 데이터를 고속 전송하기 때문에 출력 성능이 향상되는 효과를 얻게 된다.

 

 

 

 

BufferedInputStream과 BUfferedReader

 

BufferedInputStream은 바이트 기반 입력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이고,

BUfferedReader는 문자 기반 입력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다.

해당 두개는 입력 소스로부터 자신의 내부 버퍼 크기만큼 데이터를 미리 읽고 버퍼에 저장해둔다. 

프로그램은 외부의 입력 소스로부터 직접 읽는 대신 버퍼로부터 읽음으로써 읽기 성능이 향상된다.

 

속도 비교

1. 같은 용량의 파일 클래스에 파일 위치한 곳에 놔둠 

 

 

2. 소스 코드 작성 

package sec02.exam02;

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

public class NonBufferVsBufferEx {

	public static void main(String[] args) throws Exception {
		String originalFilePath1 = // 기본 스트림 생성
				NonBufferVsBufferEx.class.getResource("originalFile1.jpg").getPath();
		String targetFilePath1 = "C:/Temp/orginalFile1.jpg";
		FileInputStream fis = new FileInputStream(originalFilePath1);
		FileOutputStream fos = new FileOutputStream(targetFilePath1);
		
		String originalFilePath2 = // 버퍼 보조 스트림 연결
				NonBufferVsBufferEx.class.getResource("originalFile2.jpg").getPath();
		String targetFilePath2 = "C:/Temp/orginalFile2.jpg";
		FileInputStream fis2 = new FileInputStream(originalFilePath2);
		FileOutputStream fos2 = new FileOutputStream(targetFilePath2);
		BufferedInputStream bis = new BufferedInputStream(fis2);
		BufferedOutputStream bos = new BufferedOutputStream(fos2);
		
		long nonBufferTime = copy(fis, fos);// 이용한 복사 시간 측정
		System.out.println("버퍼를 사용하지 않았을 때 :\t" + nonBufferTime + "ns");
		
		long buffertime = copy(bis, bos);// 이용한 복사 시간 측정
		System.out.println("버퍼를 사용했을 때 :\t\t" + buffertime + "ns");
		
		fis.close();
		fos.close();
		bis.close();
		bos.close();
	}
	
	static int data = -1;
	public static long copy(InputStream is, OutputStream os) throws Exception {
		long start = System.nanoTime();// 시작 시간 저장
		
        // [파일복사] 원본 파일에서 읽은 1byte를 타깃 파일로 바로 출력
        while(true) { 
			data = is.read();
			if(data == -1) break;
			os.write(data);
		}
		os.flush();
        
		long end = System.nanoTime(); // 끝 시간 저장
		return (end-start); // 복사에 걸린 시간 리턴
	}

}


<결과>
버퍼를 사용하지 않았을 때 :	2335365300ns
버퍼를 사용했을 때 :		25020500ns

3. 설정한 경로에 파일 복사 됫는지  확인

 

 

 

 

 

 

 

 

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

DataInputStream과 DataOutStream 보조 스트림을 연결하면 기본 타입인 boolean, char, short, int, long, float,

double을 입출력할 수 있다.

주의할 점이 있는데, 데이터 타입의 크기가 모두 다르므로 DataOutputStream으로 출력한 데이터를 다시 

DataInputStream으로 읽어올 때는 출력한 순서와 동일한 순서로 읽어야 한다. 예를 들어 출력할 때 순서가 

int->boolean->double이라면 읽을 때의 순서도 동일 해야 한다.

 

package sec02.exam03;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataInputOutputStreamEx {

	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("C:/Temp/primitive.db");
		DataOutputStream dos = new DataOutputStream(fos);
		
        // 기본 타입 값 출력
		dos.writeUTF("홍길동");// 유니코드
		dos.writeDouble(95.5);
		dos.writeInt(1);
		
		dos.writeUTF("감자바");
		dos.writeDouble(90.3);
		dos.writeInt(2);
		
		dos.flush(); dos.close();
		
		FileInputStream fis = new FileInputStream("C:/Temp/primitive.db");
		DataInputStream dis = new DataInputStream(fis);
		
		for(int i=0; i<2; i++) {
        	// 기본 타입 값 읽기 
			String name = dis.readUTF();
			double score = dis.readDouble();
			int order = dis.readInt();
			System.out.println(name + ":" + score + ":" + order);
		}
		dis.close();
	}

}

<결과>
홍길동:95.5:1
감자바:90.3:2

입출력 스트림

자바에서 데이터는 스트림을 통해 입출력 된다. 스트림은 단일 뱡향으로 연속적으로 흘러가는 것을 말하는데,

물이 높은 곳에서 낮은 곳으로 흐르는듯이 데이터는 출발지에서 도착지로 흘러간다.

프로그램이 출발지냐 또는 도착지냐에 따라서 사용하는 스트림의 종류가 결정된다. 

 

 

입출력 스트림의 종류

바이트 기반 스트림 : 그림, 멀티미디어 등의 바이너리 데이터를 읽고 출력할 때 사용

문자 기반 스트림 : 문자 데이터를 읽고 출력할 때 사용

스트림 클래스가 바이트 기반인지, 문자 기반인지 구별하려면 최상위 클래스를 보면 된다. 

 

 

바이트 출력 스트림 : Out Put Stream

Out Put Stream은 바이트 기반 출력 스트림의 최상위 클래스로 추상 클래스이다. 모든 바이트 기반 출력 스트림 클래스는

Out Put Stream 클래스를 상속받아서 만들어 진다.

 

write(int b) 메소드

해당 메소드는 매개 변수로 주어지는 int(4byte)에서 끝 1byte만 출력 스트림으로 보낸다. 매개 변수가 int

타입이므로 4byte 모두 보내는 것은 아니다. 

 

 

 

밑에 예제는 10, 20 30이 저장된 각각의 바이트 파일 C:\Temp\test1.db로 출력해서

test1.db 내용으로 저장하는 예제

package sec01.exam01;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteEx {

	public static void main(String[] args) throws InterruptedException, IOException {
		// 스트림 
		OutputStream os = new FileOutputStream("c:/Temp/test1.db");// 해당 위치에 파일 생성
		
		
		// 파일에 값입력
		byte a = 10;
		byte b = 20;
		byte c = 30;
		
		// 1byte씩 출력
		os.write(a);
		os.write(b);
		os.write(c);
		

		
		os.flush();// 출력 버퍼에 잔류하는 모든 바이트 출력
		os.close();// 출력 스트림을 닫음 
		
	}

}

 

 

 

밑에 예제는 10, 20 30이 저장된 배열을 파일 C:\Temp\test2.db로 출력해서

test2.db 내용으로 저장하는 예제

 

배열 전체를 출력하기

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteEx {

	public static void main(String[] args) throws InterruptedException, IOException {
		// 스트림 
		OutputStream os = new FileOutputStream("c:/Temp/test2.db");// 해당 위치에 파일 생성
		
		

		
		byte[] array = {10, 20, 30};
		os.write(array); // 배열의 모든 바이트를 출력
		
		os.flush();// 출력 버퍼에 잔류하는 모든 바이트 출력
		os.close();// 출력 스트림을 닫음 
		
	}

}

 

 

write(byte[ ] b, int, off, int len ) 메소드

해당 메소드는 b(off)부터 len개의 바이트를 출력 스트림으로 보낸다. 

 

밑에 예제는 10, 20, 30, 40, 50이 저장된 배열에서 20, 30, 40을 추려서 파일 C:\Temp\test3.db

출력해서 test3.db의 내용으로 저장한다.

package sec01.exam01;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteEx {

	public static void main(String[] args) throws InterruptedException, IOException {
		// 스트림 
		OutputStream os = new FileOutputStream("c:/Temp/test3.db");// 해당 위치에 파일 생성
		
		
		byte[] array = {10, 20, 30, 40, 50};
		os.write(array, 1, 3); // 배열의 1번 인덱스부터 3개를 출력
		
		os.flush();// 출력 버퍼에 잔류하는 모든 바이트 출력
		os.close();// 출력 스트림을 닫음 
		
	}

}

 

 

 

 

 

 

바이트 입력 스트림 : IN Put Stream

 

 

read( ) 메소드 

해당 메소드는 입력 스트림으로부터 1byte를 읽고 int(4byte) 타입으로 리턴 한다. 따라서 리턴된 4byte 중 끝

1byte에만 데이터가 들어 있다.

 

package sec01.exam01;

import java.io.FileInputStream;
import java.io.InputStream;

public class ReadEx {
	// 파일 읽어오기
	public static void main(String[] args) throws Exception {
		InputStream is = new FileInputStream("c:/Temp/test2.db");
		
		
		while(true) {
			int data = is.read(); // 1byte씩 읽기
			if(data == -1) break;// -1을 리턴하면 자료가 없다.( 파일 끝에 도달했을 경우 )
			System.out.println(data);
		}
		
		
		
		is.close();
	}

}
위에서 출력한 test2.db 읽기 
<결과>
10
20
30

 

 

read(byte[ ] b) 메소드

해당 메소드는 입력 스트림으로부터 매개값으로 주어진 배열의 길이만큼 바이트를 읽고 해당 배열에 저장한다.

그리고 읽은 바이트 수를 리턴한다. 실제로 읽은 바이트 수가 배열의 길이보다 적을 경우, 읽은 수 만큼만 리턴

많은 양의 바이트를 읽을 때는 read(byte[ ] b) 메소드를 사용하는 것이 좋다. 

입력 스트림으로 부터 100개의 바이트가 들어온다면 read() 메소드는 100번을 반복해서 읽어야 하지만,

read(byte[ ] b) 메소드는 한 번 읽을 때 배열의 길이만큼 읽기 때문에 읽는 횟수가 현저히 줄어든다.

 

 

package sec01.exam01;

import java.io.FileInputStream;
import java.io.InputStream;

public class ReadEx {
	// 파일 읽어오기
	public static void main(String[] args) throws Exception {
		InputStream is = new FileInputStream("c:/Temp/test3.db");
		

		
		
		// 임시 저장 공간
		byte[] buffer = new byte[100];
		
		while(true) {
			int data = is.read(buffer);
			if(data == -1) break;// -1을 리턴하면 자료가 없다.
			for(int i = 0; i < data; i++) {
				System.out.println(buffer[i]);
			}
		}
		is.close();
	}

}
위에서 작성했던 test3.db 파일 입력 스트림을 생성
<결과>
20
30
40

 

 

 

read( byte[ ] b, int off, int len ) 메소드

해당 메소드는 입력 스트림으로부터 len개의 바이트만큼 읽고, 매개값으로 주어진 바이트 배열 b[off]부터 len개까지 저장한다. 그리고 읽은 바이트 수인 len개를 리턴한다. 실제로 읽은 바이트 수가 len개보다 작을 경우에는 읽은 수만큼만 리턴해당 메서드도 동일하게 입력 스트림으로부터 바이트를 더 이상 읽을 수 없다면 -1을 리턴한다.

 

지정한 길이만큼 읽기

package sec01.exam02;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ReadEx {
	// read( ) 메소드
	public static void main(String[] args) throws IOException {
		InputStream is = new FileInputStream("c:/Temp/test1.db");
		
		byte[] buffer = new byte[5];
		
		// 입력 스트림으로 부터 3byte를 읽고 buffer[2], buffer[3], buffer[4]에 각각 저장 
		int readByteNum = is.read(buffer, 2, 3);
		if(readByteNum != -1) { // 읽은 바이트가 있다면 
			for(int i=0; i<buffer.length; i++) {// 배열 전체를 읽고 출력
				System.out.println(buffer[i]);
			}
		}
		is.close();
	}

}

 

 

 

 

문자 출력 스트림 : Writer

문자 기반 출력 스트림의 최상위 클래스로 추상클래스이다. 모든 문자 기반 출력 스트림 클래스는 Writer 클래스를 상속

받아서 만들어진다.

 

 

 

write( int c ) 메소드

 해당 메소드는 매개 변수로 주어지는 int(4byte)에서 끝 2byte(1개의 문자)만 출력 스트림으로 보낸다.

매개 변수가 int 타입이므로 4byte 모두를 보내는 것은 아니다.

package sec01.exam02;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
	
public class WriteEx {

	public static void main(String[] args) throws IOException {
		Writer writer = new FileWriter("c:/Temp/test7.db");// 스트림 생성 
//		Writer은 부모 클래스 FileWriter 자식 클래스 자동 타입 변환          
        
		// 한문자씩 출력 	
		char a = 'a';
		char b = '비';
		char c = 'c';
		
		writer.write(a);
		writer.write(b);
		writer.write(c);
		

	
		
		writer.flush();// 출력 버퍼에 잔류하는 모든 문자를 출력
		writer.close();// 출력 스트림을 닫음
	}

}

 

 

write( char[ ] cbuf ) 메소드

해당 메소드는 매개값으로 주어진 char[] 배열의 모든 문자를 출력 스트림으로 보낸다.

package sec01.exam02;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
	
public class WriteEx {

	public static void main(String[] args) throws IOException {
		Writer writer = new FileWriter("c:/Temp/test7.db");

		
		// 배열 전체를 출력하기
		char[] array = {'A', 'B', 'C'};
		
		writer.write(array);
	
		
		writer.flush();
		writer.close();
	}

}

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-29 30일차  (0) 2023.06.29
2023-06-28 29일차  (0) 2023.06.28
2023-06-22 25일차  (0) 2023.06.22
2023-06-21 24일차  (0) 2023.06.21
2023-06-20 23일차  (0) 2023.06.20

클래스 순서도 

core 패키지 안에 3개 패키지가 있음 

 

 

discount 패키지

인터페이스

package core.discount;

import core.member.Member;

public interface DiscountPolicy { // 할인 정책
	int discount(Member member, int price); // 할인 금액을 리턴

}


구현 클래스 1000원 할인

package core.discount;

import core.member.Grade;
import core.member.Member;

public class FixDiscountPolicy implements DiscountPolicy{
	
	private int discountFixAmount = 1000; // 1000원 할인
	
	@Override
	public int discount(Member member, int price) {
		if(Grade.VIP == member.getGrade()){
			return discountFixAmount;
		}else {
			return 0;
		}
	
	}

}


구현 클래스 10% 할인
package core.discount;

import core.member.Grade;
import core.member.Member;

public class RateDiscountPolicy implements DiscountPolicy {
	
	private int discountPercent = 10; // 10% 할인
	
	@Override
	public int discount(Member member, int price) {
		if(member.getGrade() == Grade.VIP) {
			return price * discountPercent / 100;
		}else {
			return 0;
		}
		
	}

}

 

member 패키지

열거 enum

package core.member;

public enum Grade { // 회원 등급
	BASIC,
	VIP;
}


member DTO

package core.member;

public class Member {
	private Long id; // 회원 아이디
	private String name; // 회원 이름 
	private Grade grade; // 회원 등급
	
	
	public Member(Long id, String name, Grade grade) {
		super();
		this.id = id;
		this.name = name;
		this.grade = grade;
	}


	public Long getId() {
		return id;
	}


	public void setId(Long id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


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


	public Grade getGrade() {
		return grade;
	}


	public void setGrade(Grade grade) {
		this.grade = grade;
	}
	
	
	
}


인터페이스 1

package core.member;

public interface MemberRepository {
	void save(Member member);	// 회원 정보 저장
	Member findById(Long memberId); // 회원 정보 검색
}


구현 클래스 1

package core.member;

import java.util.HashMap;
import java.util.Map;

public class MemoryMemberRepository  implements MemberRepository{
	
	// 해시맵에 고객정보 저장, 검색 
	private static Map<Long, Member> store = new HashMap<>();
	
	@Override
	public void save(Member member) {
		store.put(member.getId(), member);
		
	}

	@Override
	public Member findById(Long memberId) {
		// TODO Auto-generated method stub
		return store.get(memberId);
	}

}


인터페이스 2

package core.member;

public interface MemberService {
	void join(Member member);
	
	Member findMember(Long memberId);
}


구현 클래스 2

package core.member;

public class MemberServiceImpl implements MemberService {

	private MemberRepository memberRepository;
	
	
	
	
	public MemberServiceImpl(MemberRepository memberRepository) {
		super();
		this.memberRepository = memberRepository;
	}

	@Override
	public void join(Member member) {
		memberRepository.save(member);
		
	}

	@Override
	public Member findMember(Long memberId) {
		// TODO Auto-generated method stub
		return memberRepository.findById(memberId);
	}

}

 

 

order 패키지

order DTO

package core.order;

public class Order {
	private Long memberId;
	private String itemName; // 상품명
	private int itemPrice; // 상품 가격
	private int discountPrice;// 할인 가격
	
	public int calculatePrice() {// 상품 가격 계산
		return itemPrice - discountPrice;
	}

	public Order(Long memberId, String itemName, int itemPrice, int discountPrice) {
		super();
		this.memberId = memberId;
		this.itemName = itemName;
		this.itemPrice = itemPrice;
		this.discountPrice = discountPrice;
	}

	public Long getMemberId() {
		return memberId;
	}

	public void setMemberId(Long memberId) {
		this.memberId = memberId;
	}

	public String getItemName() {
		return itemName;
	}

	public void setItemName(String itemName) {
		this.itemName = itemName;
	}

	public int getItemPrice() {
		return itemPrice;
	}

	public void setItemPrice(int itemPrice) {
		this.itemPrice = itemPrice;
	}

	public int getDiscountPrice() {
		return discountPrice;
	}

	public void setDiscountPrice(int discountPrice) {
		this.discountPrice = discountPrice;
	}

	@Override
	public String toString() {
		return "Order [memberId=" + memberId + ", itemName=" + itemName + ", itemPrice=" + itemPrice
				+ ", discountPrice=" + discountPrice + "]";
	}
	
	
	
	
	
}


인터페이스 정의

package core.order;

public interface OrderService {
	Order createOrder(Long memberId, String itemName, int itemPrice);
}


구현 클래스

package core.order;

import core.discount.DiscountPolicy;
import core.member.Member;
import core.member.MemberRepository;

public class OrderServiceImpl implements OrderService {
	
	private MemberRepository memberRepository; // 회원 정보 
	private DiscountPolicy discountPolicy;
	
	
	
	
	public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
		super();
		this.memberRepository = memberRepository;
		this.discountPolicy = discountPolicy;
	}




	@Override
	public Order createOrder(Long memberId, String itemName, int itemPrice) {
		Member member = memberRepository.findById(memberId);
		int discountPrice = discountPolicy.discount(member, itemPrice);
		return new Order(memberId, itemName, itemPrice, discountPrice);
	}

}

 

 

core 패키지

셋팅 ( 나중에 스프링에서 설정 해줌 ) 

package core;

// 셋팅

import core.discount.DiscountPolicy;
import core.discount.RateDiscountPolicy;
import core.member.MemberRepository;
import core.member.MemberServiceImpl;
import core.member.MemoryMemberRepository;
import core.order.OrderServiceImpl;

public class AppConfig {
	
	public DiscountPolicy discountPolicy() {
		return new RateDiscountPolicy();
	}
	
	public MemberRepository memberRepository() {
		return new MemoryMemberRepository();
	}
	
	public MemberServiceImpl memberService() {
		return new MemberServiceImpl(memberRepository());
	}
	
	public OrderServiceImpl orderService() {
		return new OrderServiceImpl(memberRepository(), discountPolicy());
	}
	
}


실행

package core;

import core.member.Grade;
import core.member.Member;
import core.order.Order;

public class MemberApp {

	public static void main(String[] args) {
		
		AppConfig app = new AppConfig();
		
		Member member = new Member(1L, "홍길수", Grade.VIP);
		app.memberService().join(member); // 회원 등록
		
		// 회원 검색
		Member findMember = app.memberService().findMember(1L);
		
		System.out.println(findMember.getName());
	
		Order order = app.orderService().createOrder(1L, "item1", 9000);
		System.out.println("할인 금액 :"+order.getDiscountPrice());
		System.out.println("지불액:"+order.calculatePrice());
	}
	

}
<결과>
홍길수
할인 금액 :900
지불액:8100

Board( List<Board> )

Board ( Dto )

package sec02.exam01;

public class Board {
	private String title;
	private String content;
	
	
	public Board(String title, String content) {
		super();
		this.title = title;
		this.content = content;
	}


	public String getTitle() {
		return title;
	}


	public String getContent() {
		return content;
	}
	
	
	
	
}


Board ( Dao )

package sec02.exam01;

import java.util.ArrayList;
import java.util.List;

public class BoardDao {
	
	public List<Board> getBoardList(){
		List<Board> list = new ArrayList<Board>();
		list.add(new Board("제목1", "내용1"));
		list.add(new Board("제목2", "내용2"));
		list.add(new Board("제목3", "내용3"));
		return list;
	}
	
}


실행

package sec02.exam01;

import java.util.List;

public class ListEx {

	public static void main(String[] args) {
		BoardDao dao = new BoardDao();
		List<Board> list = dao.getBoardList();
		for(Board board : list) {
			System.out.println(board.getTitle() + "_" + board.getContent());
		}

	}

}


<결과>
제목1_내용1
제목2_내용2
제목3_내용3

 

 

 

Set / HashSet

hashCode()와 equals() 재정의

package sec02.exam02;

import java.util.Objects;

public class Student {
	public int studentNum;
	public String name;
	
	
	
	public Student(int studentNum, String name) {
		super();
		this.studentNum = studentNum;
		this.name = name;
	}



	@Override
	public int hashCode() {
		return Objects.hash(studentNum);
	}



	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		return studentNum == other.studentNum;
	}




	
	
	
	
}


실행 ( Student 중복 저장 방지 )

package sec02.exam02;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetEx {

	public static void main(String[] args) {
		Set<Student> set = new HashSet<Student>();
		
		set.add(new Student(1, "홍길동"));
		set.add(new Student(2, "신용권"));
		set.add(new Student(1, "조민우")); // 학번이 같아서 저장되지 않음 
		
		Iterator<Student> iterator = set.iterator();
		while(iterator.hasNext()) {
			Student student = iterator.next();
			System.out.println(student.studentNum + ":" + student.name);
		}

	}

}
<결과>
1:홍길동
2:신용권

 

 

Map<>, HashMap<> / 점수 관리 ( 평균, 최고점수, 최고점수를 받은 학생 아이디 ) 

package sec02.exam02;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapEx {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("blue", 96);
		map.put("hong", 86);
		map.put("white", 92);
		
		String name = null;
		int maxScore = 0;
		int totalScore = 0;
		
		Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
		for(Map.Entry<String, Integer> entry : entrySet) {
			if(entry.getValue()>maxScore) {
				name = entry.getKey();
				maxScore = entry.getValue();
			}
			totalScore += entry.getValue();
		}
		int avgScore = totalScore / map.size();
		System.out.println("평균점수: " + avgScore);
		
		System.out.println("최고점수: " + maxScore);
		System.out.println("최고점수를 받은 아이디: " + name);

	}

}
<결과>
평균점수: 91
최고점수: 96
최고점수를 받은 아이디: blue

 

 

 

 

LIFO와 FIFO 컬렉션

LIFO : Last IN First Out ( 후입선출 ) 은 나중에 넣은 객체가 먼저 빠져나가는 자료구조

FIFO : First IN First Out ( 선입선출 ) 은 먼저 넣은 객체가 먼저 빠져나가는 자료구조

 

 

Stack 

Stack은 LIFO 자료구조를 구현한 클래스 

리턴 타입은 모든 메소드가 E ( Stack<E )

Push(E item) 메소드는 객체를 스택에 넣는다.

peek() 스택 맨 위 객체를 가져옴 / 객체를 스택에서 제거하지 않음

pop() 스택 맨 위 객체를 가져옴 / 객체를 스택에서 제거

 

Coin 예제 

정의

package sec02.exam03;

// 스택 예제

public class Coin {

		private int value;

		public Coin(int value) {
			super();
			this.value = value;
		}

		public int getValue() {
			return value;
		}
		
		
	
}


실행

package sec02.exam03;

import java.util.Stack;

//스택 예제

public class CoinEx {

	public static void main(String[] args) {
		Stack<Coin> coinBox = new Stack<Coin>();
		
		coinBox.push(new Coin(100));
		coinBox.push(new Coin(50));
		coinBox.push(new Coin(500));
		coinBox.push(new Coin(10));
		
		Coin coin1 = coinBox.pop();
		System.out.println("꺼내온 동전 = " + coin1.getValue()+ "원" );
		System.out.println("-----------------------------------------------");
		
		while(!coinBox.isEmpty()) {
			Coin coin = coinBox.pop();
			System.out.println("꺼내온 동전 = " + coin.getValue()+ "원" );
		}

	}

}
<결과>
꺼내온 동전 = 10원
-----------------------------------------------
꺼내온 동전 = 500원
꺼내온 동전 = 50원
꺼내온 동전 = 100

 

 

 

Queue( 큐 )

Queue 인터페이스는  FIFO 자료구조에서 사용되는 메소드를 정의하고 있다.

리턴 타입 boolean 메소드는 offer(E e) 주어진 객체를 넣는다.

리턴 타입 E peek() 객체 하나를 가져온다. 객체를 큐에서 제거하지 않는다.

리턴 타입 E poll() 객체 하나를 가져온다. 객체를 큐에서 제거한다.

Queue 인터페이스를 구혀한 대표적인 클래스는 LinkedList

 

Queue 큐 메시지 보내기 예제 

선언

package sec02.exam04;

public class Message {
	// Queue 큐
	public String command;
	public String to;
	
	
	public Message(String command, String to) {
		super();
		this.command = command;
		this.to = to;
	}
	
	
}


실행

package sec02.exam04;

import java.util.LinkedList;
import java.util.Queue;

public class QueueEx {

	public static void main(String[] args) {
		// Queue 큐
		
		Queue<Message> messageQueue = new LinkedList<Message>();
		
		messageQueue.offer(new Message("sendMail", "홍길동"));
		messageQueue.offer(new Message("sendSMS", "신용권"));
		messageQueue.offer(new Message("sendKakaotalk", "홍두께"));
		
		while(!messageQueue.isEmpty()) { // 메시지 큐가 비었는지 확인
			Message message = messageQueue.poll();// 메시지 큐에서 1개의 메시지 꺼냄 
			switch (message.command) {
			case "sendMail":
				System.out.println(message.to + "님에게 메일을 보냅니다.");
				break;
			case "sendSMS":
				System.out.println(message.to + "님에게 SMS를 보냅니다.");
				break;
			case "sendKakaotalk":
				System.out.println(message.to + "님에게 카카오톡을 보냅니다.");
				break;
			
			}
		}

	}

}
<결과>
홍길동님에게 메일을 보냅니다.
신용권님에게 SMS를 보냅니다.
홍두께님에게 카카오톡을 보냅니다.

 

 

 

 

 

+ Recent posts