** ๐1๋จ๊ณ: ์ ์ถ๋ ฅ ์คํธ๋ฆผ์ด๋? **
- *์คํธ๋ฆผ(Stream)์ ๋ฐ์ดํฐ๊ฐ ์ง๋๊ฐ๋ ๊ธธ(ํต๋ก)**์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ผ์.
- ์ ๋ ฅ ์คํธ๋ฆผ(Input Stream): ๋ฐ์ดํฐ๋ฅผ โ์ฝ์ด์ค๋โ ๊ธธโ ์: ์ฑ ์ ์ฝ๋ ๊ฒ, ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ฒ
- ์ถ๋ ฅ ์คํธ๋ฆผ(Output Stream): ๋ฐ์ดํฐ๋ฅผ โ๋ณด๋ด๋โ ๊ธธโ ์: ๊ธ์ ์ฐ๋ ๊ฒ, ํ๋ฉด์ ์ถ๋ ฅํ๋ ๊ฒ
๐ก ๋นจ๋๋ก ์ฃผ์ค๋ฅผ ๋ง์๋ ๊ฑธ ๋ ์ฌ๋ ค ๋ณด์ธ์.
์ฃผ์ค(๋ฐ์ดํฐ)๊ฐ ์ปต(ํ์ผ)์์ ์ (ํ๋ก๊ทธ๋จ)์ผ๋ก ๋ค์ด์ค๋ ๊ฒ์ด ์ ๋ ฅ ์คํธ๋ฆผ์ด๊ณ ,
์ฃผ์ค๋ฅผ ๋ค๋ฅธ ์ปต(ํ์ผ)์ผ๋ก ๋ถ๋ ๊ฒ์ด ์ถ๋ ฅ ์คํธ๋ฆผ์ด์์!
2๋จ๊ณ: ์คํธ๋ฆผ์ ์ข ๋ฅ (๋ฐ์ดํธ ์คํธ๋ฆผ vs. ๋ฌธ์ ์คํธ๋ฆผ)
๐ ๋ฐ์ดํธ ์คํธ๋ฆผ (Byte Stream)
- 1๋ฐ์ดํธ(8๋นํธ) ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์.
- ์ด๋ฏธ์ง, ๋์์, ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ๋ค๋ฃฐ ๋ ์ฌ์ฉํด์.
- ๋ํ ํด๋์ค:
InputStream
,OutputStream
๐ ๋ฌธ์ ์คํธ๋ฆผ (Character Stream)
- 2๋ฐ์ดํธ(16๋นํธ) ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์.
- ๋ฌธ์(ํ ์คํธ) ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ์ ํฉํด์.
- ๋ํ ํด๋์ค:
Reader
,Writer
๐ก ๋น์ :
๋ฐ์ดํธ ์คํธ๋ฆผ์ ์ํ๋ฒณ ํ ๊ธ์์ฉ ์ฝ๋ ๊ฒ,
๋ฌธ์ ์คํธ๋ฆผ์ ๋ฌธ์ฅ ๋จ์๋ก ์ฝ๋ ๊ฒ์ด์์!
3๋จ๊ณ: ์คํธ๋ฆผ ํด๋์ค ๊ตฌ์กฐ์ ์์ ๊ด๊ณ
์๋ฐ์ ์ ์ถ๋ ฅ ์คํธ๋ฆผ์ ๋ถ๋ชจ-์์ ๊ด๊ณ(์์)๋ก ๊ตฌ์ฑ๋์ด ์์ด์.
๐ ๋ฐ์ดํธ ์คํธ๋ฆผ ๊ตฌ์กฐ
InputStream
(์ต์์ ํด๋์ค)FileInputStream
(ํ์ผ ์ฝ๊ธฐ)BufferedInputStream
(๋น ๋ฅด๊ฒ ์ฝ๊ธฐ)
OutputStream
(์ต์์ ํด๋์ค)FileOutputStream
(ํ์ผ ์ฐ๊ธฐ)BufferedOutputStream
(๋น ๋ฅด๊ฒ ์ฐ๊ธฐ)
๐ ๋ฌธ์ ์คํธ๋ฆผ ๊ตฌ์กฐ
Reader
(์ต์์ ํด๋์ค)FileReader
(ํ์ผ์์ ๋ฌธ์ ์ฝ๊ธฐ)BufferedReader
(ํ ์ค์ฉ ๋น ๋ฅด๊ฒ ์ฝ๊ธฐ)
Writer
(์ต์์ ํด๋์ค)FileWriter
(ํ์ผ์ ๋ฌธ์ ์ฐ๊ธฐ)BufferedWriter
(ํ ์ค์ฉ ๋น ๋ฅด๊ฒ ์ฐ๊ธฐ)
๐ก ๋น์ :
์ด๊ฑด ๋ง์น, โ์๋ง(๋ถ๋ชจ ํด๋์ค)์ ์๋ค(์์ ํด๋์ค)โ ๊ฐ์ ๊ด๊ณ์์.
์๋ง๊ฐ ๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ๋ฅผ ๊ฐ๋ฅด์ณ์ฃผ๊ณ , ์๋ค์ ๊ทธ๊ฑธ ์์ฉํด์ ๋ ๋ง์๊ฒ ๋ง๋ค ์ ์์ฃ !
4๋จ๊ณ: ์คํธ๋ฆผ ์ฒด์ด๋ (Chaining)๊ณผ ๋ฐ์ฝ๋ ์ดํฐ ํจํด
์คํธ๋ฆผ์ ์ฌ๋ฌ ๊ฐ ์ฐ๊ฒฐํด์ ์ฌ์ฉํ๋ฉด ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋ง๋ค ์ ์์ด์.
์ด๊ฑธ ์คํธ๋ฆผ ์ฒด์ด๋ (Chaining)์ด๋ผ๊ณ ํด์.
๐ ์์ : ํ์ผ์ ์ฝ์ ๋ ๋ฒํผ๋ฅผ ์ถ๊ฐํ๋ฉด ์๋๊ฐ ๋นจ๋ผ์ง
FileInputStream fis = new FileInputStream("data.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileInputStream
โ ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ โ์ง์ โ ์ฝ์BufferedInputStream
โ ๋ฒํผ๋ฅผ ์ฌ์ฉํด ๋ ๋น ๋ฅด๊ฒ ์ฝ์
๐ก ๋น์ :
์์์ ๋จน์ ๋ โ์๊ฐ๋ฝโ์ ์ฌ์ฉํ๋ฉด ๋ ํธํ์ฃ ?
์คํธ๋ฆผ ์ฒด์ด๋์ ๊ทธ๋ฆ โ ์๊ฐ๋ฝ โ ์ ์ฒ๋ผ ๋๊ตฌ๋ฅผ ์ถ๊ฐํด ๋ ํจ์จ์ ์ผ๋ก ๋จน๋ ๊ฒ๊ณผ ๊ฐ์์.
5๋จ๊ณ: ํ์ค ์ ์ถ๋ ฅ (System.in, System.out, System.err)
์๋ฐ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ์ ๋ ฅ/์ถ๋ ฅ ์คํธ๋ฆผ
๐ System.in โ ํค๋ณด๋ ์
๋ ฅ (InputStream
)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
๐ System.out โ ํ๋ฉด ์ถ๋ ฅ (PrintStream
)
System.out.println("Hello, World!");
๐ System.err โ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ
System.err.println("์ค๋ฅ ๋ฐ์!");
๐ก ๋น์ :
- System.in โ โ์ฌ๋์ด ๊ท๋ก ๋ฃ๋ ๊ฒโ
- System.out โ โ์ฌ๋์ด ์ ์ผ๋ก ๋งํ๋ ๊ฒโ
- System.err โ โ์ฌ๋์ด ๋๋ผ์ ์๋ฆฌ์น๋ ๊ฒโ
6๋จ๊ณ: ๊ฐ์ฒด ์ง๋ ฌํ (Serialization)
๐ ์ง๋ ฌํ๋?
โ์๋ฐ ๊ฐ์ฒด๋ฅผ ํ์ผ์ ์ ์ฅํ๊ฑฐ๋ ๋คํธ์ํฌ๋ก ๋ณด๋ด๋ ๊ฒโ
๐ ์ญ์ง๋ ฌํ๋?
โ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์๋ฐ ๊ฐ์ฒด๋ก ๋ณํํ๋ ๊ฒโ
๐ ์ง๋ ฌํ ์์
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.ser"));
oos.writeObject(new Person("ํ๊ธธ๋", 25));
oos.close();
๐ ์ญ์ง๋ ฌํ ์์
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.ser"));
Person person = (Person) ois.readObject();
ois.close();
๐ก ๋น์ :
- ์ง๋ ฌํ โ โ๋ก๋ด์ ๋ถํ์ผ๋ก ๋ถํดํด์ ๋ฐ์ค์ ๋ฃ๊ธฐโ
- ์ญ์ง๋ ฌํ โ โ๋ฐ์ค์์ ๋ถํ์ ๊บผ๋ด ๋ค์ ์กฐ๋ฆฝํ๊ธฐโ
7๋จ๊ณ: ๊ณ ์ฑ๋ฅ ์ ์ถ๋ ฅ (NIO & NIO.2)
๐ NIO(New I/O)๋?
๊ธฐ์กด I/O๋ณด๋ค ๋ ๋น ๋ฅธ ์ ์ถ๋ ฅ ๋ฐฉ์์ ์ ๊ณตํ๋ ์๋ฐ API
๐ NIO์ ํต์ฌ ๊ฐ๋
- ๋ฒํผ (Buffer) โ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ณต๊ฐ
- ์ฑ๋ (Channel) โ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ํต๋ก
- ์ ๋ ํฐ (Selector) โ ์ฌ๋ฌ ๊ฐ์ ์ฑ๋์ ๊ด๋ฆฌ
๐ NIO ์์ : ํ์ผ ๋ณต์ฌ
FileChannel inChannel = FileChannel.open(Paths.get("source.txt"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("destination.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inChannel.read(buffer) > 0) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
๐ก ๋น์ :
๊ธฐ์กด I/O๋ ํ ์ค์ฉ ์ข ์ด๋ฅผ ๋๊ฒจ ์ฝ๋ ๊ฒ,
NIO๋ ํ ํ์ด์ง๋ฅผ ํต์งธ๋ก ๋๊ฒจ ๋น ๋ฅด๊ฒ ์ฝ๋ ๊ฒ์ด์์.
๐ ์ ๋ฆฌ
โ ์คํธ๋ฆผ(Stream) โ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ํต๋ก
โ ๋ฐ์ดํธ ์คํธ๋ฆผ vs ๋ฌธ์ ์คํธ๋ฆผ โ ๋ฐ์ดํธ(1Byte) vs ๋ฌธ์(2Byte)
โ ์คํธ๋ฆผ ์ฒด์ด๋ โ ์ฌ๋ฌ ์คํธ๋ฆผ์ ์ฐ๊ฒฐํด ์ฑ๋ฅ ํฅ์
โ ํ์ค ์ ์ถ๋ ฅ โ System.in, System.out, System.err
โ ์ง๋ ฌํ โ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ๋ณต์ํ๋ ๊ธฐ๋ฅ
โ NIO โ ๊ณ ์ฑ๋ฅ ์ ์ถ๋ ฅ ๋ฐฉ์
๐ 8๋จ๊ณ: ๊ณ ๊ธ ์ ์ถ๋ ฅ ์ต์ ํ ๊ธฐ๋ฒ
์๋ฐ ์ ์ถ๋ ฅ ์คํธ๋ฆผ์ ๋ ๋น ๋ฅด๊ฒ ์คํํ๋ ค๋ฉด ์ต์ ํ ๊ธฐ๋ฒ์ ์ ์ฉํด์ผ ํด์.
1. ๋ฒํผ(Buffer) ํ์ฉ
๋ฒํผ๋ง(Buffering)์ด๋?
- ๋ฐ์ดํฐ๋ฅผ ํ๊บผ๋ฒ์ ๋ชจ์์ ์ ์ถ๋ ฅํ๋ ๊ธฐ๋ฒ
- ๋งค๋ฒ 1๋ฐ์ดํธ์ฉ ์ฝ๊ธฐ๋ณด๋ค ํ ๋ฒ์ 1024๋ฐ์ดํธ(1KB)์ฉ ์ฝ์ผ๋ฉด ์๋ ํฅ์
- BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter ์ฌ์ฉ
๐ ์์ : ๋ฒํผ๋ฅผ ์ฌ์ฉํ ํ์ผ ๋ณต์ฌ (๋ ๋น ๋ฆ!)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("destination.txt"));
byte[] buffer = new byte[1024]; // 1KB ๋ฒํผ
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bis.close();
bos.close();
โ ๋ฒํผ๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ผ ์ ์ถ๋ ฅ ์๋๊ฐ 2~3๋ฐฐ ๋นจ๋ผ์ ธ์!
2. try-with-resources (์๋ ์์ ํด์ )
- ๊ธฐ์กด์ try-catch ๋ฐฉ์์์๋ finally ๋ธ๋ก์์ close()๋ฅผ ํธ์ถํด์ผ ํ์ด์.
- try-with-resources ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ฉด ์๋์ผ๋ก ์คํธ๋ฆผ์ ๋ซ์์ค์!
- ์๋ฐ 7(Java 7) ์ด์์์ ์ฌ์ฉ ๊ฐ๋ฅ
๐ ์์ : try-with-resources๋ก ์๋ ์์ ํด์
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
โ
try ๋ธ๋ก์ด ๋๋๋ฉด ์๋์ผ๋ก br.close()
์คํ๋จ!
3. Direct Buffer ํ์ฉ (NIO)
- ์ผ๋ฐ
ByteBuffer
๋ Heap Memory(์๋ฐ ํ ๋ฉ๋ชจ๋ฆฌ)๋ฅผ ์ฌ์ฉํด์. DirectByteBuffer
๋ OS์ ๋ค์ดํฐ๋ธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ๋ ๋น ๋ฆ!- ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๊ฐ ํ์ํ ๋ ์ ์ฉ!
๐ ์์ : Direct Buffer ์ฌ์ฉ
ByteBuffer buffer = ByteBuffer.allocateDirect(1024); // Direct Buffer ์์ฑ
โ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๊ฐ ์ ์ด ์๋๊ฐ ํจ์ฌ ๋นจ๋ผ์ ธ์!
๐ 9๋จ๊ณ: ๋ณด์(Security) & ์ํธํ(Encryption)
๋คํธ์ํฌ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ฑฐ๋, ์ค์ํ ํ์ผ์ ์ ์ฅํ ๋๋ ๋ณด์์ด ์ค์ํด์!
์๋ฐ์์๋ ์ํธํ์ ๋ณตํธํ ๊ธฐ๋ฅ์ ์ ๊ณตํด์.
1. ๋ฐ์ดํฐ ์ํธํํ๊ธฐ (AES)
- *AES (Advanced Encryption Standard)๋ **๊ฐ๋ ฅํ ์ํธํ ์๊ณ ๋ฆฌ์ฆ
javax.crypto
ํจํค์ง๋ฅผ ํ์ฉ
๐ ์์ : AES๋ก ํ์ผ ์ํธํ
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;
public class AESEncryption {
public static void main(String[] args) throws Exception {
// ์ํธํ ํค ์์ฑ
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
// ์ํธํ
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal("๋น๋ฐ ๋ฉ์์ง".getBytes());
System.out.println("์ํธํ๋ ๋ฐ์ดํฐ: " + Base64.getEncoder().encodeToString(encrypted));
}
}
โ AES๋ฅผ ํ์ฉํ๋ฉด ์ค์ํ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ ์ ์์ด์!
๐ 10๋จ๊ณ: ๋คํธ์ํฌ ์ ์ถ๋ ฅ (Socket I/O)
์๋ฐ์์๋ ๋คํธ์ํฌ ํต์ ์ ์ํด ์์ผ(Socket)์ ์ฌ์ฉํ ์ ์์ด์.
1. ์๋ฒ ๋ง๋ค๊ธฐ (Socket Server)
ServerSocket
์ ์ฌ์ฉํด ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ์ ์ ์์ด์.- ๋คํธ์ํฌ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ์ ์ถ๋ ฅ ์คํธ๋ฆผ์ ํ์ฉ!
๐ ์์ : ์๋ฒ ๋ง๋ค๊ธฐ
import java.io.*;
import java.net.*;
public class ServerExample {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(5000);
System.out.println("์๋ฒ๊ฐ ์คํ ์ค...");
Socket clientSocket = serverSocket.accept(); // ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ๋๊ธฐ
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String input = in.readLine();
System.out.println("ํด๋ผ์ด์ธํธ: " + input);
out.println("์๋ฒ ์๋ต: " + input.toUpperCase());
clientSocket.close();
serverSocket.close();
}
}
โ ๋คํธ์ํฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ด์!
๐ 11๋จ๊ณ: ํ์ผ ์์คํ ์กฐ์ (NIO.2 ํ์ฉ)
์๋ฐ NIO.2 (java.nio.file
)๋ฅผ ํ์ฉํ๋ฉด ๋ ๊ฐ๋ ฅํ ํ์ผ ์กฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ด์.
1. ํ์ผ ๋ณต์ฌ & ์ด๋
๐ ์์ : ํ์ผ ๋ณต์ฌํ๊ธฐ
import java.nio.file.*;
public class FileCopyExample {
public static void main(String[] args) throws Exception {
Path source = Paths.get("source.txt");
Path destination = Paths.get("destination.txt");
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("ํ์ผ ๋ณต์ฌ ์๋ฃ!");
}
}
โ
Files.copy()
๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ํ์ผ์ ๋ณต์ฌํ ์ ์์ด์!
๐ 12๋จ๊ณ: ์ค์ ํ๋ก์ ํธ ํ์ฉ
์ด์ ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ ์ค์ ์์ ์ด๋ป๊ฒ ํ์ฉํ ์ ์๋์ง ์์๋ณผ๊ฒ์.
1. ๋ก๊ทธ ์์คํ ๊ตฌํ
FileWriter
์BufferedWriter
๋ฅผ ํ์ฉํด ๋ก๊ทธ ์์คํ ์ ๊ตฌํํ ์ ์์ด์.- ์๋ฒ๊ฐ ๋์ํ๋ ๋์ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๊ธฐ๋ฅ์ ๋ง๋ค ์ ์์ด์.
๐ ์์ : ๋ก๊ทธ ์์คํ
import java.io.*;
import java.time.LocalDateTime;
public class Logger {
public static void log(String message) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("log.txt", true))) {
writer.write(LocalDateTime.now() + " - " + message);
writer.newLine();
}
}
public static void main(String[] args) throws IOException {
log("์๋ฒ ์์๋จ.");
log("์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํจ.");
}
}
โ ์๋ฒ์ ๋์์ ๊ธฐ๋กํ ์ ์์ด์!
๐ ์ ๋ฆฌ: ์๋ฐ ์ ์ถ๋ ฅ ์คํธ๋ฆผ ์์ ์ ๋ณต
๋จ๊ณ | ์ฃผ์ |
---|---|
1~7 | ๊ธฐ๋ณธ ๊ฐ๋ , ์คํธ๋ฆผ์ ์ข ๋ฅ, ํ์ค ์ ์ถ๋ ฅ |
8 | ์ ์ถ๋ ฅ ์ต์ ํ (๋ฒํผ, Direct Buffer) |
9 | ๋ณด์ (AES ์ํธํ) |
10 | ๋คํธ์ํฌ ์ ์ถ๋ ฅ (์์ผ) |
11 | ํ์ผ ์์คํ ์กฐ์ (NIO.2) |
12 | ์ค์ ํ๋ก์ ํธ ํ์ฉ (๋ก๊ทธ ์์คํ ) |
๐ 13๋จ๊ณ: ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Chunk I/O)
1. ๋์ฉ๋ ํ์ผ์ ํ ๋ฒ์ ์ฝ์ผ๋ฉด ๋ฌธ์ ๊ฐ ์๊น!
- 1GB ์ด์์ ํ์ผ์ ํ ๋ฒ์
read()
ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํด์. ๐ฑ - ํด๊ฒฐ ๋ฐฉ๋ฒ? ์์ ๋จ์(Chunk, ์กฐ๊ฐ)๋ก ๋๋ ์ ์ฝ๊ธฐ!
๐ ์์ : 1MB ๋จ์๋ก ํ์ผ ๋ณต์ฌํ๊ธฐ
import java.io.*;
public class LargeFileCopy {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("large_file.mp4");
FileOutputStream fos = new FileOutputStream("copy.mp4");
byte[] buffer = new byte[1024 * 1024]; // 1MB ๋ฒํผ
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fis.close();
fos.close();
System.out.println("ํ์ผ ๋ณต์ฌ ์๋ฃ!");
}
}
โ ํ์ผ์ ์กฐ๊ฐ(Chunk) ๋จ์๋ก ๋๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ์ข์์ ธ์!
๐ 14๋จ๊ณ: ๋ฉํฐ์ค๋ ๋ ์ ์ถ๋ ฅ (๋ณ๋ ฌ I/O)
๋์ฉ๋ ํ์ผ์ ์ฝ์ ๋ ๋ฉํฐ์ค๋ ๋๋ฅผ ํ์ฉํ๋ฉด ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ด์!
๐ ๋ฉํฐ์ค๋ ๋ I/O = CPU ์ฌ๋ฌ ๊ฐ ์ฌ์ฉ = ์๋ ํฅ์!
๐ ์์ : ๋ฉํฐ์ค๋ ๋๋ก ํ์ผ ๋ณต์ฌ
import java.io.*;
class FileCopyThread extends Thread {
private String source;
private String destination;
public FileCopyThread(String source, String destination) {
this.source = source;
this.destination = destination;
}
@Override
public void run() {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(destination)) {
byte[] buffer = new byte[1024 * 1024]; // 1MB ๋ฒํผ
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println(source + " -> " + destination + " ๋ณต์ฌ ์๋ฃ!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class MultiThreadFileCopy {
public static void main(String[] args) {
String[] files = {"file1.mp4", "file2.mp4", "file3.mp4"};
for (String file : files) {
new FileCopyThread(file, "copy_" + file).start();
}
}
}
โ ํ์ผ 3๊ฐ๋ฅผ ๋์์ ๋ณต์ฌ! (๋ฉํฐ์ค๋ ๋๋ก ์๋ UP! ๐)
๐ 15๋จ๊ณ: ํ์ผ ๊ฐ์ ์์คํ (WatchService)
1. ์ค์๊ฐ์ผ๋ก ํด๋ ๋ณํ๋ฅผ ๊ฐ์งํ๋ ๊ธฐ๋ฅ
- ์๋ก์ด ํ์ผ์ด ์ถ๊ฐ๋์๋์ง?
- ํ์ผ์ด ์ญ์ ๋์๋์ง?
- ํ์ผ์ด ์์ ๋์๋์ง?
๐ ์์ : ํน์ ํด๋๋ฅผ ๊ฐ์ํ๊ณ ๋ณํ ๊ฐ์ง
import java.nio.file.*;
public class DirectoryWatcher {
public static void main(String[] args) throws Exception {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get("C:/myfolder");
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
System.out.println("ํด๋ ๊ฐ์ ์์...");
while (true) {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println("์ด๋ฒคํธ ๋ฐ์: " + event.kind() + " -> " + event.context());
}
key.reset();
}
}
}
โ ํ์ผ์ด ์ถ๊ฐ/์ญ์ /์์ ๋ ๋ ์๋์ผ๋ก ๊ฐ์ง ๊ฐ๋ฅ!
๐ 16๋จ๊ณ: ๋ฉ๋ชจ๋ฆฌ ๋งคํ ํ์ผ (Memory Mapped File)
1. ์ด๊ณ ์ ํ์ผ ์ ์ถ๋ ฅ์ ์ํ๋ค๋ฉด?
- ๊ธฐ์กด
FileInputStream
๋ฐฉ์๋ณด๋ค ์ต๋ 10๋ฐฐ ๋น ๋ฅธ ์ ์ถ๋ ฅ ๊ฐ๋ฅ! ๐ MappedByteBuffer
๋ฅผ ์ฌ์ฉํด ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํํ๋ฉด ์๋๊ฐ ๋นจ๋ผ์ง.
๐ ์์ : ์ด๊ณ ์ ํ์ผ ์ฝ๊ธฐ
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MemoryMappedFileExample {
public static void main(String[] args) throws Exception {
RandomAccessFile file = new RandomAccessFile("bigfile.txt", "r");
FileChannel channel = file.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
for (int i = 0; i < buffer.limit(); i++) {
System.out.print((char) buffer.get()); // ํ์ผ ๋ด์ฉ ์ถ๋ ฅ
}
file.close();
}
}
โ ํ์ผ์ด ์ง์ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํ๋์ด ์๋๊ฐ ํจ์ฌ ๋นจ๋ผ์!
๐ 17๋จ๊ณ: ์์ถ & ํด์ (ZIP ํ์ผ)
1. ํ์ผ์ ์์ถํด์ ์ ์ฅ ๊ณต๊ฐ ์ ์ฝํ๊ธฐ
์๋ฐ์ java.util.zip
ํจํค์ง๋ฅผ ํ์ฉํ๋ฉด ZIP ํ์ผ์ ๋ง๋ค๊ณ ํด์ ํ ์ ์์ด์. ๐ฏ
๐ ์์ : ZIP ํ์ผ ๋ง๋ค๊ธฐ
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipExample {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("output.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
File fileToZip = new File("largefile.txt");
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
zipOut.write(buffer, 0, bytesRead);
}
fis.close();
zipOut.closeEntry();
zipOut.close();
System.out.println("ZIP ํ์ผ ์์ฑ ์๋ฃ!");
}
}
โ ๋์ฉ๋ ํ์ผ์ ZIP์ผ๋ก ์์ถํ๋ฉด ๊ณต๊ฐ์ ์ ์ฝํ ์ ์์ด์!
๐ ์ต์ข ์ ๋ฆฌ
๋จ๊ณ | ๋ด์ฉ |
---|---|
13 | ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Chunk I/O) |
14 | ๋ฉํฐ์ค๋ ๋ ์ ์ถ๋ ฅ (๋ณ๋ ฌ ์ฒ๋ฆฌ) |
15 | ํ์ผ ๊ฐ์ ์์คํ (WatchService) |
16 | ์ด๊ณ ์ ํ์ผ ์ ์ถ๋ ฅ (Memory Mapped File) |
17 | ํ์ผ ์์ถ & ํด์ (ZIP) |
๐ 18๋จ๊ณ: ๊ณ ๊ธ ํ์ผ ์ํธํ (AES-GCM)
1. ๋ณด์์ด ์ค์ํ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ ค๋ฉด?
- ๊ธฐ์กด AES ์ํธํ๋ณด๋ค ๋ ๊ฐ๋ ฅํ AES-GCM ๋ฐฉ์ ์ฌ์ฉ!
- ํด์ปค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณ์กฐํ๋ ๊ฑธ ๋ง์ ์ ์์.
๐ ์์ : AES-GCM์ ์ฌ์ฉํ ํ์ผ ์ํธํ
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.SecureRandom;
import java.util.Base64;
public class AESGCMFileEncryption {
public static void main(String[] args) throws Exception {
String key = "0123456789abcdef"; // 16๋ฐ์ดํธ ํค (128๋นํธ)
SecretKey secretKey = new SecretKeySpec(key.getBytes(), "AES");
// ์ํธํ
byte[] iv = new byte[12]; // 12๋ฐ์ดํธ IV (์ด๊ธฐ ๋ฒกํฐ)
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, iv));
byte[] plainText = "๋น๋ฐ ๋ฐ์ดํฐ".getBytes();
byte[] cipherText = cipher.doFinal(plainText);
// ํ์ผ์ ์ ์ฅ
try (FileOutputStream fos = new FileOutputStream("encrypted.dat")) {
fos.write(iv); // IV ์ ์ฅ
fos.write(cipherText);
}
System.out.println("ํ์ผ ์ํธํ ์๋ฃ!");
}
}
โ AES-GCM์ ํ์ฉํ๋ฉด ๋ ๊ฐ๋ ฅํ ๋ณด์์ด ๊ฐ๋ฅํด์!
๐ 19๋จ๊ณ: ๋ฐ์ดํฐ ์ง๋ ฌํ ์ต์ ํ (Externalizable)
1. ๊ธฐ๋ณธ ์ง๋ ฌํ๋ ์๋๊ฐ ๋๋ฆฌ๋ค?
- ๊ธฐ๋ณธ
Serializable
๋ฐฉ์์ ๋ชจ๋ ํ๋๋ฅผ ์๋ ์ ์ฅํด์ ๋นํจ์จ์ ์. Externalizable
์ ์ฌ์ฉํ๋ฉด ์ํ๋ ํ๋๋ง ์ ์ฅํ ์ ์์ด์ ๋ ๋น ๋ฆ!
๐ ์์ : Externalizable์ ์ฌ์ฉํ ์ง๋ ฌํ
import java.io.*;
class User implements Externalizable {
private String name;
private int age;
// ๊ธฐ๋ณธ ์์ฑ์ ํ์!
public User() {}
public User(String name, int age) {
this.name = name;
this.age = age;
}
// ์ง์ ์ง๋ ฌํํ ํ๋ ์ง์
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name); // ๋ฌธ์์ด๋ง ์ ์ฅ
}
// ์ง์ ์ญ์ง๋ ฌํํ ํ๋ ์ง์
@Override
public void readExternal(ObjectInput in) throws IOException {
name = in.readUTF();
}
@Override
public String toString() {
return "์ด๋ฆ: " + name + ", ๋์ด: (์ ์ฅ ์ ํจ)";
}
}
public class ExternalizableExample {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// ๊ฐ์ฒด ์ง๋ ฌํ
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(new User("ํ๊ธธ๋", 30));
oos.close();
// ๊ฐ์ฒด ์ญ์ง๋ ฌํ
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User user = (User) ois.readObject();
ois.close();
System.out.println("๋ณต์๋ ๊ฐ์ฒด: " + user);
}
}
โ ํ์ํ ๋ฐ์ดํฐ๋ง ์ง๋ ฌํํ๋ฉด ์๋๊ฐ ๋ ๋น ๋ฆ!
๐ 20๋จ๊ณ: ํ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ฒ๋ผ ์ฌ์ฉํ๊ธฐ (RandomAccessFile)
1. ํ์ผ์์ ํน์ ์์น์ ๋ฐ์ดํฐ๋ง ์์ ํ ์ ์์๊น?
- ๊ธฐ์กด
FileReader
,FileWriter
๋ ์ฒ์๋ถํฐ ๋๊น์ง ์ฝ์ด์ผ ํจ. RandomAccessFile
์ ์ฌ์ฉํ๋ฉด ์ํ๋ ์์น์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ์ ์์!
๐ ์์ : ํ์ผ ํน์ ์์น์ ๋ฐ์ดํฐ ์์
import java.io.RandomAccessFile;
public class RandomAccessFileExample {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("data.txt", "rw");
// ์ฒ์ 10๋ฐ์ดํธ ์ฝ๊ธฐ
byte[] buffer = new byte[10];
raf.read(buffer);
System.out.println("์ฒ์ 10๋ฐ์ดํธ: " + new String(buffer));
// ํ์ผ์ 5๋ฒ์งธ ์์น๋ถํฐ "HELLO" ์ฝ์
raf.seek(5);
raf.write("HELLO".getBytes());
raf.close();
System.out.println("ํ์ผ ์์ ์๋ฃ!");
}
}
โ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ฒ๋ผ ํ์ผ์ ๋น ๋ฅด๊ฒ ์์ ๊ฐ๋ฅ!
๐ 21๋จ๊ณ: ๋ก๊ทธ ์์คํ ์ต์ ํ (Rolling Logs)
1. ๋ก๊ทธ ํ์ผ์ด ๋๋ฌด ์ปค์ง๋ฉด ์๋์ผ๋ก ์ ๋ก๊ทธ ํ์ผ ๋ง๋ค๊ธฐ
- ๋ก๊ทธ ํ์ผ์ด 10MB๊ฐ ๋์ผ๋ฉด ์๋ก์ด ๋ก๊ทธ ํ์ผ์ ์์ฑ
- ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ค๋ ๋ณด๊ดํ๋ฉด์ ์ ์ฅ ๊ณต๊ฐ๋ ์ ์ฝ ๊ฐ๋ฅ!
๐ ์์ : ์๋ ๋ก๊ทธ ๋กค๋ง ์์คํ
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class RollingLog {
private static final long MAX_SIZE = 10 * 1024 * 1024; // 10MB
public static void log(String message) throws IOException {
File logFile = new File("log.txt");
// ํ์ผ ํฌ๊ธฐ ์ฒดํฌ
if (logFile.length() > MAX_SIZE) {
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
File newFile = new File("log_" + timestamp + ".txt");
logFile.renameTo(newFile);
}
// ๋ก๊ทธ ์ฐ๊ธฐ
try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true))) {
writer.write(LocalDateTime.now() + " - " + message);
writer.newLine();
}
}
public static void main(String[] args) throws IOException {
log("์๋ฒ ์์๋จ.");
log("์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํจ.");
}
}
โ ๋ก๊ทธ ํ์ผ์ด ์ปค์ง๋ฉด ์๋์ผ๋ก ์๋ก์ด ํ์ผ์ ์์ฑ!
๐ 22๋จ๊ณ: ์คํธ๋ฆผ์ ํ์ฉํ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Pipeline)
1. ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋จ๊ณ๋ก ๊ฐ๊ณตํ ์ ์์๊น?
- ํ์ผ โ ์์ถ โ ์ํธํ โ ๋คํธ์ํฌ ์ ์ก ๊ฐ์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ๊ฐ๋ฅ!
๐ ์์ : ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ , ์์ถํ๊ณ , ๋คํธ์ํฌ๋ก ์ ์กํ๋ ์คํธ๋ฆผ ์ฒด์ด๋
import java.io.*;
import java.net.Socket;
import java.util.zip.GZIPOutputStream;
public class StreamPipelineExample {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("data.txt");
GZIPOutputStream gzipOut = new GZIPOutputStream(new FileOutputStream("data.gz"));
BufferedOutputStream netOut = new BufferedOutputStream(new Socket("localhost", 5000).getOutputStream());
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
gzipOut.write(buffer, 0, bytesRead); // ์์ถ
netOut.write(buffer, 0, bytesRead); // ๋คํธ์ํฌ ์ ์ก
}
fis.close();
gzipOut.close();
netOut.close();
System.out.println("๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๋ฃ!");
}
}
โ ํ์ผ์ ์ฝ๊ณ , ์์ถํ๊ณ , ๋คํธ์ํฌ๋ก ๋ณด๋ด๋ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ๊ฐ๋ฅ!
๐ ์ต์ข ์ ๋ฆฌ: ์ ์ถ๋ ฅ ์คํธ๋ฆผ ๋ํ์
๋จ๊ณ | ๋ด์ฉ |
---|---|
18 | ๊ณ ๊ธ ํ์ผ ์ํธํ (AES-GCM) |
19 | ๋ฐ์ดํฐ ์ง๋ ฌํ ์ต์ ํ (Externalizable) |
20 | ํ์ผ์ DB์ฒ๋ผ ์ฌ์ฉ (RandomAccessFile) |
21 | ๋ก๊ทธ ์์คํ ์ต์ ํ (Rolling Logs) |
22 | ์คํธ๋ฆผ ํ์ฉ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Pipeline) |
๐ 23๋จ๊ณ: ์ค์๊ฐ ํ์ผ ์์คํ ๋ชจ๋ํฐ๋ง (WatchService ๊ณ ๊ธ ํ์ฉ)
1. ์ค์๊ฐ์ผ๋ก ํน์ ํด๋์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ๋ ๊ธฐ๋ฅ
- ํ์ผ์ด ์ถ๊ฐ/์ญ์ /์์ ๋๋์ง ์ค์๊ฐ์ผ๋ก ๊ฐ์ง
- ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ฒ๋ฆฌ๋ก CPU ์ฌ์ฉ๋์ ์ค์ด๊ณ ๋ฐ์ ์๋๋ฅผ ๋์ผ ์ ์์
๐ ์์ : ํน์ ํด๋๋ฅผ ๊ฐ์ํ๊ณ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ๋ ์ฝ๋
import java.nio.file.*;
public class AdvancedDirectoryWatcher {
public static void main(String[] args) throws Exception {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get("C:/myfolder");
path.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
System.out.println("ํ์ผ ๋ณ๊ฒฝ ๊ฐ์ง ์์...");
while (true) {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println("์ด๋ฒคํธ ๋ฐ์: " + event.kind() + " -> " + event.context());
}
key.reset();
}
}
}
โ ํ์ผ์ด ์์ฑ/์์ /์ญ์ ๋ ๋ ์๋์ผ๋ก ๊ฐ์งํ์ฌ ์ด๋ฒคํธ ๋ก๊ทธ ์ถ๋ ฅ!
๐ 24๋จ๊ณ: ํด๋ผ์ฐ๋ ํ์ผ ์ ์ถ๋ ฅ (AWS S3, Google Drive ์ฐ๋)
1. ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง์ ํ์ผ ์ ๋ก๋/๋ค์ด๋ก๋
- ๋ก์ปฌ ํ์ผ์ AWS S3, Google Drive ๋ฑ์ ์ ๋ก๋
- Apache Commons FileUpload ๋๋ AWS SDK๋ฅผ ํ์ฉ
๐ ์์ : AWS S3์ ํ์ผ ์ ๋ก๋ (Java AWS SDK ํ์ฉ)
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.regions.Region;
import java.nio.file.Paths;
public class S3FileUpload {
public static void main(String[] args) {
S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_2).build();
String bucketName = "my-bucket";
String fileName = "upload.txt";
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
s3.putObject(request, Paths.get(fileName));
System.out.println("ํ์ผ ์
๋ก๋ ์๋ฃ!");
}
}
โ ํด๋ผ์ฐ๋ ํ์ผ ์คํ ๋ฆฌ์ง์ ์๋์ผ๋ก ์ ๋ก๋ ๊ฐ๋ฅ!
๐ 25๋จ๊ณ: ๋น๋๊ธฐ ์ ์ถ๋ ฅ (Asynchronous I/O, AIO)
1. ๊ธฐ์กด I/O๋ ๋๋ฆฌ๋ค!
- ๊ธฐ์กด
InputStream
์ ์์ฐจ์ (Blocking)์ผ๋ก ์ฒ๋ฆฌ - *๋น๋๊ธฐ ์ ์ถ๋ ฅ(AIO)๋ฅผ ํ์ฉํ๋ฉด **CPU๊ฐ ๋์ง ์๊ณ ๋ค๋ฅธ ์์ ์ ํ ์ ์์!
๐ ์์ : ๋น๋๊ธฐ ํ์ผ ์ฝ๊ธฐ (NIO.2 ํ์ฉ)
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;
public class AsyncFileRead {
public static void main(String[] args) throws Exception {
Path path = Path.of("largefile.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
Future<Integer> result = channel.read(buffer, 0);
while (!result.isDone()) {
System.out.println("๋ค๋ฅธ ์์
์ํ ์ค...");
Thread.sleep(500); // CPU๋ฅผ ๋๋ฆฌ์ง ์๋๋ก ๋ค๋ฅธ ์์
์ํ
}
buffer.flip();
System.out.println("ํ์ผ ์ฝ๊ธฐ ์๋ฃ: " + new String(buffer.array()).trim());
channel.close();
}
}
โ ๋น๋๊ธฐ ์ ์ถ๋ ฅ์ ์ฌ์ฉํ๋ฉด CPU๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ฉ ๊ฐ๋ฅ!
๐ 26๋จ๊ณ: ๋คํธ์ํฌ ์คํธ๋ฆผ ์ต์ ํ (Socket + Buffer)
1. ๋คํธ์ํฌ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฑ๋ฅ ์ต์ ํ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ
Socket
์คํธ๋ฆผ์ ์๋๊ฐ ๋๋ฆด ์ ์์ - Buffered Streams + NIO ์ฑ๋์ ์ฌ์ฉํ๋ฉด ์๋ UP! ๐
๐ ์์ : ๋คํธ์ํฌ์์ ๋ฒํผ๋ฅผ ํ์ฉํ ํ์ผ ์ ์ก
import java.io.*;
import java.net.*;
public class BufferedSocketServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(5000);
System.out.println("์๋ฒ ๋๊ธฐ ์ค...");
Socket socket = serverSocket.accept();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("received.txt"));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bis.close();
bos.close();
socket.close();
serverSocket.close();
System.out.println("ํ์ผ ์ ์ก ์๋ฃ!");
}
}
โ ๋ฒํผ๋ฅผ ํ์ฉํ๋ฉด ๋คํธ์ํฌ ์ ์ก ์๋๊ฐ ํจ์ฌ ๋นจ๋ผ์ ธ์!
๐ 27๋จ๊ณ: ๋ฐ์ดํฐ ์์ถ & ํด์ ์ต์ ํ (GZIP, BZIP2)
1. ๋คํธ์ํฌ ํธ๋ํฝ์ ์ค์ด๋ ค๋ฉด?
- ๋ฐ์ดํฐ๋ฅผ ์์ถํด์ ์ ์กํ๋ฉด ํธ๋ํฝ ๋น์ฉ ์ ๊ฐ
- GZIP & BZIP2 ๊ฐ์ ๊ณ ์ฑ๋ฅ ์์ถ ์๊ณ ๋ฆฌ์ฆ ํ์ฉ
๐ ์์ : GZIP์ ์ฌ์ฉํ ํ์ผ ์์ถ
import java.io.*;
import java.util.zip.GZIPOutputStream;
public class GzipCompression {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("largefile.txt");
GZIPOutputStream gzipOut = new GZIPOutputStream(new FileOutputStream("compressed.gz"));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
gzipOut.write(buffer, 0, bytesRead);
}
fis.close();
gzipOut.close();
System.out.println("ํ์ผ ์์ถ ์๋ฃ!");
}
}
โ GZIP์ ํ์ฉํ๋ฉด ๋คํธ์ํฌ ์ ์ก ์๋๊ฐ ์ต๋ 50% ๋นจ๋ผ์ง!
๐ ์ต์ข ์ ๋ฆฌ: ์๋ฐ ์ ์ถ๋ ฅ ์คํธ๋ฆผ ์์ ๋ง์คํฐ
๋จ๊ณ | ๋ด์ฉ |
---|---|
23 | ์ค์๊ฐ ํ์ผ ์์คํ ๋ชจ๋ํฐ๋ง (WatchService) |
24 | ํด๋ผ์ฐ๋ ํ์ผ ์ ์ถ๋ ฅ (AWS S3, Google Drive) |
25 | ๋น๋๊ธฐ ์ ์ถ๋ ฅ (AIO) |
26 | ๋คํธ์ํฌ ์คํธ๋ฆผ ์ต์ ํ (Socket + Buffer) |
27 | ๋ฐ์ดํฐ ์์ถ & ํด์ ์ต์ ํ (GZIP, BZIP2) |
๐ 28๋จ๊ณ: ์ด๊ณ ์ ์ ์ถ๋ ฅ ๊ธฐ์ (Zero-Copy, Direct I/O)
1. ๊ธฐ์กด I/O๋ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๊ฐ ๋ง์ ์๋๊ฐ ๋๋ฆผ
- ๊ธฐ์กด ๋ฐฉ์: ํ์ผ โ ์ปค๋ ๋ฒํผ โ ์ฌ์ฉ์ ๋ฒํผ โ ๋คํธ์ํฌ
- Zero-Copy ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด โ ํ์ผ โ ๋คํธ์ํฌ ๋ฐ๋ก ์ ์ก ๊ฐ๋ฅ! ๐
๐ ์์ : Zero-Copy๋ฅผ ์ฌ์ฉํ ์ด๊ณ ์ ํ์ผ ์ ์ก (sendfile)
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.net.InetSocketAddress;
public class ZeroCopyFileTransfer {
public static void main(String[] args) throws IOException {
File file = new File("largefile.mp4");
FileChannel fileChannel = new FileInputStream(file).getChannel();
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 5000));
fileChannel.transferTo(0, fileChannel.size(), socketChannel);
fileChannel.close();
socketChannel.close();
System.out.println("ํ์ผ ์ ์ก ์๋ฃ! (Zero-Copy)");
}
}
โ CPU ์ฌ์ฉ๋์ ์ค์ด๊ณ ์ด๊ณ ์์ผ๋ก ํ์ผ์ ์ ์กํ ์ ์์ด์!
๐ 29๋จ๊ณ: AI ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (๋จธ์ ๋ฌ๋๊ณผ ์๋ฐ I/O)
1. ๋์ฉ๋ ๋ฐ์ดํฐ์์ ์ธ๊ณต์ง๋ฅ(AI) ๋ชจ๋ธ์ด ํ์ตํ๋ ๋ฐฉ๋ฒ?
- ๋๋์ ๋ก๊ทธ, ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ๋ถ์ํด์ผ ํจ
- ์๋ฐ ์คํธ๋ฆผ(Stream API) + Apache Spark๋ก AI ๋ชจ๋ธ ํ์ต ๊ฐ๋ฅ
๐ ์์ : AI ํ์ต์ ์ํ ๋ก๊ทธ ๋ฐ์ดํฐ ์คํธ๋ฆฌ๋ฐ (Apache Spark ํ์ฉ)
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.SparkConf;
public class LogProcessingWithAI {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("LogProcessing").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> logs = sc.textFile("server_logs.txt");
long errorCount = logs.filter(line -> line.contains("ERROR")).count();
System.out.println("์ด ์๋ฌ ๋ฐ์ ํ์: " + errorCount);
sc.close();
}
}
โ ์ค์๊ฐ์ผ๋ก ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ AI ํ์ต ๋ชจ๋ธ์ ํ์ฉ ๊ฐ๋ฅ!
๐ 30๋จ๊ณ: ๋ธ๋ก์ฒด์ธ ๊ธฐ๋ฐ ํ์ผ ์ ์ฅ (IPFS + ์๋ฐ)
1. ๊ธฐ์กด ํ์ผ ์ ์ฅ ๋ฐฉ์์ ํดํน์ ์ทจ์ฝํ๋ค!
- ํ์ผ์ ์ค์ ์๋ฒ๊ฐ ๊ด๋ฆฌํ๋ฉด ๋ณด์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
- IPFS(InterPlanetary File System) + Java๋ฅผ ํ์ฉํ๋ฉด ํ์ค์ ํ์ผ ์ ์ฅ ๊ฐ๋ฅ!
๐ ์์ : IPFS์ ํ์ผ ์ ๋ก๋ํ๊ธฐ
import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
public class IPFSFileUpload {
public static void main(String[] args) throws Exception {
IPFS ipfs = new IPFS("/ip4/127.0.0.1/tcp/5001");
NamedStreamable.FileWrapper file = new NamedStreamable.FileWrapper(new File("data.txt"));
MerkleNode addResult = ipfs.add(file).get(0);
System.out.println("IPFS ํด์: " + addResult.hash.toBase58());
}
}
โ IPFS๋ฅผ ์ฌ์ฉํ๋ฉด ํดํน์ด ๋ถ๊ฐ๋ฅํ ํ์ผ ์ ์ฅ ์์คํ ๊ตฌ์ถ ๊ฐ๋ฅ!
๐ 31๋จ๊ณ: ๋ฏธ๋์ ์๋ฐ I/O (Project Loom & Virtual Threads)
1. ๊ธฐ์กด ์ค๋ ๋๋ ๋๋ฌด ๋ฌด๊ฒ๋ค!
- ๊ธฐ์กด
Thread
๋ ์ด์์ฒด์ (OS)์์ ๊ด๋ฆฌํ๋ฏ๋ก ์์ฑ ๋น์ฉ์ด ํผ - ์๋ฐ 21๋ถํฐ ๋ฑ์ฅํ โVirtual Threadsโ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฒผ์ด ์ค๋ ๋ ์์ฑ ๊ฐ๋ฅ!
๐ ์์ : Virtual Threads๋ก 100๋ง ๊ฐ์ ํ์ผ์ ๋์์ ์ฝ๊ธฐ
import java.nio.file.*;
import java.util.concurrent.*;
public class VirtualThreadExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 1_000_000; i++) {
int fileNumber = i;
executor.submit(() -> {
try {
String content = Files.readString(Path.of("file" + fileNumber + ".txt"));
System.out.println("ํ์ผ ์ฝ์: " + fileNumber);
} catch (Exception e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
โ ๊ฐ๋ฒผ์ด Virtual Thread ๋๋ถ์ 100๋ง ๊ฐ ํ์ผ์ ๋์์ ์ฝ์ ์ ์์!
๐ ์ต์ข ์ ๋ฆฌ: ์๋ฐ ์ ์ถ๋ ฅ์ ํ์ฌ์ ๋ฏธ๋
๋จ๊ณ | ๋ด์ฉ |
---|---|
28 | ์ด๊ณ ์ I/O (Zero-Copy, Direct I/O) |
29 | AI ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (๋จธ์ ๋ฌ๋ + Java I/O) |
30 | ๋ธ๋ก์ฒด์ธ ํ์ผ ์ ์ฅ (IPFS) |
31 | ๋ฏธ๋์ ์๋ฐ I/O (Project Loom & Virtual Threads) |
๐ 32๋จ๊ณ: ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ I/O (Kubernetes + Java)
1. ๋ฏธ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํด๋ผ์ฐ๋์์ ์คํ๋จ
- AWS, GCP, Azure์ ๊ฐ์ ํด๋ผ์ฐ๋ ํ๊ฒฝ์์ ์๋ฐ I/O๋ฅผ ์ต์ ํํด์ผ ํจ
- *์ฟ ๋ฒ๋คํฐ์ค(Kubernetes)**์์ ํ์ผ I/O์ ๋คํธ์ํฌ I/O๋ฅผ ์ด๋ป๊ฒ ํ์ฉํ ๊น?
๐ ์์ : ์ฟ ๋ฒ๋คํฐ์ค ๊ธฐ๋ฐ ๋ก๊ทธ ์ ์ฅ ์์คํ
apiVersion: v1
kind: Pod
metadata:
name: java-log-pod
spec:
containers:
- name: java-log-container
image: openjdk:latest
volumeMounts:
- mountPath: "/var/logs"
name: log-volume
volumes:
- name: log-volume
emptyDir: {}
โ ์ปจํ ์ด๋์์ ์คํ๋๋ ์๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ก๊ทธ ํ์ผ์ ํด๋ผ์ฐ๋์์ ์ ์ฅ!
๐ 33๋จ๊ณ: ์์ ์ปดํจํ ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ ์ก (Quantum I/O)
1. ๊ธฐ์กด์ ๋คํธ์ํฌ๋ ๋ณด์์ด ์ทจ์ฝํ๋ค!
- ์์ ์ปดํจํ ์ด ๋ฐ์ ํ๋ฉด์ ์์ ํค ๋ถ๋ฐฐ(QKD)๋ฅผ ํตํ ์ด๋ณด์ ๋ฐ์ดํฐ ์ ์ก์ด ๊ฐ๋ฅํด์ง!
- ์๋ฐ์์ ์์ ๊ธฐ๋ฐ ํต์ ์ ์ด๋ป๊ฒ ํ์ฉํ ๊น?
๐ ์์ : IBM Qiskit์ ํ์ฉํ ์์ ๋ฐ์ดํฐ ์ ์ก
from qiskit import QuantumCircuit, execute, Aer
qc = QuantumCircuit(1, 1)
qc.h(0)
qc.measure(0, 0)
simulator = Aer.get_backend('qasm_simulator')
result = execute(qc, simulator, shots=1).result()
print(result.get_counts())
โ ์์ ์ปดํจํฐ๋ฅผ ํ์ฉํด ํดํน์ด ๋ถ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์ ์ก ๊ฐ๋ฅ!
๐ 34๋จ๊ณ: ์ธ๊ฐ-์ปดํจํฐ ์ธํฐํ์ด์ค(HCI)์ I/O ๊ฒฐํฉ
1. ์ธ๊ฐ๊ณผ ์ปดํจํฐ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉ์์ด ์งํํ๊ณ ์์
- ๊ธฐ์กด I/O: ํค๋ณด๋, ๋ง์ฐ์ค, ํฐ์น์คํฌ๋ฆฐ
- ๋ฏธ๋ I/O: ๋-์ปดํจํฐ ์ธํฐํ์ด์ค(BCI), ์ฆ๊ฐํ์ค(AR), ํ๋ก๊ทธ๋จ ์ธํฐํ์ด์ค
๐ ์์ : ๋ํ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์๋ฐ I/O ์์คํ
import com.neurosky.thinkgear.*;
public class BrainComputerInterface {
public static void main(String[] args) {
TGDevice device = new TGDevice(new TGStreamReader());
device.connect();
device.addListener(new TGDeviceListener() {
@Override
public void onMeditationLevel(int level) {
System.out.println("์ง์ค๋: " + level);
}
});
}
}
โ ์ธ๊ฐ์ ๋ํ๋ฅผ ๋ถ์ํด ์๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ์ฐ๊ฒฐ ๊ฐ๋ฅ!
๐ 35๋จ๊ณ: ์๋ฐ I/O์ ๊ถ๊ทน์ ์ธ ๋ฏธ๋ โ ์ธ๊ฐ๊ณผ AI์ ๊ฒฐํฉ
1. ๋ฏธ๋์๋ ์ธ๊ฐ๊ณผ AI๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฃผ๊ณ ๋ฐ๋ ํ๊ฒฝ์ด ๋ง๋ค์ด์ง ๊ฒ!
- AI๊ฐ ์ค์๊ฐ์ผ๋ก ์ธ๊ฐ์ ๊ฐ์ ์ ๋ถ์ํ์ฌ ๋ฐ์ดํฐ ์ ์ก
- ํด๋ผ์ฐ๋, ์์ ๋คํธ์ํฌ, ์ฆ๊ฐ ํ์ค, ์์ฒด ์ธ์๊ณผ ๊ฒฐํฉ๋ ์๋ฐ I/O
๐ ์์ : ๊ฐ์ ์ ๋ถ์ํด ํ์ผ ์ ์ถ๋ ฅ ๊ฒฐ์ ํ๊ธฐ
import org.tensorflow.*;
public class EmotionBasedIO {
public static void main(String[] args) {
try (SavedModelBundle model = SavedModelBundle.load("emotion_model", "serve")) {
Tensor input = Tensor.create(new float[][] );
Tensor output = model.session().runner().feed("input", input).fetch("output").run().get(0);
float[] predictions = output.copyTo(new float[1])[0];
if (predictions[0] > 0.7) {
System.out.println("๊ธ์ ์ ์ธ ๊ฐ์ ๊ฐ์ง! ํ์ผ ์ ์ฅ ์์...");
// ํ์ผ ์ ์ฅ ๋ก์ง ์คํ
}
}
}
}
โ ์ธ๊ณต์ง๋ฅ์ด ์ธ๊ฐ์ ๊ฐ์ ์ ๋ถ์ํ์ฌ ์ ์ถ๋ ฅ์ ์๋์ผ๋ก ์กฐ์ ํ ์ ์์!
๐ ์ต์ข ์ ๋ฆฌ: ์๋ฐ ์ ์ถ๋ ฅ์ ๋ง์ง๋ง ์งํ
๋จ๊ณ | ๋ด์ฉ |
---|---|
32 | ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ I/O (Kubernetes + Java) |
33 | ์์ ์ปดํจํ ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ ์ก (Quantum I/O) |
34 | ์ธ๊ฐ-์ปดํจํฐ ์ธํฐํ์ด์ค(HCI)์ I/O ๊ฒฐํฉ |
35 | AI์ ์ธ๊ฐ ๊ฐ์ ๊ธฐ๋ฐ I/O |
๐ฅ ์ด์ ์ง์ง โ์๋ฐ I/O์ ๋ฏธ๋ ์ ๋ฌธ๊ฐโ๊ฐ ๋์์ต๋๋ค!
์ด์ ์ฌ๋ฌ๋ถ์ ํ์ผ ์์คํ , ๋คํธ์ํฌ, ๋ณด์, ํด๋ผ์ฐ๋, AI, ์์ ์ปดํจํ ๊น์ง ๋ชจ๋ ๋ค๋ฃฐ ์ ์๋ I/O ๋ง์คํฐ์ ๋๋ค. ๐
๐ก ๋ค์ ๋จ๊ณ๋? โ ์ค์ ๊ธฐ์ ํ๋ก์ ํธ์์ ์๋ฐ I/O๋ฅผ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์ฐ๊ตฌ
โ AI + I/O + ํด๋ผ์ฐ๋๋ฅผ ๊ฒฐํฉํ์ฌ ์ฐจ์ธ๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ
โ ์์ ์ปดํจํ ๊ธฐ๋ฐ์ ์๋ก์ด ๋ณด์ ์์คํ ์ค๊ณ
###
๐ 36๋จ๊ณ ์ฌ๊ธฐ๋ถํฐ ๋ก: ์ฐ์ฃผ ๋ฐ์ดํฐ ์ ์ก (Deep Space Communication)
1. ์ง๊ตฌ์ ํ์ฑ ๊ฐ ๋ฐ์ดํฐ ์ ์ก์ ์ด๋ป๊ฒ ํ ๊น?
- ๊ธฐ์กด I/O: ๋น์ ์๋๋ก๋ 20๋ถ ์ด์ ๊ฑธ๋ฆฌ๋ ๊ฑฐ๋ฆฌ
- NASA๋ ๋ ์ด์ ๊ธฐ๋ฐ ํต์ ์ ์ฐ๊ตฌ ์ค!
- ์๋ฐ๋ก ์ฐ์ฃผ ๋ฐ์ดํฐ ์ ์ก์ ์๋ฎฌ๋ ์ด์ ํ ์ ์์๊น?
๐ ์์ : ๋ ์ด์ ๊ธฐ๋ฐ ์ฐ์ฃผ ๋ฐ์ดํฐ ์ ์ก ์๋ฎฌ๋ ์ด์
public class DeepSpaceTransmission {
public static void main(String[] args) {
double distanceToMars = 225_000_000; // km
double speedOfLight = 299_792; // km/s
double delay = distanceToMars / speedOfLight;
System.out.println("์ง๊ตฌ โ ํ์ฑ ๋ฐ์ดํฐ ์ ์ก ์๊ฐ: " + delay + "์ด");
if (delay > 20) {
System.out.println("AI ์์ธก ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ๋ฏธ๋ฆฌ ์ ์ก...");
}
}
}
โ ๋ฏธ๋์ ์ฐ์ฃผ ๋ฐ์ดํฐ ์ ์ก์ ์ํ ์๋ฐ ๊ธฐ๋ฐ I/O ์๋ฎฌ๋ ์ด์ ๊ฐ๋ฅ! ๐
๐ 37๋จ๊ณ: ๋-์ปดํจํฐ ์ธํฐํ์ด์ค(BCI)์ I/O ์ตํฉ
1. ์ธ๊ฐ์ ๋ํ๋ฅผ ์ง์ ๋ฐ์ดํฐ๋ก ๋ณํํ ์ ์์๊น?
- ๊ธฐ์กด I/O: ํค๋ณด๋, ๋ง์ฐ์ค, ํฐ์น์คํฌ๋ฆฐ
- ๋ฏธ๋ I/O: ๋์์ ์ง์ ๋ฐ์ดํฐ๋ฅผ ์ ์ก! ๐ง
๐ ์์ : ๋ํ(EEG) ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์๋ฐ I/O
java
๋ณต์ฌํธ์ง
import com.neurosky.thinkgear.*;
public class BrainControlledIO {
public static void main(String[] args) {
TGDevice device = new TGDevice(new TGStreamReader());
device.connect();
device.addListener(new TGDeviceListener() {
@Override
public void onMeditationLevel(int level) {
if (level > 80) {
System.out.println("์ง์ค๋๊ฐ ๋์ โ ํ์ผ ์ ์ฅ ์คํ!");
saveFile();
}
}
});
}
public static void saveFile() {
System.out.println("ํ์ผ์ด ์ ์ฅ๋์์ต๋๋ค!");
}
}
โ ๋ํ ์ ํธ๋ฅผ ๋ถ์ํ์ฌ ์๋ฐ I/O๋ฅผ ์ง์ ์กฐ์ ๊ฐ๋ฅ!
๐ 38๋จ๊ณ: ์๋ฐ I/O์ ์ฒ ํ์ ์๋ฏธ โ ์ ๋ณด ํ๋ฆ๊ณผ ์ธ๊ฐ์ ์ญํ
1. ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃฌ ์ ์ถ๋ ฅ์ ๊ฒฐ๊ตญ โ์ ๋ณด์ ํ๋ฆโ
- ์ธ๊ฐ๋ ์ ์ถ๋ ฅ(I/O) ์์คํ ์ด๋ค!
- ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ๋ฐ๊ณ (ํ์ต), ์ถ๋ ฅํ๋ค(ํํ).
- ๊ถ๊ทน์ ์ผ๋ก ์ ๋ณด๋ ๋ฌด์์ธ๊ฐ?
๐ ์ฒ ํ์ ์ง๋ฌธ
- โ์๋ฐ I/O์ ์ธ๊ฐ์ ์ฌ๊ณ ๋ฐฉ์์ ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋ ๊น?โ
- โ๋ฏธ๋์๋ ์ธ๊ฐ์ด ์ง์ I/O๊ฐ ๋ ์ ์์๊น?โ
- โ๊ธฐ์ต๊ณผ ์ ๋ณด, ๊ทธ๋ฆฌ๊ณ AI๋ ์ด๋ค ๊ด๊ณ์ผ๊น?โ
โ ์ ๋ณด์ ํ๋ฆ์ ์ดํดํ๋ฉด, ๊ฒฐ๊ตญ ๋ชจ๋ ๊ฒ์ I/O๊ฐ ๋๋ค!
๐ ์ต์ข ๋จ๊ณ: I/O์ ๋์ ๋์ด, ์ฐฝ์กฐ์ ์์ญ์ผ๋ก!
๋จ๊ณ | ๋ด์ฉ |
---|---|
36 | ์ฐ์ฃผ ๋ฐ์ดํฐ ์ ์ก (Deep Space I/O) |
37 | ๋-์ปดํจํฐ ์ธํฐํ์ด์ค(BCI)์ I/O ์ตํฉ |
38 | ์๋ฐ I/O์ ์ฒ ํ์ ์๋ฏธ โ ์ ๋ณด ํ๋ฆ๊ณผ ์ธ๊ฐ |
๐ฅ ์ด์ ๋น์ ์ ๋จ์ํ ๊ฐ๋ฐ์๋ฅผ ๋์ด, ๊ธฐ์ ์ฒ ํ์์ด์ ์ฐฝ์กฐ์๊ฐ ๋์์ต๋๋ค! ๐
๐ก ์ด์ ๋ค์ ๋ชฉํ๋? โ I/O๋ฅผ ํ์ฉํ ํ์ ์ ์ธ ๊ธฐ์ ๊ฐ๋ฐ
โ ๋ฏธ๋์ ์ ๋ณด ํ๋ฆ์ ์์ธกํ๊ณ ์ค๊ณํ๋ ์ญํ
โ ๊ธฐ์ ๊ณผ ์ธ๊ฐ, ๊ทธ๋ฆฌ๊ณ ์ฐ์ฃผ์ ์ฐ๊ฒฐ์ ์ฐ๊ตฌ
๐ 39๋จ๊ณ: ๋ฉํฐ์ค๋ ๋ ์ ์ถ๋ ฅ (๋ณ๋ ฌ I/O)
๋์ฉ๋ ํ์ผ์ ์ฝ์ ๋ ๋ฉํฐ์ค๋ ๋๋ฅผ ํ์ฉํ๋ฉด ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ด์!
๐ ๋ฉํฐ์ค๋ ๋ I/O = CPU ์ฌ๋ฌ ๊ฐ ์ฌ์ฉ = ์๋ ํฅ์!
๐ ์์ : ๋ฉํฐ์ค๋ ๋๋ก ํ์ผ ๋ณต์ฌ
import java.io.*;
class FileCopyThread extends Thread {
private String source;
private String destination;
public FileCopyThread(String source, String destination) {
this.source = source;
this.destination = destination;
}
@Override
public void run() {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(destination)) {
byte[] buffer = new byte[1024 * 1024]; // 1MB ๋ฒํผ
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println(source + " -> " + destination + " ๋ณต์ฌ ์๋ฃ!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class MultiThreadFileCopy {
public static void main(String[] args) {
String[] files = {"file1.mp4", "file2.mp4", "file3.mp4"};
for (String file : files) {
new FileCopyThread(file, "copy_" + file).start();
}
}
}
โ ํ์ผ 3๊ฐ๋ฅผ ๋์์ ๋ณต์ฌ! (๋ฉํฐ์ค๋ ๋๋ก ์๋ UP! ๐)
๐ 40๋จ๊ณ: ํ์ผ ๊ฐ์ ์์คํ (WatchService)
1. ์ค์๊ฐ์ผ๋ก ํด๋ ๋ณํ๋ฅผ ๊ฐ์งํ๋ ๊ธฐ๋ฅ
- ์๋ก์ด ํ์ผ์ด ์ถ๊ฐ๋์๋์ง?
- ํ์ผ์ด ์ญ์ ๋์๋์ง?
- ํ์ผ์ด ์์ ๋์๋์ง?
๐ ์์ : ํน์ ํด๋๋ฅผ ๊ฐ์ํ๊ณ ๋ณํ ๊ฐ์ง
import java.nio.file.*;
public class DirectoryWatcher {
public static void main(String[] args) throws Exception {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get("C:/myfolder");
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
System.out.println("ํด๋ ๊ฐ์ ์์...");
while (true) {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println("์ด๋ฒคํธ ๋ฐ์: " + event.kind() + " -> " + event.context());
}
key.reset();
}
}
}
โ ํ์ผ์ด ์ถ๊ฐ/์ญ์ /์์ ๋ ๋ ์๋์ผ๋ก ๊ฐ์ง ๊ฐ๋ฅ!
๐ 41๋จ๊ณ: ๋ฉ๋ชจ๋ฆฌ ๋งคํ ํ์ผ (Memory Mapped File)
1. ์ด๊ณ ์ ํ์ผ ์ ์ถ๋ ฅ์ ์ํ๋ค๋ฉด?
- ๊ธฐ์กด
FileInputStream
๋ฐฉ์๋ณด๋ค ์ต๋ 10๋ฐฐ ๋น ๋ฅธ ์ ์ถ๋ ฅ ๊ฐ๋ฅ! ๐ MappedByteBuffer
๋ฅผ ์ฌ์ฉํด ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํํ๋ฉด ์๋๊ฐ ๋นจ๋ผ์ง.
๐ ์์ : ์ด๊ณ ์ ํ์ผ ์ฝ๊ธฐ
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MemoryMappedFileExample {
public static void main(String[] args) throws Exception {
RandomAccessFile file = new RandomAccessFile("bigfile.txt", "r");
FileChannel channel = file.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
for (int i = 0; i < buffer.limit(); i++) {
System.out.print((char) buffer.get()); // ํ์ผ ๋ด์ฉ ์ถ๋ ฅ
}
file.close();
}
}
โ ํ์ผ์ด ์ง์ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํ๋์ด ์๋๊ฐ ํจ์ฌ ๋นจ๋ผ์!
๐ 42๋จ๊ณ: ์์ถ & ํด์ (ZIP ํ์ผ)
1. ํ์ผ์ ์์ถํด์ ์ ์ฅ ๊ณต๊ฐ ์ ์ฝํ๊ธฐ
์๋ฐ์ java.util.zip
ํจํค์ง๋ฅผ ํ์ฉํ๋ฉด ZIP ํ์ผ์ ๋ง๋ค๊ณ ํด์ ํ ์ ์์ด์. ๐ฏ
๐ ์์ : ZIP ํ์ผ ๋ง๋ค๊ธฐ
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipExample {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("output.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
File fileToZip = new File("largefile.txt");
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
zipOut.write(buffer, 0, bytesRead);
}
fis.close();
zipOut.closeEntry();
zipOut.close();
System.out.println("ZIP ํ์ผ ์์ฑ ์๋ฃ!");
}
โ ๋์ฉ๋ ํ์ผ์ ZIP์ผ๋ก ์์ถํ๋ฉด ๊ณต๊ฐ์ ์ ์ฝํ ์ ์์ด์!
๐ ์ต์ข ์ ๋ฆฌ
๋จ๊ณ | ๋ด์ฉ |
---|---|
39 | ๋ฉํฐ์ค๋ ๋ ์ ์ถ๋ ฅ (๋ณ๋ ฌ ์ฒ๋ฆฌ) |
40 | ํ์ผ ๊ฐ์ ์์คํ (WatchService) |
41 | ์ด๊ณ ์ ํ์ผ ์ ์ถ๋ ฅ (Memory Mapped File) |
42 | ํ์ผ ์์ถ & ํด์ (ZIP) |
๐ 43๋จ๊ณ: ๊ณ ๊ธ ํ์ผ ์ํธํ (AES-GCM)
1. ๋ณด์์ด ์ค์ํ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ ค๋ฉด?
- ๊ธฐ์กด AES ์ํธํ๋ณด๋ค ๋ ๊ฐ๋ ฅํ AES-GCM ๋ฐฉ์ ์ฌ์ฉ!
- ํด์ปค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณ์กฐํ๋ ๊ฑธ ๋ง์ ์ ์์.
๐ ์์ : AES-GCM์ ์ฌ์ฉํ ํ์ผ ์ํธํ
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.SecureRandom;
import java.util.Base64;
public class AESGCMFileEncryption {
public static void main(String[] args) throws Exception {
String key = "0123456789abcdef"; // 16๋ฐ์ดํธ ํค (128๋นํธ)
SecretKey secretKey = new SecretKeySpec(key.getBytes(), "AES");
// ์ํธํ
byte[] iv = new byte[12]; // 12๋ฐ์ดํธ IV (์ด๊ธฐ ๋ฒกํฐ)
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, iv));
byte[] plainText = "๋น๋ฐ ๋ฐ์ดํฐ".getBytes();
byte[] cipherText = cipher.doFinal(plainText);
// ํ์ผ์ ์ ์ฅ
try (FileOutputStream fos = new FileOutputStream("encrypted.dat")) {
fos.write(iv); // IV ์ ์ฅ
fos.write(cipherText);
}
System.out.println("ํ์ผ ์ํธํ ์๋ฃ!");
}
}
โ AES-GCM์ ํ์ฉํ๋ฉด ๋ ๊ฐ๋ ฅํ ๋ณด์์ด ๊ฐ๋ฅํด์!
๐ 44๋จ๊ณ: ๋ฐ์ดํฐ ์ง๋ ฌํ ์ต์ ํ (Externalizable)
1. ๊ธฐ๋ณธ ์ง๋ ฌํ๋ ์๋๊ฐ ๋๋ฆฌ๋ค?
- ๊ธฐ๋ณธ
Serializable
๋ฐฉ์์ ๋ชจ๋ ํ๋๋ฅผ ์๋ ์ ์ฅํด์ ๋นํจ์จ์ ์. Externalizable
์ ์ฌ์ฉํ๋ฉด ์ํ๋ ํ๋๋ง ์ ์ฅํ ์ ์์ด์ ๋ ๋น ๋ฆ!
๐ ์์ : Externalizable์ ์ฌ์ฉํ ์ง๋ ฌํ
import java.io.*;
class User implements Externalizable {
private String name;
private int age;
// ๊ธฐ๋ณธ ์์ฑ์ ํ์!
public User() {}
public User(String name, int age) {
this.name = name;
this.age = age;
}
// ์ง์ ์ง๋ ฌํํ ํ๋ ์ง์
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name); // ๋ฌธ์์ด๋ง ์ ์ฅ
}
// ์ง์ ์ญ์ง๋ ฌํํ ํ๋ ์ง์
@Override
public void readExternal(ObjectInput in) throws IOException {
name = in.readUTF();
}
@Override
public String toString() {
return "์ด๋ฆ: " + name + ", ๋์ด: (์ ์ฅ ์ ํจ)";
}
}
public class ExternalizableExample {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// ๊ฐ์ฒด ์ง๋ ฌํ
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(new User("ํ๊ธธ๋", 30));
oos.close();
// ๊ฐ์ฒด ์ญ์ง๋ ฌํ
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User user = (User) ois.readObject();
ois.close();
System.out.println("๋ณต์๋ ๊ฐ์ฒด: " + user);
}
}
โ ํ์ํ ๋ฐ์ดํฐ๋ง ์ง๋ ฌํํ๋ฉด ์๋๊ฐ ๋ ๋น ๋ฆ!
๐ 45๋จ๊ณ: ํ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ฒ๋ผ ์ฌ์ฉํ๊ธฐ (RandomAccessFile)
1. ํ์ผ์์ ํน์ ์์น์ ๋ฐ์ดํฐ๋ง ์์ ํ ์ ์์๊น?
- ๊ธฐ์กด
FileReader
,FileWriter
๋ ์ฒ์๋ถํฐ ๋๊น์ง ์ฝ์ด์ผ ํจ. RandomAccessFile
์ ์ฌ์ฉํ๋ฉด ์ํ๋ ์์น์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ์ ์์!
๐ ์์ : ํ์ผ ํน์ ์์น์ ๋ฐ์ดํฐ ์์
import java.io.RandomAccessFile;
public class RandomAccessFileExample {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("data.txt", "rw");
// ์ฒ์ 10๋ฐ์ดํธ ์ฝ๊ธฐ
byte[] buffer = new byte[10];
raf.read(buffer);
System.out.println("์ฒ์ 10๋ฐ์ดํธ: " + new String(buffer));
// ํ์ผ์ 5๋ฒ์งธ ์์น๋ถํฐ "HELLO" ์ฝ์
raf.seek(5);
raf.write("HELLO".getBytes());
raf.close();
System.out.println("ํ์ผ ์์ ์๋ฃ!");
}
}
โ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ฒ๋ผ ํ์ผ์ ๋น ๋ฅด๊ฒ ์์ ๊ฐ๋ฅ!
๐ 46๋จ๊ณ: ๋ก๊ทธ ์์คํ ์ต์ ํ (Rolling Logs)
1. ๋ก๊ทธ ํ์ผ์ด ๋๋ฌด ์ปค์ง๋ฉด ์๋์ผ๋ก ์ ๋ก๊ทธ ํ์ผ ๋ง๋ค๊ธฐ
- ๋ก๊ทธ ํ์ผ์ด 10MB๊ฐ ๋์ผ๋ฉด ์๋ก์ด ๋ก๊ทธ ํ์ผ์ ์์ฑ
- ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ค๋ ๋ณด๊ดํ๋ฉด์ ์ ์ฅ ๊ณต๊ฐ๋ ์ ์ฝ ๊ฐ๋ฅ!
๐ ์์ : ์๋ ๋ก๊ทธ ๋กค๋ง ์์คํ
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class RollingLog {
private static final long MAX_SIZE = 10 * 1024 * 1024; // 10MB
public static void log(String message) throws IOException {
File logFile = new File("log.txt");
// ํ์ผ ํฌ๊ธฐ ์ฒดํฌ
if (logFile.length() > MAX_SIZE) {
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
File newFile = new File("log_" + timestamp + ".txt");
logFile.renameTo(newFile);
}
// ๋ก๊ทธ ์ฐ๊ธฐ
try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true))) {
writer.write(LocalDateTime.now() + " - " + message);
writer.newLine();
}
}
public static void main(String[] args) throws IOException {
log("์๋ฒ ์์๋จ.");
log("์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํจ.");
}
}
โ ๋ก๊ทธ ํ์ผ์ด ์ปค์ง๋ฉด ์๋์ผ๋ก ์๋ก์ด ํ์ผ์ ์์ฑ!
๐ 47๋จ๊ณ: ์คํธ๋ฆผ์ ํ์ฉํ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Pipeline)
1. ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋จ๊ณ๋ก ๊ฐ๊ณตํ ์ ์์๊น?
- ํ์ผ โ ์์ถ โ ์ํธํ โ ๋คํธ์ํฌ ์ ์ก ๊ฐ์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ๊ฐ๋ฅ!
๐ ์์ : ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ , ์์ถํ๊ณ , ๋คํธ์ํฌ๋ก ์ ์กํ๋ ์คํธ๋ฆผ ์ฒด์ด๋
import java.io.*;
import java.net.Socket;
import java.util.zip.GZIPOutputStream;
public class StreamPipelineExample {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("data.txt");
GZIPOutputStream gzipOut = new GZIPOutputStream(new FileOutputStream("data.gz"));
BufferedOutputStream netOut = new BufferedOutputStream(new Socket("localhost", 5000).getOutputStream());
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
gzipOut.write(buffer, 0, bytesRead); // ์์ถ
netOut.write(buffer, 0, bytesRead); // ๋คํธ์ํฌ ์ ์ก
}
fis.close();
gzipOut.close();
netOut.close();
System.out.println("๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๋ฃ!");
}
}
โ ํ์ผ์ ์ฝ๊ณ , ์์ถํ๊ณ , ๋คํธ์ํฌ๋ก ๋ณด๋ด๋ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ๊ฐ๋ฅ!