PHpullh

LANGUAGE COMPARISON

File를 언어별로 비교하기

같은 개념을 실제 예제로 나란히 확인하고, 각 언어의 개별 설명으로 이어갈 수 있습니다.

Kotlin

파일 읽기/쓰기 기초

Kotlin에서 파일을 읽고 쓰는 가장 간단한 방법. java.io.File 확장 함수를 활용합니다.

<span class="kw">import</span> <span class="pk">java.io.File</span>

<span class="kw">fun</span> <span class="fn">main</span>() {
    <span class="kw">val</span> file = File(<span class="str">"hello.txt"</span>)

    <span class="cm">// 쓰기</span>
    file.<span class="fn">writeText</span>(<span class="str">"Hello, Kotlin!
한글도 OK"</span>, Charsets.UTF_8)

    <span class="cm">// 전체 읽기</span>
    <span class="kw">val</span> content = file.<span class="fn">readText</span>(Charsets.UTF_8)
    <span class="fn">println</span>(content)

    <span class="cm">// 줄 단위 읽기</span>
    file.<span class="fn">readLines</span>().<span class="fn">forEach</span> { <span class="fn">println</span>(it) }

    <span class="cm">// 줄 단위 처리 (대용량 파일)</span>
    file.<span class="fn">forEachLine</span> { line ->
        <span class="fn">println</span>(line.<span class="fn">trim</span>())
    }

    <span class="cm">// 추가 쓰기 (append)</span>
    file.<span class="fn">appendText</span>(<span class="str">"
추가 내용"</span>)

    <span class="cm">// 파일 존재 확인 후 삭제</span>
    <span class="kw">if</span> (file.<span class="fn">exists</span>()) file.<span class="fn">delete</span>()
}

Python

비동기 파일 I/O

파일 I/O를 비동기로 처리하여 이벤트 루프를 블로킹하지 않는 방법입니다.

import asyncio

# run_in_executor로 동기 I/O를 비동기로
async def read_file_async(path: str) -> str:
    loop = asyncio.get_running_loop()
    return await loop.run_in_executor(
        None,  # 기본 ThreadPoolExecutor
        lambda: open(path).read() if __import__('os').path.exists(path)
                else f"파일 없음: {path}"
    )

# 여러 파일 동시 읽기
async def read_many(paths: list[str]):
    tasks = [read_file_async(p) for p in paths]
    return await asyncio.gather(*tasks)

# aiofiles 패턴 시뮬레이션
class AsyncFile:
    def __init__(self, content=""):
        self.content = content

    async def __aenter__(self):
        await asyncio.sleep(0.01)  # I/O 시뮬레이션
        return self

    async def __aexit__(self, *args):
        pass

    async def read(self):
        await asyncio.sleep(0.01)
        return self.content

    async def write(self, data):
        await asyncio.sleep(0.01)
        self.content += data

async def main():
    # 동시 파일 처리
    async with AsyncFile("Hello, World!") as f:
        content = await f.read()
        print(f"내용: {content}")

    print("비동기 파일 I/O 완료")

asyncio.run(main())

Go

파일 I/O & os 패키지

Go의 파일 처리. os , bufio , io 패키지를 활용합니다.

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	// 파일 쓰기
	err := os.WriteFile("test.txt",
		[]byte("Hello\nGo\nWorld\n"), 0644)
	if err != nil { panic(err) }

	// 파일 읽기 (전체)
	data, err := os.ReadFile("test.txt")
	if err != nil { panic(err) }
	fmt.Print(string(data))

	// bufio로 줄 단위 읽기 (대용량 파일에 적합)
	f, err := os.Open("test.txt")
	if err != nil { panic(err) }
	defer f.Close()

	scanner := bufio.NewScanner(f)
	lineNum := 0
	for scanner.Scan() {
		lineNum++
		line := scanner.Text()
		fmt.Printf("%d: %s\n", lineNum, line)
	}
	if err := scanner.Err(); err != nil {
		fmt.Println("읽기 에러:", err)
	}

	// 파일 추가 쓰기 (append)
	af, err := os.OpenFile("test.txt",
		os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil { panic(err) }
	defer af.Close()
	fmt.Fprintln(af, "추가된 줄")

	// strings.NewReader — 문자열을 io.Reader로
	r := strings.NewReader("hello world")
	bufReader := bufio.NewReader(r)
	word, _ := bufReader.ReadString(' ')
	fmt.Printf("첫 단어: %q
", strings.TrimSpace(word))

	// 환경 변수
	home := os.Getenv("HOME")
	fmt.Println("홈 디렉토리:", home)

	// 임시 파일
	tmp, err := os.CreateTemp("", "myapp-*.txt")
	if err != nil { panic(err) }
	defer os.Remove(tmp.Name())
	fmt.Println("임시 파일:", tmp.Name())
	tmp.Close()
}

Java

NIO2 — Path & Files & WatchService

Java 7+ NIO2의 Path 와 Files 로 파일 처리를 현대적으로 합니다.

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.util.stream.Stream;

public class NIO2Demo {
    public static void main(String[] args) throws IOException {
        Path dir  = Path.of("temp");
        Path file = dir.resolve("hello.txt");

        // 디렉토리 & 파일 생성
        Files.createDirectories(dir);
        Files.writeString(file, "Hello, NIO2!\n한글도 OK",
            StandardCharsets.UTF_8);

        // 읽기
        String content = Files.readString(file, StandardCharsets.UTF_8);
        System.out.println(content);

        // 줄 단위 — Stream<String> (대용량에 적합)
        try (Stream<String> lines = Files.lines(file, StandardCharsets.UTF_8)) {
            lines.filter(l -> !l.isBlank())
                 .map(String::trim)
                 .forEach(System.out::println);
        }

        // 파일 복사, 이동, 삭제
        Path copy = dir.resolve("copy.txt");
        Files.copy(file, copy, StandardCopyOption.REPLACE_EXISTING);
        Files.move(copy, dir.resolve("moved.txt"),
            StandardCopyOption.REPLACE_EXISTING);
        Files.deleteIfExists(dir.resolve("moved.txt"));

        // 디렉토리 탐색
        try (Stream<Path> paths = Files.walk(dir)) {
            paths.filter(Files::isRegularFile)
                 .forEach(p -> System.out.println(p.getFileName()));
        }

        // 파일 속성
        var attr = Files.readAttributes(file,
            java.nio.file.attribute.BasicFileAttributes.class);
        System.out.println("크기: " + attr.size() + "B");
        System.out.println("생성: " + attr.creationTime());

        // Path 조작
        System.out.println(file.getFileName());  // hello.txt
        System.out.println(file.getParent());    // temp
        System.out.println(file.toAbsolutePath());

        // 정리
        Files.deleteIfExists(file);
        Files.deleteIfExists(dir);
    }
}

PHP

파일 읽기

작은 파일을 한 번에 읽을 때 가장 간단한 file_get_contents 예제입니다.

<?php
$path = __FILE__;
echo file_get_contents($path) !== false ? 'loaded' : 'failed';