LoGin
article thumbnail
반응형

 

파일 내용을 합칠 일이 드물지만 일하는 중 SQL 파일을 하나로 합쳐야 하는 경우가 생겼습니다.

 

Java NIO(New Input/Output)는 JDK 1.4부터 도입된 새로운 입출력 API로, 기존 IO 보다 빨라졌다고 하네요.

 

Java NIO란 뭘까

New Input/Output의 약자로, 기존 IO의 느린 처리 속도를 개선하고 효율적인 입출력 작업을 제공하기 위해 도입된 API입니다.

 

그렇다면 IO는 뭘까

자바의 표준 라이브러리로, 프로그램과 외부 (파일, 네트워크 등) 간의 데이터를 입출력하는 기능을 제공합니다. Java IO는 JDK1.0부터 포함된 API로, 스트림 기반의 동기식 입출력을 제공합니다. 자바에서 파일 읽기, 파일 쓰기, 네트워크 통신 등의 다양한 입출력 작업을 수행하는 데 사용되겠죠.

 

스트림 : 데이터를 바이트 단위로 읽고 쓰는 일련의 데이터 흐름을 의미합니다. 입력 스트림(Input Stream)과 출력 스트림(Output Striam)으로 나뉩니다.

 

둘의 차이점(개선사항) 으로는 입출력은 스트림에서 채널기반으로 바뀌고, 버퍼링(Buffered)을 사용하며 비동기 입출력을 지원하고, 블로킹과 논블로킹을 모두 지원한다는 점입니다.

 

 

Java NIO의 특징

채널(channerl)과 버퍼(Buffer)

NIO의 가장 큰 특징으로는 채널(channerl)과 버퍼(Buffer)를 사용한다는 점입니다.

 

채널(Channerl) : 데이터가 입출력되는 통로라고 생각하면 됩니다. 채널은 양방향 입출력이 가능하며, 동시에 읽고 쓰기가 가능합니다. 채널은 스트림과 달리 데이터를 한 번에 여러 바이트씩 읽고 쓸 수 있어 효율적입니다.

 

버퍼(Buffer): 데이터를 임시로 저장하는 메모리 공간입니다. NIO는 버퍼를 사용하여 데이터를 읽고 쓰기 때문에, 필요한 데이터를 메모리에 한꺼번에 담아 효율적으로 처리할 수 있습니다.

 

비동기(Non-Blocking) I/O

비동기는 데이터가 준비될 때까지 기다리지 않고 다른 작업을 수행할 수 있어 효율적인 멀티태스킹이 가능합니다.

블로킹 방식은 기존 IO에서 입출력 작업이 완료될 때까지 작업이 실행되고 있는 스레드가 블로킹되겠죠.

NIO는 채널만 선택해서 작업을 처리하기 때문에, 스레드가 블로킹되지 않습니다.

 

자바에서 설명해 주는 NIO 사이트 한번 방문해 보시면 설명 잘 되어있으니 참고하세요.

 

Core Libraries

 

docs.oracle.com

 

예제에 사용할 라이브러리 메서드 설명

  • Paths.get(String) : 문자열로 지정된 파일 경로를 `Path` 객체로 반환
  • toFile() : `Path` 객체를 `File` 객체로 변환
  • exists() : 파일이 존재하는지 확인, 존재하면 true, 없으면 false 반환
  • createNewFile() : 새로운 파일 생성, 파일이 이미 존재하면 false 없으면 파일 생성하고 true 반환
  • extension : 파일의 확장자를 반환
  • BufferedReader(FileReader(file) : 지정된 파일을 읽기 위해 파일 리더 생성 후 효율적인 파일 읽기를 위한 버퍼링 된 리더 생성
  • File.writeString : 지정된 경로의 파일에 문자열을 씀
  • StandardOpenOption.APPEND : 기존 파일 내용에 문자열 추가
  • BufferedReader.readLine() : 파일의 다음 줄을 읽음, 줄이 없으면 null 반환
  •  also {} : 읽은 내용을 line 변수에 할당

 

 

파일 내용 합치기 예제

흐름은

1. 파일 경로 찾고 해당 위치에 파일을 만듭니다. (있다면 삭제)

2. 합칠 파일들을 ListUp 합니다.

3. 리스트를 돌면서 한 파일에 데이터를 추가합니다.

 

import java.io.BufferedReader
import java.io.FileReader
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardOpenOption

/**
 * 동작 : erd/nps/init에 있는 파일들을 합쳐 erd/combined.sql에 넣는다.
 */
fun main() {
    // 합칠 파일 경로
    val combinedFilePath = Paths.get("erd/combined.sql")
    val combinedFile = combinedFilePath.toFile()

    // 기존 파일 삭제 후 새 파일 생성
    if (combinedFile.exists()) { // exists() : 파일이 존재하는지 테스트 true false 반환
        println("======================== 파일이 존재해 삭제합니다 ==========================");
        combinedFile.delete() // 존재 시 삭제
    }
    combinedFile.createNewFile() // 파일 생성

    // 합칠 파일 List Up /// 파일이고 .sql인 확장자
    val sqlFiles = Paths.get("erd/nps/init").toFile().listFiles { file -> file.isFile && file.extension == "sql" }
        ?.sortBy { it.name }

    // 파일 합치기
    sqlFiles?.forEach { file ->
        val br = BufferedReader(FileReader(file))
        println(file)
        println(br)
        var line: String?

        // 파일 시작 주석 달기
        Files.writeString(combinedFilePath, "-- 시작 파일명 : ${file.name}\n", StandardOpenOption.APPEND)

        // 본문 입력
        while (br.readLine().also { line = it } != null) {
            Files.writeString(combinedFilePath, line!! + "\n", StandardOpenOption.APPEND)
        }

        // 파일 끝 표시
        Files.writeString(combinedFilePath, "-- 끝 파일명 : ${file.name}------------------------", StandardOpenOption.APPEND)
    }
    println("모든 SQL 파일이 erd/combined.sql로 성공적으로 합쳐졌습니다.")
}

 

결과

전부 합치고 나니 73000줄....

이거 덕분에 파일 변화를 확인할 수 있게 됐습니다.

 

 

잘 합쳐졌네요.

파일 내용 합치기 말고도 파일 복사, 이동, 삭제, 잠금, 권한 설정 등 할 수 있습니다.

 

사용했던 메모...

728x90
반응형
profile

LoGin

@LoGinShin

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!