낭만 프로그래머

Java에서 문자열 Byte 계산관련 본문

Java/Common

Java에서 문자열 Byte 계산관련

조영래 2020. 2. 19. 13:54

프로젝트 수행 중에 Migration 시에 Oracle에서 계산되어지는 Byte 수와 Java에서 사용되어 지는 Byte 수가 달라 난감해 한적이 있었습니다. ㅜㅜ
그래서 정리 했습니다.

1. JVM이 수행되는 PC의 문자셋 유형을 확인 합니다. (cmd에서)

chcp

chcp 코드 값은 https://docs.microsoft.com/ko-kr/windows/win32/intl/code-page-identifiers 참조 하세요
949면 ks_c_5601-1987 이네요 euc-kr과 거의 동일하게 보시면 됩니다.
사용하는 byte 수를 확인해보니 한글은 2byte 나머지는 1byte 또는 2byte라고 하네요.

2. 오라클에서 사용되어 지는 문자셋 유형을 확인해 봅니다 (sqlplus에서)

select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';

AL32UTF8 이네요. 참고로 AL32UTF8 은 한글이 3byte 입니다.

3. JAVA 프로그램과 오라클 사이에 byte 차이 해결

    A. 방법1: 오라클을 3byte에서 2byte로 사용하도록 변경해 줍니다
       참조 : https://gompangyi.tistory.com/122

    B. 방법2: JAVA 프로그램에서 긴 문자열을 오라클의 문자셋에서 사용되어 지는 byte에 맞게 짤라서 Insert 하기
        짤라서라도 억지로 넣어야 하는 경우에 사용 (제가 마이그레이션 할 때 이렇게 했음 ㅋㅋ)

public String javaToOracleStringConvertor(String s, int limitByteLength) {
	byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
    if (limitByteLength.length <= length) {
		return s;
	}
	int totalByteCount = 0;
	for (int i = 0; i < s.length(); ) {
	    int cp = s.codePointAt(i);
	    int n = Character.charCount(cp);
	    int byteCount = s.substring(i, i + n).getBytes(StandardCharsets.UTF_8).length;
	    if ((totalByteCount + byteCount) > limitByteLength) {
	        break;
	    }
	    totalByteCount += byteCount;
	    	i += n;
	}
	return new String(bytes, 0, totalByteCount);
}

 

참조 :
https://gompangyi.tistory.com/122 
https://stackoverflow.com/questions/31455706/how-to-do-substring-for-utf8-string-in-java 
https://jun7222.tistory.com/494