JAVA/java 공부

[JAVA] 데이터입출력 (스트림)

congs 2023. 9. 12. 01:04

 

데이터입출력 (스트림)

  • 자바(프로그래밍언어)는 입력스트림, 출력스트림을 통해 데이터를 입출력함.

 

스트림 : 단방향으로 데이터가 흘러가는 형태

  1. 다양한 입출력 장치에 의해 입출력이 이루어짐
  2. 다양한 장치에 독립적으로 일관성있는 입출력을 유지하기위해

→ 입출력 스트림을 통해 일관성을 제공

 

두 가지 형태의 스트림 구분 (바이트/문자)

: (한글 가 = 2바이트, 영어 a = 1바이트)

  1. 바이트 형태의 스트림 : 기본형 (문자, 그림, 멀티미디어)
    1. 입력 : InputStream : fileInputStream, ButteredInputStream, DataInputStream
    2. 출력 : OutputStream : fileOutputStream, ButteredOutputStream, DataOutputStream
  2. 문자 형태의 스트림 : 문자만 입출력하는 경우 사용
    1. 입력: Reader : FileReader, BufferedReader, InputStreamReader
    2. 출력: Writer : FileWriter, PrintWriter, BufferedWriter

 

기반스트림 / 보조스트림

: 바이트/문자 스크림에서 더 깊게 들어가서!

       1. 기반 스트림 : 대상에서 직접 자료를 읽고 쓰는 기능이 있는 스트림

                                   ex) fileInputStream, fileOutputStream, FileReader, FileWriter

       2. 보조 스트림 : 직접 읽고 쓰는 기능은 없지만 추가적인 기능을 더해주는 스트림

                                   ex) InputStreamReader, BufferedReader, BufferedWriter, ButteredOutputStream

public static void main(String[] args) {
		
		//표준 출력(모니터=콘솔) 스트림
		System.out.println();
		
		//표준 입력(키보드) 스트림
		//int d = System.in.read(); //한바이트 읽기 -> 오류(try/catch)사용하기
		try {
			int a = System.in.read();
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
		//표준 에러 출력(모니터) 스트림
		System.err.println();
		
//===========================================================================

		// 알파벳 하나를 쓰고 enter을 누르면 알파벳을 콘솔에 출력 (Scanner사용x)
		System.out.println("알파벳 하나를 입력하고 Enter: ");
		int i;
		try {
			i = System.in.read(); //read() : 하나의 바이트 값만 받을수있음
			System.out.println(i); //i의 아스키코드값
			System.out.println((char)i);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		//알파벳 여러개를 쓰고 enter을 누리면 알파벳을 하나씩 콘솔에 출력 (read()사용)
		System.out.println("알파벳 여러개를 입력하고 Enter: ");
		int h;
		try {
			while((h=System.in.read()) != '\\n') { //enter치기 전까지 while문
				System.out.println((char)h);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

 

 

 


 

1. InputStreamReader 문자입력-출력

: 문자 입력 스트림 - 보조스트림

import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderEx {

	public static void main(String[] args) {
		// 한글을 읽고 출력 (여러글자)
		System.out.println("한글로 입력 (enter): ");
		int i;
		
		//InputStreamReader -> 보조스트림
		InputStreamReader isr = new InputStreamReader(System.in);
		try {
			while((i=isr.read()) != '\n') {
				System.out.println((char)i);
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
		
		
		
		
	}

}

 

2. InputStream (FileInputStream)

: FileInputStream : 바이트 단위 기반 스트림

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

public class InputStreamEx01 {

	public static void main(String[] args) throws IOException {
		
		// FileInputStream : 바이트 단위 기반 스트림
		byte[] b = new byte[1024];
		FileInputStream input = new FileInputStream("out.txt");
		input.read(b);
		
		//byte배열을 문자열로 변경하여 출력
		//1. 방법 1
//		String date = new String(b);
//		System.out.println(date);
		//2. 방법2
		System.out.println(new String(b));
		
		input.close();

	}

}

 

3. FileWriter 파일에 넣기 - 출력

: 문자 출력스트림 - 기반스트림

 

✔ 만들고 확인하는 방법

  1. package를 모두 닫고 f5로 파일 확인
  2. 내 워크스페이스 - java_workspace안에 파일 확인
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterEx01 {

	public static void main(String[] args) throws IOException {
		// < 문자 기반 스트림 > 
		//throws IOException 이용
		
		FileWriter fw = new FileWriter("test.txt"); //try/catch도 가능(파일이 없을 경우대비)
		
		for(int i=0; i<=10; i++) {
			String data = i+"test \r\n"; //\r\n : 캐리지리턴 (다음줄의 처음위치로 돌아가세요)
			fw.write(data);		
		}
		fw.close();//파일 닫기
		
		
		// + 파일을 추가모드로 열어라 (같은 파일명에 11~20까지 넣기) -> "파일명",true 
		FileWriter fw1 = new FileWriter("test.txt",true); 
								// ,true 추가모드로 열것인가를 boolean으로 확인! 있는 파일에 넣겠습니다
		
		for(int i=11; i<=20; i++) {
			String date = i+"test1 \r\n";
			fw1.write(date);
		}
		fw1.close();

	}

}
public class FileWriter_try {

	public static void main(String[] args) {
		//try-catch 이용
		
		try {
			FileWriter fw = new FileWriter("연습.txt");
			for(int i=0; i<=10; i++) {
				String data = i+"뿡 \r\n";
				fw.write(data);
			}
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

 

4. FileObject 파일정보출력

: 파일이 가지고 있는 정보를 출력

public static void main(String[] args) {
		// 파일이 가지고 있는 정보를 출력
		// D:\워크스페이스\java_workspace\\out.txt (파일경로)
		File f = new File("D:\\워크스페이스\\java_workspace\\out.txt");
		
		String fileName = f.getName();
		System.out.println(fileName); //only 파일명
		
		
		System.out.println(f.getPath()); //경로+파일명
		System.out.println(f.getAbsolutePath()); //절대 경로+파일명
		
		System.out.println(f.getParent()); //only 경로
		
		System.out.println(File.separator); //파일 구분자 -> \ (가장 많이 사용)
		System.out.println(File.pathSeparator);
		
		//시스템에서 알아낸 사용자 파일의 경로를 분리해보기
		
		String fstr = f.toString(); //해당경로+파일명
		System.out.println(fstr);
		//드라이브만 추출
		System.out.println(fstr.substring(0, 1)); 
		System.out.println(fstr.substring(0,fstr.indexOf(File.separator)-1));
		//파일명만 추출
		System.out.println(fstr.substring(fstr.indexOf(fileName)));
		System.out.println(fstr.substring(fstr.lastIndexOf(File.separator)+1));
		//파일경로만 추출
		System.out.println(fstr.substring(fstr.indexOf(File.separator)+1, fstr.lastIndexOf(File.separator)));
		
		//파일명과 확장자 분리추출
		System.out.println(f.getName());
		String[] str = f.getName().split(File.separator+".");
		System.out.println("파일명: "+str[0]);
		System.out.println("확장자: "+str[1]);
		
		//StringTokenizer 클래스 사용
		//각각의 값을 분리
		StringTokenizer stk = new StringTokenizer(f.getName(),".");
		while(stk.hasMoreElements()) { //토큰 요소에 값이 있다면 true리턴
			System.out.println(stk.nextElement());
		}
		
		
	}

 

5.PrintWriter 텍스트 출력

  • println, print, printf와 같은 역할
  • 개체의 형식화된 표현을 텍스트 출력 - 스트림으로 출력
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterEx01 {

	public static void main(String[] args) throws IOException {
		// PrinterWriter : 개체의 형식화된 표현을 텍스트 출력 - 스트림으로 출력
		// println, print, printf와 같은 역할
		
		PrintWriter pw = new PrintWriter(System.out);
		
		String str = "Hello";
		pw.print(str);
		pw.println(); // 줄바꿈
		pw.println(str);
		pw.printf("%.2f", Math.PI); //Math.PI = 파이값
		
		pw.flush(); // 잔류바이트 버퍼를 지우는 용도 (메모리공간에 남아있는 정보를 삭제 = clear역할)
		pw.close(); // => flush+close역할이 모두 기본으로 됨.(사실 닫으면 flush가 필요없음)
		
		PrintWriter pw1 = new PrintWriter("test2.txt");
		for(int i=0; i<=10; i++) {
			String data = i+"Test2 입니다";
			pw1.println(data); //알아서 줄을 바꿔서 입력
		}
		pw1.close();

		//추가모드로 파일에 데이터를 추가하고 싶은 경우 -> 파일 객체로 생성해서 추가 (FileWriter 이용)
		PrintWriter pw2 = new PrintWriter(new FileWriter("test2.txt",true));
		for(int i=11; i<=20; i++) {
			String date = i+"Test2 이지롱롱";
			pw2.println(date);
		}
		pw2.append('+'); //append(하나씩 추가)
		pw2.append("추가");
		pw2.close();
		
		
		
		
		
		
		
	}

}

 

6. BufferedReader 라인단위 읽기 - 추출

: 문자 보조 스트림 (Buffered가 붙으면 모두 보조스트림)

✔ 실행방법

  1. 라인단위로 읽기가 가능
  2. 더 이상 읽을 라인이 없는 경우, null을 리턴
  3. 보조스트림을 사용할 경우, 생성자에 기반스트림을 매개변수로 꼭 사용!
  4. **BufferedReader br = new BufferedReader(new FileReader("out.txt"));**
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderEx01 {

	public static void main(String[] args) throws IOException {
		// BufferedReader : 문자 기반 보조스트림
		//Buffered가 들어가면 보조스트림
		//1. 라인단위로 읽기가 가능한 기능
		//2. 더 이상 읽을 라인이 없는 경우, null을 리턴
		//3. 보조스트림을 사용할 경우 생성자에 기반 스트림을 매개변수로 꼭 포함!!
		
		BufferedReader br = new BufferedReader(new FileReader("out.txt"));
		while(true) {
			String line = br.readLine(); //한 라인씩 읽어들임
			if(line == null) { //더이상 읽을 라인이 없는 경우
				break; 
			}
			 System.out.println(line);
		}
		br.close();
		
		System.out.println("----------------");
		System.out.println("파일이 같은 java_workspace에 있지 않는경우 > ");
		
		BufferedReader br1 = new BufferedReader(new FileReader("C:\\\\Users\\\\EZENIC-172\\\\Downloads\\\\input.txt"));
		//파일이 같은 java_workspace에 있지 않는경우, 파일 위치\\\\파일명.txt
		while(true) {
			String line = br1.readLine(); //한 라인씩 읽어들임
			if(line == null) { //더이상 읽을 라인이 없는 경우
				break; 
			}
			System.out.println(line);
		}
		br1.close();
		
		
		
		
		
	}

}

 

1 ) out.txt 파일을 읽어들여 map에 저장 출력하기

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

public class BufferedReaderEx03 {

	public static void main(String[] args) throws IOException {
		// out.txt 파일을 읽어들여 map에 저장 -> 이름:점수 총합계와 인원수 출력
		
		
		BufferedReader br = new BufferedReader(new FileReader("out.txt"));
		HashMap<String, Integer> map = new HashMap<>();
		String line= br.readLine();
		while((line=br.readLine())!= null) {
			String name = line.substring(0,line.indexOf(" "));
			int score = Integer.parseInt(line.substring(line.indexOf(" ")+1));
			map.put(name, score);
		}
		br.close();
		
		System.out.println("--학생 정보--");
		int sum=0;
		int cnt = 0;
		for(String tmp : map.keySet()) {
			System.out.println(tmp+":"+map.get(tmp));
			sum += map.get(tmp);
			cnt++;
		}
		System.out.println("점수 합계: "+sum);
		System.out.println("학생 수: "+cnt);
		System.out.println("학생 평균: "+(double)sum/cnt);
		
		
		

	}

}

 

2 ) out.txt 파일을 읽어들여 out2.txt에 저장 출력하기

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class BufferedReaderEx02 {

	public static void main(String[] args) throws IOException {
		// BufferedReader, PrintWriter
		// 해당 파일을 읽어들여 복사해 객체생성
		// out.txt에서 파일읽기 -> out2.txt에 적용
		
		BufferedReader br = new BufferedReader(new FileReader("out.txt"));
		FileWriter fw = new FileWriter("out2.txt",true);
		//PrintWriter pr = new PrintWriter(System.out);
		
		
		System.out.println("읽어들이는중");
		while(true) {
			String line = br.readLine();
			if(line == null) {
				fw.close();
				break;
			}
			fw.write(line+"\n");
			System.out.println(line);
		}
		br.close();
		
//------------------------------------------------------------------------------------
		
		BufferedReader br1 = null;
		PrintWriter pw1 = null;
		
		final String Path_OUT = "out2.txt";
		System.out.println("읽어들이는중");
		 
		br1= new BufferedReader(new FileReader("out.txt"));
		pw1= new PrintWriter(new FileWriter(Path_OUT));
		
		System.out.println("복사를 위해 객체생성 완료");
		
		String line = "";
		 
		while((line= br1.readLine())!=null){
			System.out.println(line);
			pw1.println(line);
			pw1.write(line+"\r\n");
		}
		
		System.out.println("텍스트 복사 완료");
		
		if(br!=null) {
			br1.close();
		}
		if(pw1 != null) {
			pw1.close();
		}


	}

}