본문 바로가기
Develops/JAVA

[JAVA] 문자열 Byte로 자르기

by SLOTH91 2024. 3. 3.
반응형

 문자열을 지정된 Encoding으로 Byte Size만큼 자르는 메서드 
 - '\n' 값이 없을 경우 Byte Size 로 Split 
 - Byte Size 내의 가장 가까운 '\n' 값을 기준으로  Split
 - '\n\n' 값이 있을 경우 강제 Split

 


      /**
        * <pre>문자열을 지정된 Encoding으로 Byte Size만큼 자르는 메서드</pre>
        * @param raw 문자열
        * @param len 자를 Byte Size
        * @param encoding 문자열의 인코딩 방법 ex) UTF-8, EUC-KR, CP949
        * @return String[] len에서 지정한 크기로 자른 문자열 결과값을 배열로 반환
        */
    public static String[] parseStringByBytes(String raw, int len, String encoding) {  
        if (raw == null) return null;
        String[] ary = null;
        try {
            byte[] rawBytes = raw.getBytes(encoding);
            int rawLength = rawBytes.length;


            if(rawLength > len){
                int tmpSplitNumber = 0;
                int limitLength = len;
                
                // '\n' Index List
                ArrayList<Integer> aryIndentList = new ArrayList<Integer>();
                // Final Split Index List
                ArrayList<Integer> aryIndentResult = new ArrayList<Integer>();

                for (int i = 0; i < rawLength; i++) {
                    // '\n' 값 체크
                    if (rawBytes[i] == 10) aryIndentList.add(i+1);
                }


                // '\n' 값이 존재하지 않는 경우
                if (aryIndentList.size() == 0) {
                    if ( rawLength > len ) {
                        while (rawLength > limitLength) {
                            aryIndentResult.add(limitLength);
                            limitLength = limitLength + len; 
                        }
                    }
                    aryIndentResult.add(rawLength);
                }
                else{
                    for (int i = 0; i < aryIndentList.size(); i++) {
                        System.out.println("i:"+i);
                        int compareNumber = aryIndentList.get(i);
                        
                        // '\n' 값이 연달아 있는지 체크하여 강제 split 처리
                        if (aryIndentList.size() > (i+1) && aryIndentList.get(i+1) -1 == compareNumber) {
                            compareNumber = aryIndentList.get(i+1);
                            i++;
                            if ( compareNumber > limitLength ) {
                                tmpSplitNumber = limitLength;
                                while ( compareNumber > limitLength ) {
                                    aryIndentResult.add(compareNumber);
                                    limitLength = tmpSplitNumber + len;
                                    if ( compareNumber > limitLength ) { tmpSplitNumber = limitLength; }
                                    else {
                                        aryIndentResult.add(compareNumber);
                                        tmpSplitNumber = compareNumber;
                                        limitLength = tmpSplitNumber + len;
                                    }
                                }
                            } else { 
                                aryIndentResult.add(compareNumber);
                                tmpSplitNumber = compareNumber;
                                limitLength = tmpSplitNumber + len;
                            }
                        }
                        else {
                            // '\n' 값이 마지막일 경우
                            if (aryIndentList.size() == (i+1)) {
                                if ( compareNumber > limitLength ) {
                                    tmpSplitNumber = limitLength;
                                    while ( compareNumber > limitLength ) {
                                        aryIndentResult.add(tmpSplitNumber);
                                        limitLength = tmpSplitNumber + len;
                                        if ( compareNumber > limitLength ) { tmpSplitNumber = limitLength; }
                                    }
                                }
                                tmpSplitNumber = compareNumber;
                             
                                if ( tmpSplitNumber <= rawLength ) {
                                    /* '\n'의 위치로부터 문자열의 마지막까지 80byte 이내일 경우  */
                                    if (tmpSplitNumber >= (limitLength - 80)) {
                                        aryIndentResult.add(limitLength);
                                    }
                                    else {
                                        while ( tmpSplitNumber < rawLength ) {
                                            aryIndentResult.add(tmpSplitNumber);
                                            limitLength = tmpSplitNumber + len;
                                            if ( rawLength > limitLength ) { tmpSplitNumber = limitLength; }
                                            else tmpSplitNumber = rawLength;
                                        }
                                        aryIndentResult.add(tmpSplitNumber);
                                        System.out.println(tmpSplitNumber);
                                    }
                                }
                                else { aryIndentResult.add(compareNumber); System.out.println(compareNumber);}
                            }
                            else {
                                if ( compareNumber < limitLength ) { tmpSplitNumber = compareNumber; }
                                else if ( compareNumber == limitLength ) {
                                    aryIndentResult.add(compareNumber);
                                    tmpSplitNumber = compareNumber;
                                    limitLength = limitLength + len;
                                }
                                else { 
                                    while (compareNumber > tmpSplitNumber) {
                                        aryIndentResult.add(tmpSplitNumber);
                                        limitLength = tmpSplitNumber + len;
                                        if ( compareNumber > limitLength ) { tmpSplitNumber = limitLength; }
                                        else tmpSplitNumber = compareNumber;
                                    }
                                }
                            }
                        }
                    }
                }

                int index = 0;
                int offset = 0;

 

                int hangulByteNum = encoding.equals("UTF-8") ? 3 : 2;


                int aryLength = aryIndentResult.size();
                ary = new String[aryLength];
                for(int i=0; i<aryLength; i++){
                    System.out.println("i:"+i);
                    int minusByteNum = 0;
                    if (i == 0) offset = aryIndentResult.get(i);
                    else offset = aryIndentResult.get(i) - aryIndentResult.get(i-1);
                    if(index + offset > rawBytes.length){
                        offset = rawBytes.length - index;
                    }
                    for(int j=0; j<offset; j++){ 
                        if(((int)rawBytes[index + j] & 0x80) != 0){
                            minusByteNum ++;
                        }
                    }
                    if(minusByteNum % hangulByteNum != 0){
                        offset -= minusByteNum % hangulByteNum;
                    }     
                    ary[i] = new String(rawBytes, index, offset, encoding);  
                    index += offset ;
                }    
            } else {
                ary = new String[]{raw};
            }    
        } catch(Exception e) {
            System.out.println("[Exception]" +e.getLocalizedMessage());
            StackTraceElement[] elem = e.getStackTrace();
            for (int i = 0; i < elem.length; i++)
                System.out.println(elem[i]);
        }
        return ary;
    }

반응형