공부방

파일 입출력 본문

문법/기본 문법

파일 입출력

코딩 화이팅 2023. 1. 31. 16:18

I/O 와 Stream

  • I/O : 데이터의 입력(input)과 출력(output)
  • 데이터는 한쪽에서 주고 한쪽에서 받는 구조(일방통행)
    • 입력과 출력의 끝단 : 노드(Node)
    • 두 노드를 연결하고 데이터를 전송할 수 있는 개념 : 스트림(Stream)
    • 스트림은 단방향으로만 통신이 가능, 하나의 스트림으로 입력과 출력을 같이 처리할 수 없음

InputStream / OutputStream : 바이트 형식으로 뽑아내주는 스트림

Reader / Writer : char형으로 뽑아내주는 스트림

 

byte->image., exe.

char->txt.

package test01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class test1 {
	public static void main(String[] args) throws IOException {
		//byte stream
		// ->이미지
		
		FileInputStream in=null;
		FileOutputStream out=null;
		
		//여기서는 예외처리 X
		//try~finally 쓰는 이유?
		try {
			in = new FileInputStream("졸려.jpg.jpg");//입력 스트림
			out = new FileOutputStream("졸려-copy.jpg");//출력 스트림
			
			int b; //byte를 int형으로 저장해도 됨 / 묵시적 형변환 =>inputstream을 써서 byte형으로 알아서 선언이 되는건지?
			
			while((b=in.read()) !=-1) { //입력된 걸 하나씩 읽어보다가 -1이 아니면 / byte형은 값이 없을 때 -1
				out.write(b); //받은 바이트를 그대로 출력
			}
			System.out.println("복사를 완료했습니다.");
		} finally {
			//입출력 스트림을 닫아준다.
			if (in !=null) {
				in.close();
			}
			if (out !=null) {
				out.close();
			}
			System.out.println("시스템 종료");
		}
	}
}
//복사를 완료했습니다.
시스템 종료
졸려-copy.jpg라는 파일 생성
======================================================================================
package test01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class test2 {
	public static void main(String[] args) throws IOException {
		//byte stream
		// ->이미지
		
		//여기서는 예외처리 X
		//try with resource
		//try 다음에 (), ()안에 필요한 리소스를 정의
		//문장은 ; 구분
		//close할 필요 없이 알아서 close해줌
		try(FileInputStream in = new FileInputStream("졸려.jpg.jpg");FileOutputStream out = new FileOutputStream("졸려-copy2.jpg.jpg")) {
			
//			try {
//				in = new FileInputStream("졸려.jpg.jpg");//입력 스트림
//				out = new FileOutputStream("졸려-copy.jpg");//출력 스트림
//				
//				int b; //byte를 int형으로 저장해도 됨 / 묵시적 형변환 =>inputstream을 써서 byte형으로 알아서 선언이 되는건지?
//				
//				while((b=in.read()) !=-1) { //입력된 걸 하나씩 읽어보다가 -1이 아니면 / byte형은 값이 없을 때 -1
//					out.write(b); //받은 바이트를 그대로 출력
//				}
			//위에 코드에서 줄여줄 수 있다.
				
			int b; //byte를 int형으로 저장해도 됨 묵시적 형변환
			
			while((b=in.read()) !=-1) {
				out.write(b);
			}
			System.out.println("복사를 완료했습니다.");
			System.out.println("알아서 스트림을 닫아줍니다.");
		} 
	}
}
//복사를 완료했습니다.
알아서 스트림을 닫아줍니다.
졸려-copy2.jpg 파일 생성
package test01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class test3 {
	public static void main(String[] args) throws IOException {
		//byte stream
		// ->이미지
		
		//여기서는 예외처리 X
		//try with resource
		//try 다음에 (), ()안에 필요한 리소스를 정의
		//close할 필요 없이 알아서 close해줌
		try(FileInputStream in = new FileInputStream("졸려.jpg.jpg");FileOutputStream out = new FileOutputStream("졸려-copy3.jpg.jpg")) {
			
			//버퍼 사용
			byte[] buffer=new byte[10];
			int read; //byte를 int형으로 저장해도 됨 묵시적 형변환
			
			while((read=in.read(buffer)) !=-1) {
//				매번 in.read(buffer)할 때마다 buffer에 바이트를 채워줌
				//read : 어디까지가 읽으면 되는지
				out.write(buffer, 0, read);//off만큼 건너띄고 len만큼 읽어서 buf에 채움
		//						더이상 읽을게 없으면 -1 리턴
				System.out.println(Arrays.toString(buffer)+", "+read);
			}
			System.out.println("복사를 완료했습니다.");
			System.out.println("알아서 스트림을 닫아줍니다.");
		} 
	}
}
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[81, -120, 99, 9, 27, -120, 34, -128, -120, -30], 10
[-118, 40, 12, -1, -39, -120, 34, -128, -120, -30], 5
복사를 완료했습니다.
알아서 스트림을 닫아줍니다.
졸려-copy3.jpg 파일 생성

많은 값들 밑에 5번만 실행됐기 때문에 마지막에서 2번째와 마지막 줄의 
뒤에서 5칸은 같다.
package test02;

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

public class test1 {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		//character Stream-> reader, writer
		try(FileReader reader=new FileReader("big_input.txt"); FileWriter writer=new FileWriter("big_input-copy.txt")){
			int c;//charcter를 int에 담아도 됨
			while((c=reader.read())!=-1) {
				writer.write(c);
			}
			System.out.println("복사 완료");
			System.out.println("try with resource 구문을 사용해서 알아서 정리됨");
		}
		
	}
}
//
복사 완료
try with resource 구문을 사용해서 알아서 정리됨
big_input-copy.txt파일 생성

보조 스트림

Filter Stream, Processing Stream

  • 다른 스트림에 부가적인 기능을 제공하는 스트림
  • 스트림 체이닝
    • 필요에 따라 여러 보조 스트림을 연결해서 사용 가능
package test03;

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

public class test1 {
	public static void main(String[] args) throws IOException {
		test1("    FileReader & FileWriter    ");
		//FileReader & FileWriter
		test2("BufferedReader & BufferedWriter");
		//BufferedReader & BufferedWriter가 더 빠른지?
	}
	public static void test1(String testname) throws IOException {
		try(FileReader reader=new FileReader("big_input.txt"); FileWriter writer=new FileWriter("big_input-copy2.txt")){
			long start =System.nanoTime();
			int c;
			while((c=reader.read())!=-1) {
				writer.write(c);
			}
			long end=System.nanoTime();
			System.out.printf("%s - %15d ns. \n", testname, end-start);
		}
	}
	
	//보조 스트림 사용하기
	public static void test2(String testname) throws IOException {
		try(BufferedReader reader=new BufferedReader(new FileReader("big_input.txt")); BufferedWriter writer=new BufferedWriter(new FileWriter("big_input-copy3.txt"))){
			long start =System.nanoTime();
			//buffered reader&writer는 character 하나씩 읽어오는게 아님
			String line;
			while((line=reader.readLine()) !=null) {//line 단위로 들어오기 때문에 -1이 아니라 null
				writer.write(line);
				writer.newLine();//줄바꿈
			}
			long end=System.nanoTime();
			System.out.printf("%s - %15d ns. \n", testname, end-start);
		}
	}
}
//
    FileReader & FileWriter     -          196000 ns. 
BufferedReader & BufferedWriter -           71200 ns.

 

package test04;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class test1 {
	public static void main(String[] args) throws IOException {
		//Scanner vs. BufferedReader
		//big_input.txt에서 한줄씩 읽어와서 정수형으로 바꾸기
		
		test1("    scanner   ");
		test2("BufferedReader");
		//FileReader & FileWriter
	}
	public static void test1(String testname) throws IOException {
		try(Scanner sc=new Scanner(new FileInputStream("big_input.txt"))){//scanner는 byte 스트림 밖에 읽지 못하기 때문에 txt.파일이지만 FileInputStream 함수 사용 
			long start=System.nanoTime();
			while(sc.hasNext()) {//다음 값이 있다면
				int num=sc.nextInt();//scanner는 형변환을 해줘서 int형으로 저장
			}
			long end = System.nanoTime();
			System.out.printf("%s - %15d ns. \n", testname, end-start);
		}
	}
	
	public static void test2(String testname) throws IOException {
		try(BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("big_input.txt")))){
			
			//InputStreamReader : 바이트(byte)로 온걸 문자열(char)로 변환해주는 보조 스트림
			
			
			long start=System.nanoTime();
			String l;//buffer는 라인 단위
			while((l=br.readLine())!=null) {
				int num=Integer.parseInt(l);//buffer는 형변환이 되지 않아 직접 형변환 해줘야됨
			}
			long end = System.nanoTime();
			System.out.printf("%s - %15d ns. \n", testname, end-start);
		}
	}	
}
//
    scanner    -         1221000 ns. 
BufferedReader -           77200 ns.
package test05;

import java.io.File;

public class test1 {
	public static void main(String[] args) {
		//File 클래스
		//file 또는 directory의 객체 생성
		File f=new File("big_input.txt");
		System.out.println("이름 : "+f.getName());
		System.out.println("경로 : "+f.getPath());
		System.out.println("디렉토리 여부 : "+f.isDirectory());
		System.out.println("파일 여부 : "+f.isFile());
		System.out.println(f.toString());
		System.out.println(f);
	}
}
//
이름 : big_input.txt
경로 : big_input.txt
디렉토리 여부 : false
파일 여부 : true
big_input.txt
big_input.txt

객체 직렬화

  • 객체를 저장하거나 네트워크로 전송하기 위해서 연속적인 데이터로 변환하는 것
  • Serialize 인터페이스 구현
  • 직렬화에서 제외하려는 멤버는 transient 선언
package test06;

import java.io.Serializable;

public class person implements Serializable{//객체 직렬화
	private String name;
	private int age;
	
	public person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "person [name=" + name + ", age=" + age + "]";
	}
	
	
}
============================================================================
package test06;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class test1 {
	public static void main(String[] args) {
		ObjectInputStream in=null;
		ObjectOutputStream out=null;
		
		try {
			out = new ObjectOutputStream(new FileOutputStream(new File("object.dat")));
			out.writeObject(new person("강현", 26));
			System.out.println("객체를 파일에 출력했습니다.");
			
			in=new ObjectInputStream(new FileInputStream(new File("object.dat")));
			Object obj=in.readObject();//obj라는 객체를 생성해서 데이터들을 입력한다.
			person p=(person) obj;//obj라는 객체를 사람으로 형변환해준다.
			System.out.println(p);	
		}catch(Exception e){
			System.out.println("try 블록의 예외를 처리했어요");
			e.printStackTrace();
		}finally {
			try {
			if (out!=null) {
				out.close();
			}
			if (in!=null) {
				in.close();
			}
			}catch(Exception e) {
				System.out.println("중첩 try-catch문을 사용해서 예외를 처리했어요.");
			}
		}
	}
}
//
객체를 파일에 출력했습니다.
person [name=강현, age=26]
object.dat 라는 파일 생성

'문법 > 기본 문법' 카테고리의 다른 글

예외처리  (0) 2023.01.30
컬렉션  (0) 2023.01.27
인터페이스&제네릭  (0) 2023.01.26
추상클래스, 인터페이스, 제어자  (0) 2023.01.25
상속, 다형성  (0) 2023.01.20