** ๐Ÿ“Œ1๋‹จ๊ณ„: ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์ด๋ž€? **

๐Ÿ’ก ๋นจ๋Œ€๋กœ ์ฃผ์Šค๋ฅผ ๋งˆ์‹œ๋Š” ๊ฑธ ๋– ์˜ฌ๋ ค ๋ณด์„ธ์š”.

์ฃผ์Šค(๋ฐ์ดํ„ฐ)๊ฐ€ ์ปต(ํŒŒ์ผ)์—์„œ ์ž…(ํ”„๋กœ๊ทธ๋žจ)์œผ๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์ด ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์ด๊ณ ,

์ฃผ์Šค๋ฅผ ๋‹ค๋ฅธ ์ปต(ํŒŒ์ผ)์œผ๋กœ ๋ถ“๋Š” ๊ฒƒ์ด ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์ด์—์š”!


2๋‹จ๊ณ„: ์ŠคํŠธ๋ฆผ์˜ ์ข…๋ฅ˜ (๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ vs. ๋ฌธ์ž ์ŠคํŠธ๋ฆผ)

๐Ÿ“Œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ (Byte Stream)

๐Ÿ“Œ ๋ฌธ์ž ์ŠคํŠธ๋ฆผ (Character Stream)

๐Ÿ’ก ๋น„์œ :

๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์€ ์•ŒํŒŒ๋ฒณ ํ•œ ๊ธ€์ž์”ฉ ์ฝ๋Š” ๊ฒƒ,

๋ฌธ์ž ์ŠคํŠธ๋ฆผ์€ ๋ฌธ์žฅ ๋‹จ์œ„๋กœ ์ฝ๋Š” ๊ฒƒ์ด์—์š”!


3๋‹จ๊ณ„: ์ŠคํŠธ๋ฆผ ํด๋ž˜์Šค ๊ตฌ์กฐ์™€ ์ƒ์† ๊ด€๊ณ„

์ž๋ฐ”์˜ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์€ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„(์ƒ์†)๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์–ด์š”.

๐Ÿ“Œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๊ตฌ์กฐ

๐Ÿ“Œ ๋ฌธ์ž ์ŠคํŠธ๋ฆผ ๊ตฌ์กฐ

๐Ÿ’ก ๋น„์œ :

์ด๊ฑด ๋งˆ์น˜, โ€œ์—„๋งˆ(๋ถ€๋ชจ ํด๋ž˜์Šค)์™€ ์•„๋“ค(์ž์‹ ํด๋ž˜์Šค)โ€ ๊ฐ™์€ ๊ด€๊ณ„์˜ˆ์š”.

์—„๋งˆ๊ฐ€ ๊ธฐ๋ณธ์ ์ธ ์š”๋ฆฌ๋ฅผ ๊ฐ€๋ฅด์ณ์ฃผ๊ณ , ์•„๋“ค์€ ๊ทธ๊ฑธ ์‘์šฉํ•ด์„œ ๋” ๋ง›์žˆ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ !


4๋‹จ๊ณ„: ์ŠคํŠธ๋ฆผ ์ฒด์ด๋‹ (Chaining)๊ณผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

์ŠคํŠธ๋ฆผ์„ ์—ฌ๋Ÿฌ ๊ฐœ ์—ฐ๊ฒฐํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

์ด๊ฑธ ์ŠคํŠธ๋ฆผ ์ฒด์ด๋‹ (Chaining)์ด๋ผ๊ณ  ํ•ด์š”.

๐Ÿ“Œ ์˜ˆ์ œ: ํŒŒ์ผ์„ ์ฝ์„ ๋•Œ ๋ฒ„ํผ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์†๋„๊ฐ€ ๋นจ๋ผ์ง

FileInputStream fis = new FileInputStream("data.txt");
BufferedInputStream bis = new BufferedInputStream(fis);

๐Ÿ’ก ๋น„์œ :

์Œ์‹์„ ๋จน์„ ๋•Œ โ€œ์ˆŸ๊ฐ€๋ฝโ€์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ํŽธํ•˜์ฃ ?

์ŠคํŠธ๋ฆผ ์ฒด์ด๋‹์€ ๊ทธ๋ฆ‡ โ†’ ์ˆŸ๊ฐ€๋ฝ โ†’ ์ž…์ฒ˜๋Ÿผ ๋„๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋” ํšจ์œจ์ ์œผ๋กœ ๋จน๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.


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("์˜ค๋ฅ˜ ๋ฐœ์ƒ!");

๐Ÿ’ก ๋น„์œ :


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์˜ ํ•ต์‹ฌ ๊ฐœ๋…

๐Ÿ“Œ 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)์ด๋ž€?

๐Ÿ“Œ ์˜ˆ์ œ: ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ•œ ํŒŒ์ผ ๋ณต์‚ฌ (๋” ๋น ๋ฆ„!)

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-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)

๐Ÿ“Œ ์˜ˆ์ œ: Direct Buffer ์‚ฌ์šฉ

ByteBuffer buffer = ByteBuffer.allocateDirect(1024); // Direct Buffer ์ƒ์„ฑ

โœ… ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๊ฐ€ ์ ์–ด ์†๋„๊ฐ€ ํ›จ์”ฌ ๋นจ๋ผ์ ธ์š”!


๐Ÿ“Œ 9๋‹จ๊ณ„: ๋ณด์•ˆ(Security) & ์•”ํ˜ธํ™”(Encryption)

๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ฑฐ๋‚˜, ์ค‘์š”ํ•œ ํŒŒ์ผ์„ ์ €์žฅํ•  ๋•Œ๋Š” ๋ณด์•ˆ์ด ์ค‘์š”ํ•ด์š”!

์ž๋ฐ”์—์„œ๋Š” ์•”ํ˜ธํ™”์™€ ๋ณตํ˜ธํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”.

1. ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”ํ•˜๊ธฐ (AES)

๐Ÿ“Œ ์˜ˆ์ œ: 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)

๐Ÿ“Œ ์˜ˆ์ œ: ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

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. ๋กœ๊ทธ ์‹œ์Šคํ…œ ๊ตฌํ˜„

๐Ÿ“Œ ์˜ˆ์ œ: ๋กœ๊ทธ ์‹œ์Šคํ…œ

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. ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ํ•œ ๋ฒˆ์— ์ฝ์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊น€!

๐Ÿ“Œ ์˜ˆ์ œ: 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. ์ดˆ๊ณ ์† ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ์›ํ•œ๋‹ค๋ฉด?

๐Ÿ“Œ ์˜ˆ์ œ: ์ดˆ๊ณ ์† ํŒŒ์ผ ์ฝ๊ธฐ

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-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. ๊ธฐ๋ณธ ์ง๋ ฌํ™”๋Š” ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค?

๐Ÿ“Œ ์˜ˆ์ œ: 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. ํŒŒ์ผ์—์„œ ํŠน์ • ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿ“Œ ์˜ˆ์ œ: ํŒŒ์ผ ํŠน์ • ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ ์ˆ˜์ •

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. ๋กœ๊ทธ ํŒŒ์ผ์ด ๋„ˆ๋ฌด ์ปค์ง€๋ฉด ์ž๋™์œผ๋กœ ์ƒˆ ๋กœ๊ทธ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

๐Ÿ“Œ ์˜ˆ์ œ: ์ž๋™ ๋กœ๊ทธ ๋กค๋ง ์‹œ์Šคํ…œ

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. ์‹ค์‹œ๊ฐ„์œผ๋กœ ํŠน์ • ํด๋”์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ

๐Ÿ“Œ ์˜ˆ์ œ: ํŠน์ • ํด๋”๋ฅผ ๊ฐ์‹œํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๋Š” ์ฝ”๋“œ

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์— ํŒŒ์ผ ์—…๋กœ๋“œ (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๋Š” ๋А๋ฆฌ๋‹ค!

๐Ÿ“Œ ์˜ˆ์ œ: ๋น„๋™๊ธฐ ํŒŒ์ผ ์ฝ๊ธฐ (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. ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•

๐Ÿ“Œ ์˜ˆ์ œ: ๋„คํŠธ์›Œํฌ์—์„œ ๋ฒ„ํผ๋ฅผ ํ™œ์šฉํ•œ ํŒŒ์ผ ์ „์†ก

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์„ ์‚ฌ์šฉํ•œ ํŒŒ์ผ ์••์ถ•

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๋ฅผ ์‚ฌ์šฉํ•œ ์ดˆ๊ณ ์† ํŒŒ์ผ ์ „์†ก (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) ๋ชจ๋ธ์ด ํ•™์Šตํ•˜๋Š” ๋ฐฉ๋ฒ•?

๐Ÿ“Œ ์˜ˆ์ œ: 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์— ํŒŒ์ผ ์—…๋กœ๋“œํ•˜๊ธฐ

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. ๊ธฐ์กด ์Šค๋ ˆ๋“œ๋Š” ๋„ˆ๋ฌด ๋ฌด๊ฒ๋‹ค!

๐Ÿ“Œ ์˜ˆ์ œ: 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. ๋ฏธ๋ž˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํด๋ผ์šฐ๋“œ์—์„œ ์‹คํ–‰๋จ

๐Ÿ“Œ ์˜ˆ์ œ: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๊ธฐ๋ฐ˜ ๋กœ๊ทธ ์ €์žฅ ์‹œ์Šคํ…œ

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. ๊ธฐ์กด์˜ ๋„คํŠธ์›Œํฌ๋Š” ๋ณด์•ˆ์ด ์ทจ์•ฝํ•˜๋‹ค!

๐Ÿ“Œ ์˜ˆ์ œ: 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 ์‹œ์Šคํ…œ

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๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ฃผ๊ณ ๋ฐ›๋Š” ํ™˜๊ฒฝ์ด ๋งŒ๋“ค์–ด์งˆ ๊ฒƒ!

๐Ÿ“Œ ์˜ˆ์ œ: ๊ฐ์ •์„ ๋ถ„์„ํ•ด ํŒŒ์ผ ์ž…์ถœ๋ ฅ ๊ฒฐ์ •ํ•˜๊ธฐ

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. ์ง€๊ตฌ์™€ ํ™”์„ฑ ๊ฐ„ ๋ฐ์ดํ„ฐ ์ „์†ก์€ ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?

๐Ÿ“Œ ์˜ˆ์ œ: ๋ ˆ์ด์ € ๊ธฐ๋ฐ˜ ์šฐ์ฃผ ๋ฐ์ดํ„ฐ ์ „์†ก ์‹œ๋ฎฌ๋ ˆ์ด์…˜

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. ์ธ๊ฐ„์˜ ๋‡ŒํŒŒ๋ฅผ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿ“Œ ์˜ˆ์ œ: ๋‡ŒํŒŒ(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์˜ ๋์„ ๋„˜์–ด, ์ฐฝ์กฐ์˜ ์˜์—ญ์œผ๋กœ!

๋‹จ๊ณ„ ๋‚ด์šฉ
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. ์ดˆ๊ณ ์† ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ์›ํ•œ๋‹ค๋ฉด?

๐Ÿ“Œ ์˜ˆ์ œ: ์ดˆ๊ณ ์† ํŒŒ์ผ ์ฝ๊ธฐ

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-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. ๊ธฐ๋ณธ ์ง๋ ฌํ™”๋Š” ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค?

๐Ÿ“Œ ์˜ˆ์ œ: 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. ํŒŒ์ผ์—์„œ ํŠน์ • ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿ“Œ ์˜ˆ์ œ: ํŒŒ์ผ ํŠน์ • ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ ์ˆ˜์ •

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. ๋กœ๊ทธ ํŒŒ์ผ์ด ๋„ˆ๋ฌด ์ปค์ง€๋ฉด ์ž๋™์œผ๋กœ ์ƒˆ ๋กœ๊ทธ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

๐Ÿ“Œ ์˜ˆ์ œ: ์ž๋™ ๋กœ๊ทธ ๋กค๋ง ์‹œ์Šคํ…œ

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("๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์™„๋ฃŒ!");
    }
}

โœ… ํŒŒ์ผ์„ ์ฝ๊ณ , ์••์ถ•ํ•˜๊ณ , ๋„คํŠธ์›Œํฌ๋กœ ๋ณด๋‚ด๋Š” ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ• ๊ฐ€๋Šฅ!