🦁멋쟁이 사자처럼 15기/3월달 수업 내용 정리

멋쟁이 사자처럼 14회차 ( 03 / 18 )

코딩하는 하마 2025. 3. 18. 16:57

 

[학습 목표]

1. Java IO를 활용하여 파일을 읽고 쓸 수 있다. (동기화 전용)
-> 소량의 데이터 , 단일 처리 , 단방향 스트림 처리 , java.io
- File (정보용)

2. Java NIO (New IO)를 이용하여 버퍼(buffer)와 채널 (Channel)(비동기(동기도 됨))활용한 비동기 파일 입출력을 할 수 있다. -> 대량의 데이터 , 다중 처리 , 양방향(채널) 버퍼 처리 , java.nio

3. Java NIO.2(Files API, Path API)를 사용하여 파일 및 디렉토리를 생성, 복사,이동, 삭제할 수 있다.
- Files (디렉토리 파일 관리용)

4. Java IO, NIO, NIO.2 의 차이점을 이해하고 적절한 상황에서 사용할 수 있다.

 


 

Java IO 와 Java NIO

- 동기 : 싱글 스레드 ( 어떤 일을 시작하면 끝까지 끝내야 다른 일 시작 가능 )

>> 동기화 -> 파일 오픈 -> read() -> 파일 닫기

 

- 비동기 : 멀티 스레드 ( 어떤 일을 시작하고 중간에 어떤 일을 시작하거나 끝낼 수 있음 , 동시에 이것저것 함 )

 

 

1) Java IO 

https://docs.oracle.com/javase/tutorial/essential/io/index.html

 

Lesson: Basic I/O (The Java™ Tutorials > Essential Java Classes)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Dev.java for updated tutorials taking advantag

docs.oracle.com

위 링크를 참조하여 정리해보았다.

스트림 기반 : 데이터를 순차적인 스트림으로 처리 

블로킹 I/O : 읽기 / 쓰기 작업이 완료도리 때까지 스레드가 대기함 

파일 , 네트워크 , 메모리 등 다양한 입출력 지원 : 기본적인 파일 입출력 , 네트퉈크 통신, 메모리 스트림 등을 처리 

단순하고 사용하기 쉬움 : 기본적인 입출력 작업을 처리하는 데 적합.

 

 

byte _{이미지 , 영상} char _{한 글자 , char[] . String} Object _{class}
int read(byte[]) : byte

int write (byte)
read(char)
read(char[])
readLine()
write(char)
write(char[]) 
writeLine(String)
readObject()

write Object (Object)

 

여기서 Object 단위로 읽어들일 때 

class -> 파일로 읽는다 -> Object

객체 생성 (파일 <- FileOutputStream <- ObjectOutputStream <- writeObject (new Student(“111”,1,1,1))

직렬화 -> 특정클래스의 객체를 byteStream으로 변환하는 작업 ) 을 거친다. 

 

직렬화

-static : 직렬화 대상이 아님 -> 직렬화와 무관, 읽기 시점의 static 값 출력

-transient : 일시적 데이터로 직렬화 제외 ,읽기 후 null로 출력

-serialVersionUID : 직렬화 버전 관리 -> 클래스 구조 변경시 사용 권장

 

 

1) 파일 

2) 읽어오기 (BufferedInputStream)

new BuffereInputStream(new FileInputStream(new File(a.txt));

3) 버퍼에 담기

4) read() 

 

 

ex01 ) 파일에 직접 읽고 쓰기 (byte 단위로)

package com.sec13; 

//파일에 직접 담아서 가져오는 것
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//byte 단위로 읽고 쓰자.
public class d_MyIOStream {
	public static void main(String[] args) {
		String filename = "./d.txt"; 
		//File filename = new File("d.txt");
		//System.out.println(filename.getPath());
		try {
			MyWriter(filename);
			MyReader(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		// TODO Auto-generated method stub
		FileOutputStream fo = new FileOutputStream(filename);
		for(byte i ='A';i<= 'Z';i++) {
			fo.write(i); //IOException
		}
		fo.close();
		System.out.println("파일에서 A에서 Z까지 저장완료!!");
	}
	private static void MyReader(String filename) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fi = new FileInputStream(filename);
		int data;
		System.out.println(" 파일에서 읽은 데이터 ");
		while((data = fi.read()) != -1) { //한 바이트씩 읽어서 data에 대입하자 data의 값이 -1일 때까지
			System.out.print(data+"  ");
			
		}
		
		fi.close();
	}
  
} // class end

 

 

ex02 ) 버퍼에서 읽고 쓰기 (byte 단위로)

package com.sec13;

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

//버퍼 이용해서 가져오기
public class e_MyIOStream {

	public static void main(String[] args) {
		String filename = "d.txt"; 
		//File filename = new File("d.txt");
		//System.out.println(filename.getPath());
		try {
			MyWriter(filename);
			MyReader(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(filename));
		for(byte i ='A';i<= 'Z';i++) {
			bo.write(i); //IOException
		}
		bo.close();
		System.out.println("파일에서 A에서 Z까지 저장완료!!");
	}
	private static void MyReader(String filename) throws IOException {
		// TODO Auto-generated method stub
		BufferedInputStream bi = new BufferedInputStream(new FileInputStream(filename));
		int data;
		System.out.println(" 파일에서 읽은 데이터 ");
		while((data = bi.read()) != -1) { //한 바이트씩 읽어서 data에 대입하자 data의 값이 -1일 때까지
			System.out.print(data+"  ");
			
		}
		
		bi.close();
	}
  
}

 

 

ex03) 파일에서 직접 읽고 쓰기 (char 단위로)

package com.sec13;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//char 단위로 읽고 쓰자.
public class f_MyIOStream {
	public static void main(String[] args) {
		String filename = "f.txt"; 

		try {
			MyWriter(filename);
			MyReader(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		// TODO Auto-generated method stub
		FileWriter fw = new FileWriter(filename);
		for(char i ='A';i<= 'Z';i++) {
			fw.write(i); //IOException
		}
		fw.close();
		System.out.println("파일에서 A에서 Z까지 저장완료!!");
	}
	private static void MyReader(String filename) throws IOException {
		// TODO Auto-generated method stub
		FileReader fr = new FileReader(filename);
		int data=0;
		System.out.println(" 파일에서 읽은 데이터 ");
		while((data = fr.read()) != -1) { 
			System.out.print((char)data+"  ");
			
		}
		
		fr.close();
	}
  
} // class end

 

 

ex04) 버퍼로 읽고 쓰기 (char단위로)

package com.sec13;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//버퍼 이용해서 가져오기 
//char 단위를 BufferedReader, BufferedWriter 로 읽고 쓰자.
public class g_MyIOStream2 {

	public static void main(String[] args) {
		String filename = "g.txt"; 

		try {
			MyWriter(filename);
			MyReader(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		BufferedWriter bw = new BufferedWriter (new FileWriter(filename));
		for(char i ='A';i<= 'Z';i++) {
			bw.write(i); //IOException
		}
		bw.close();
		System.out.println("파일에서 A에서 Z까지 저장완료!!");
	}
	private static void MyReader(String filename) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(filename));
		int data=0;
		System.out.println(" 파일에서 읽은 데이터 ");
		while((data = br.read()) != -1) { //0 ~ 65535 코드 값으로 data에 대입하자 -1이 될 때까지
			System.out.print((char)data+"  ");
			
		}
		
		br.close();
	}
  
}

 

 

ex05) 버퍼로 읽고 쓰기 (char 단위로) - readLine()으로 읽어들이기

package com.sec13;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//버퍼 이용해서 가져오기 
//char 단위를 BufferedReader, BufferedWriter 로 읽고 쓰자.
public class g_MyIOStream2 {

	public static void main(String[] args) {
		String filename = "g.txt"; 

		try {
			MyWriter(filename);
			MyReader02(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		BufferedWriter bw = new BufferedWriter (new FileWriter(filename));
		for(char i ='A';i<= 'Z';i++) {
			bw.append(i); //IOException
		}
		bw.close();
		System.out.println("파일에서 A에서 Z까지 저장완료!!");
	}
	private static void MyReader02(String filename) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader(filename));
		String data = null;
		System.out.println(" 파일에서 읽은 데이터 ");
		while((data = br.readLine()) != null) { //0 ~ 65535 코드 값으로 data에 대입하자 -1이 될 때까지
			System.out.println(data);
			
		}
		
		br.close();
	}
  
}

 

 

ex06) 파일로 읽고 쓰기 (Object 단위로)

package com.sec13;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//Object 단위로 읽고 쓰자.
class Student implements Serializable { //직렬화  (해당 클래스를 바이트 스트림으로 변환하겠다)
private String name;
private int age;
private int height;
private int weight;


public Student()  {
	super();
	// TODO Auto-generated constructor stub
}

public Student(String name, int age, int height, int weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public int getHeight() {
return height;
}

public int getWeight() {
return weight;
}

public String studentInfo() {
	return 
			String.format("%10s  %5d %5d  %5d \n",this.getName(), this.getAge(), this.getHeight() , this.getWeight());
}
/*public void studentInfo() {
System.out.println(name + "\t" + age + "\t" + height + "\t" + weight);
}*/
public String toString() {
	return 
			String.format("%10s %5d  %5d %5d \n", this.getName(), this.getAge(),this.getHeight(),this.getWeight());
}
}

public class h_MyObject2 {

	public static void main(String[] args) {
		String filename = "h.txt"; 

		try {
			MyWriter(filename);
			MyReader02(filename);
			
		}catch(Exception e) {
			System.out.println(e);
		} //try end
		
	}
	
	private static void MyWriter(String filename) throws IOException {
		ObjectOutputStream oo = new ObjectOutputStream (new FileOutputStream(filename));
		oo.writeObject(new Student("111",1,1,1));
		oo.writeObject(new Student("222",2,2,2));
		oo.writeObject(new Student("333",3,3,3));
		oo.close();
		System.out.println("파일에 객체를 저장했어");
	}
	private static void MyReader02(String filename) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
		ObjectInputStream oi = new ObjectInputStream(new FileInputStream(filename));
		System.out.println(oi.readObject());
		System.out.println(oi.readObject());
		System.out.println(oi.readObject());
		System.out.println("파일에서 읽은 데이터");
		oi.close();
		
		oi.close();
	}
  
}

 

 

2) Java NIO (New I/O)

버퍼 기반: 데이터를 버퍼에 저장하고 처리한다.

논블로킹 I/O: 읽기/쓰기 작업이 완료되지 않아도 스레드가 다른 작업을 수행한다.

채널과 셀렉터: 채널을 통해 입출력을 수행하고, 셀렉터를 사용하여 여러 채널을 효율적으로 관리

고성능 I/O: 대규모 네트워크 애플리케이션 등 고성능 I/O가 필요한 경우에 적합하다.

 

ex)

package com.sec13;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

//nio -> buffer와 channel을 적절히 주면 된다.
public class b_nio {
    public static void myread() {
        try (FileChannel channel = FileChannel.open(Paths.get("a.txt"), StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (channel.read(buffer) > 0) {
                buffer.flip();
                System.out.print(new String(buffer.array(), 0, buffer.limit()));
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void mywrite(String content) {
        try (FileChannel channel = FileChannel.open(Paths.get("./a.txt"), StandardOpenOption.APPEND)) {
            ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
            channel.write(buffer);
            buffer = ByteBuffer.wrap(System.lineSeparator().getBytes());
            channel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println("NIO Read:");
        myread();
        System.out.println("\nNIO Write:");
        mywrite("Appended using NIO.");
        myread();
    }
}

 

 


 

Java NIO file ( NIO.2)

파일 시스템 API: 파일 및 디렉터리 작업을 위한 강력하고 유연한 API를 제공한다

Path 인터페이스: 파일 경로를 추상화하여 플랫폼 독립적인 코드를 작성할 수 있도록 한다.

Files 클래스: 파일 복사, 이동, 삭제, 속성 관리 등 다양한 파일 시스템 작업을 지원한다.

파일 시스템 작업에 특화: 파일 시스템 관련 작업을 보다 쉽고 효율적으로 처리한다.

 

ex)

package com.sec13.myNio;

import java.nio.file.*;
//D : Test
//    -AA
//    -BB
//     -a.txt 파일을 생성해보자.
public class a_NIO2 {

	public static void main(String[] args) throws Exception {
		// Q1. D: Test  폴더를 생성하자
		Path test = Paths.get("C:\\test");
		Files.createDirectory(test);
		//Q2. test\\AA
		Path aadir = test.resolve("AA");
		Files.createDirectories(aadir);
		//Q3. test\\BB 폴더 생성
		Path bbdir = test.resolve("BB");
		Files.createDirectories(bbdir);
		
		//Q4. test\\BB\\a.txt 폴더 생성
		Path atxt = bbdir.resolve("a.txt");
		Files.createFile(atxt);
		System.out.println("완료!!!");
		
		//Q5. test\\BB\\a.txt 파일만 삭제하기
		Files.delete(atxt);
		System.out.println("삭제 완료");
	}

}