자바 파일 입출력

강효림·2023년 9월 20일
0

JAVA

목록 보기
19/19

Stream (스트림)

스트림 입출력이란!
버퍼를 가지고 순차적으로 이루어지는 입출력

  • 입력 스트림 : 입력장치로 부터 자바 프로그램으로 데이터 전달
  • 출력 스트림 : 출력장치로 데이터 출력
    동시에 일어나지 않음!!
    오직 단방향!!!
    선입선출 구조!!

BiteStream

단위 : byte
최상위 클래스 - InputStream & OutputStream
상속받는 클래스들 이름 끝에 Stream으로 끝남

BiteStreamClass

  • InputStream / OutputStream
    추상클래스
    바이트 스트림을 다루는 모든 클래스의 슈퍼클래스

  • FileInputStream / FileOutputStream
    파일로부터 바이트 단위로 읽거나 저장하는 클래스
    바이너리 파일의 입출력 용도

  • DataInputStream / DataOutputStream
    자바의 기본 데이터 타입의 값을 바이너리 값 그대로 입출력
    문자열도 바이너리 형태로 입출력

FileOutputStream으로 바이너리 파일 쓰기 예제

public static void main(String[] args) {
		byte b[] = {4,25,75,73,-1};
		
		try {
			FileOutputStream fout = new FileOutputStream("C:\\Temp\\test.out");
			for(int i = 0; i<b.length; i++) {
				fout.write(b[i]);
			}
			fout.close();
		}catch(IOException e){
			System.out.println("error");
			return;
		}
		System.out.println("save");
}

FileInputStream으로 바이너리 파일 읽기 예제

위에서 만든 test.out에 저장된 배열 읽어오기

public static void main(String[] args) {
		byte b[] = new byte[5];
		
		try{
			FileInputStream fin = new FileInputStream("C:\\Temp\\test.out");
			int n = 0,c;
			
			while((c= fin.read())!= -1) {
				b[n] = (byte)c;
				n++;
			}
			System.out.println("배열 출력");
			for(int i = 0; i<b.length; i++) {
				System.out.println(b[i]+ " ");
			}
			fin.close();
			
		}catch(IOException e) {
			System.out.println("error");
		}
}

문자 스트림

단위 : 유니코드 (2byte)
최상위 클래스 - Reader & Writer
Reader를 상속받는 클래스들 이름 끝에는 Reader가,
Writer를 상속받는 클래스들 이름 끝에는 Writer가 붙는다.

  • 문자 스트림은 뒤에 Stream은 붙이지 않는다.

FileReader로 텍스트 파일 읽기 예제

public static void main(String[] args) {
		FileReader fr = null;

		try {
			fr = new FileReader("C:\\Temp\\file.txt");
			int c;

			while((c = fr.read()) != -1)
				System.out.println((char)c);  //한 글자 씩 읽어오기
			fr.close();
		}catch(IOException e){
			System.out.println("error");
		}
}

InputStreamReader로 한글 텍스트 파일 읽어오는 예제

public static void main(String[] args) {
		InputStreamReader in = null;
		FileInputStream fs = null;
		
		try {
			fs = new FileInputStream("C:\\Temp\\test.txt");
			in = new InputStreamReader(fs, "ANSI"); //한글 읽어오는 인코딩타입
			int c;
			
			System.out.println("인코딩 문자 집합 : " + in.getEncoding());
			
			while((c=in.read())!=-1) {
				System.out.println((char)c);
			}
			in.close(); //나중에 객체 생성한 것 부터 닫아주기
			fs.close(); 
		}catch(IOException e) {
			System.out.println("error");
		}
}

인코딩 타입이 잘못 지정되면 읽은 문자가 제대로 인식되지 않아 출력 결과가 깨진다.

FileWriter

  • 파일 문자 단위 쓰기
    문자를 하나씩 입력해서 쓰기

  • 파일 블록 단위 쓰기
    배열로 크기를 지정하고 배열크기 만큼 쓰기

FileWriter를 사용해 키보드로 입력받은 것을 파일로 저장하는 예제

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		FileWriter fout = null;
		int c;
		
		try {
			fout = new FileWriter("C:\\Temp\\test4.txt");
			while(true) {
				String line = sc.nextLine();
				if(line.length() == 0) break;
				
				fout.write(line, 0, line.length());
				fout.write("\r\n",0,2);
			}
			fout.close();
		}catch(IOException e) {
			System.out.println("error");
		}
}

BufferStream

버퍼 입출력 스트림과 버퍼 입출력의 특징

  • 버퍼스트림
    버퍼를 가진 스트림
    입출력 데이터를 일시적으로 저장하는 버퍼를 이용하여 입출력 효율 개선

  • 버퍼 입출력의 목적
    입출력 시 운영체제의 api 호출 횟수를 줄여 입출력 성능 개선

바이트 버퍼 스트림

바이트 단위의 바이너리 데이터를 처리하는 버퍼 스트림

  • BufferedInputStream
  • BufferedOutputStream

BufferStream을 이용한 출력 예제

public static void main(String[] args) {
		FileReader fin = null;
		int c = 0;
		
		try {
			fin = new FileReader("C:\\Temp\\test.txt");
			BufferedOutputStream out = new BufferedOutputStream(System.out, 5);
			while((c=fin.read())!= -1)
				out.write(c); //버퍼가 꽉 찰 때 문자가 화면에 출력
			
			Scanner sc = new Scanner(System.in);
			out.flush(); //버퍼에 남아있던 문자 모두 출력
			
			out.close();
			fin.close();
		}catch(IOException e) {
			e.printStackTrace();
		}
}

문자 버퍼 스트림

유니코드의 문자 데이터만 처리하는 버퍼 스트림

  • BufferedReader
  • BufferedWriter

File 클래스

  • 파일의 경로명을 다루는 클래스
  • 파일 관리 기능
    파일 이름 변경, 삭제, 디렉터리 생성, 크기 등 파일 관리
    읽고쓰는 기능은 없다.

File 클래스 활용한 파일 관리

public static void listDirectory(File dir) {
		System.out.println(dir.getPath() + "의 서브 리스트");
		File[] subFiles = dir.listFiles();
		
		for(int i = 0; i<subFiles.length; i++) {
			File f = subFiles[i];
			long t = f.lastModified();
			System.out.println(f.getName());
			System.out.println("파일 크기 " + f.length());
			System.out.printf("수정 시간 %tb %td %ta %tT",t,t,t,t);
			
		}
	}

	public static void main(String[] args) {
		File f1 = new File("C:\\windows\\system.ini");
		System.out.println(f1.getPath() + " " + f1.getParent() + " " + f1.getName());
		
		String res = "";
		if(f1.isFile()) res = "파일";
		else if(f1.isDirectory()) res = "디렉토리";
		System.out.println(f1.getPath() + "는 " + res);
		
		File f2 = new File("c:\\Temp\\java_sample"); 
		if(!f2.exists()) {
			f2.mkdir(); // 존재하지 않으면 디렉토리 생성
		}
		listDirectory(new File("c:\\Temp")); 
		f2.renameTo(new File("c:\\Temp\\javasample")); 
		listDirectory(new File("c:\\Temp"));
	}

텍스트 파일 복사 예제

public static void main(String[] args) {
		File src = new File("C:\\windows\\system.ini");
		File dest = new File("C:\\Temp\\system.txt");
		
		int c;
		try {
			FileReader fr = new FileReader(src);
			FileWriter fw = new FileWriter(dest);
			
			while((c=fr.read())!= -1)
				fw.write((char)c);
			
			fr.close();
			fw.close();
			System.out.println("복사완료");
		}catch(IOException e) {
			System.out.println("error");
		}
}

바이너리 파일(이미지) 복사 예제

public static void main(String[] args) {
		File src = new File("C:\\Users\\PC\\Pictures\\Screenshots\\insta.png");
		File dest = new File("C:\\Temp\\copyimg.png");
		int c;
		
		try {
			FileInputStream fi = new FileInputStream(src);
			FileOutputStream fo = new FileOutputStream(dest);
			
			while((c=fi.read())!= -1)
				fo.write((byte)c);
			fi.close();
			fo.close();
			System.out.println("복사완료");
		}catch(IOException e) {
			System.out.println("error");
		}
}

블록 단위로 바이너리 파일 고속 복사

public static void main(String[] args) {
		File src = new File("C:\\Users\\PC\\Pictures\\Screenshots\\insta.png");
		File dest = new File("C:\\Temp\\fastcopyimg.png");
		
		try {
			FileInputStream fi = new FileInputStream(src);
			FileOutputStream fo = new FileOutputStream(dest);
			byte[] buf = new byte[1024*10];  //10KB 버퍼
			
			while(true) {
				int n = fi.read(buf);
				fo.write(buf, 0, n);
				
				if(n<buf.length)
					break;
			}
			
			fi.close();
			fo.close();
			System.out.println("copied");
		}catch(IOException e) {
			System.out.println("error");
		}
		
}

0개의 댓글