본문 바로가기
개발 업무(코딩)-개발자였을때 썼던..

파일 오픈해서 그 내용 저장시키기(유니코드, 바이너리) using c

by 주용사 2023. 1. 9.
728x90

c로 개발하다보면 java나 js에 있는 기능들을 사용해야할 때가 종종 생긴다. 자료를 못찾는 것인지 정확힌 모르겠지만 딱 맞는 자료가 마땅히 없다. 자료를 참고하고 수십번의 노가다 작업을 통해 java와 c에서 만들었을 때 같은 결과물을 도출해냈다.

일단 java 소스

/* Insert */
    public static boolean Insert()
    {
        Connection          con = null;
        PreparedStatement   pstmt = null;

        String QRY = "INSERT INTO TRADE_REQUEST_BIN  ("+
                            "REQ_DATE , REQ_TIME , SVC_TYPE , BANK_CODE, "+
                            "COMP_CODE, SEQ_NO   , MSG_CODE , SEND_FLAG, RECV_FLAG, "+
                            "SEND_DATE, SEND_TIME, RECV_DATE, RECV_TIME, SEND_MSG , "+
                            "RECV_MSG, BIN_DATA ) VALUES ("  +
                            "?, ?, ?, ?, ?,  ?, ?, ?, ?, ?,  ?, ?, ?, ?, ?,?)";

        int cnt = 0;
        try {
            con = getConnection();
            con.setAutoCommit(false);

            pstmt = con.prepareStatement(QRY);

            pstmt.setString (1, "20210907"       );
            pstmt.setString (2, "100000" );
            pstmt.setString (3, "DBT" );
            pstmt.setString (4, "  1"     );
            pstmt.setString (5, "QTINVEST"     );
            pstmt.setString (6, "900002"     );
            pstmt.setString (7, "0700100"     );
            pstmt.setString (8, "N"     );
            pstmt.setString (9,"N"    );
            pstmt.setString (10,""    );
            pstmt.setString (11,""    );
            pstmt.setString (12,""    );
            pstmt.setString (13,""    );
            pstmt.setString (14,"         QTINVEST  0700100190000220180516202216                                       1             D0000001  7110004524401   1        20210907     Y3046062311   123451234512345                     QTINVEST    1       0QTINVEST           01jpg 0043913                                                 ");
            pstmt.setString (15,""    );

            File Blob = new File("/home/tqtcore/KSNET/Online/RFB_PRF/test/image.jpg");
            FileInputStream is = new FileInputStream (Blob);
            FileInputStream is2 = is;
            pstmt.setBinaryStream(16, is2, (int) Blob.length());
            cnt = pstmt.executeUpdate();

            con.commit();
            return true;
        } catch(Throwable t) {
            t.printStackTrace();
        } finally {
            try {if(pstmt!=null){pstmt.close();pstmt= null;}}catch(Exception e){}
            try {if(con !=null) {con.close( );}}catch(Exception e){}
        }
        return false;
    }

여기서 내가 구현하고 싶었던 구간은

FileInputStream is2 = is;

pstmt.setBinaryStream(16, is2, (int) Blob.length());

이거다. 자바 소스에서 저기서 파일을 오픈해서 파일의 내용을 그대로 db에 저장시킨다.

--

이 부분을 c를 이용해 구현했다.

/***************************************************************************************************************/
    /* open file                                                                                                   */
    /***************************************************************************************************************/
    /* file */
    FILE *fp;
    char ztemp[1024];
    char ztemp2[1024];
    int nsize = 0;
    char ch;
    fp = fopen("/home/tqtcore/KSNET/Online/RFB_PRF/test/image.jpg", "r");


    /* get file size */
    fseek(fp, 0, SEEK_END);
    nsize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    /* 여기서 선언안하면 malloc으로 끌어와야함..*/
    char buffer[nsize + 1];
    char hex[nsize*2 +1];
    char zquery[nsize*2 + 4096];

    memset(buffer, 0x00, sizeof(buffer));
    memset(hex, 0x00, sizeof(hex));

    /* file을 fgetc로 하나씩 파일의 끝까지 읽어오고 hex로 저장한다 */
    /* hex로 변경하는 이유는 파일의 내용인 이 유니코드들을 읽어오다가 깨지기 때문이고 fread는 또 안먹는다 */
    /* rb로 읽어오나 rt로 읽어오나 결과물은 같다,,wchar_t로도 해결이 안됐다  */
    /* 헥사도 길이 비교해가면서 노동한 결과물이다 ffffffff 이런것들이 문제였음 */
    /* 더좋은 방법이 있다면 이 과정을 안하고 바로 넣는게 맞지만 현재로썬 최선 */
    for (ii = 0; (ii < nsize && (!(ch = fgetc(fp)) != EOF) ); ii++)
    {
        if(ii == 0)
        {
            sprintf(hex, "%02x", ch);
            if(strlen(hex) >= 4)
            {
                sprintf(hex, "%s", hex + strlen(hex) - 2 );
            }
        }
        else if(ii > 0)
        {
            memset(ztemp, 0x00, sizeof(ztemp));
            sprintf(ztemp, "%02x", ch);

            /* convert ffffa8 -> a8 */
            if(strlen(ztemp) >= 4)
            {
                memset(ztemp2, 0x00, sizeof(ztemp2));
                sprintf(ztemp2, "%s", ztemp+strlen(ztemp) - 2);
                memset(ztemp, 0x00, sizeof(ztemp));
                sprintf(ztemp, "%s", ztemp2);
            }
            strncat(hex, ztemp, strlen(ztemp));
        }
    }

    //NorLog(USR_DEBUG, "hex [%s]", hex);

    /* file close */
    fclose(fp);

/***************************************************************************************************************/
    /* KSNET db insert                                                                                             */
    /***************************************************************************************************************/
    memset(zquery, 0x00, sizeof(zquery));
    sprintf (zquery, "INSERT INTO TRADE_REQUEST_BIN \
            (REQ_DATE, \
             REQ_TIME, \
             SVC_TYPE, \
             BANK_CODE, \
             COMP_CODE, \
             SEQ_NO, \
             MSG_CODE, \
             SEND_FLAG, \
             RECV_FLAG, \
             SEND_DATE, \
             SEND_TIME, \
             RECV_DATE, \
             RECV_TIME, \
             SEND_MSG, \
             RECV_MSG, \
             BIN_DATA \
            ) \
            VALUES \
            ( TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM('%s'),\
              TRIM(UNHEX('%s')));"
            , zyyyymmdd, zhhmmss, zsvc_type, zbank_code, zcomp_code, zseq_no, zmsg_code
            , zsend_flag, "N", zsend_date, zsend_time, "", "", zsend_msg,  "", hex);

    //NorLog(USR_DEBUG, "zquery [%s]", zquery);

    rt = DB_Thread_Execute(lpInfo->lpMasterDB, zquery, __LINE__, __FILE__);

    if (rt != OK)
    {
        DB_Thread_Rollback(lpInfo->lpMasterDB, __LINE__, __FILE__);

        NorLog (USR_WARN, "TR ERROR.. LINE[%d] FILE[%s]", __LINE__, __FILE__);
        return 9990;
    }

c로 구현한 것이다. 여기서 주목할 것은 두개이다.

java와 똑같이 구현한 부분. 그리고 sql쿼리 자체에서 unhex로 넣는 부분.

일단 알아야할 건 난 linux 환경에서 구현했다.

참고. sql에서는 hex로 셀렉해오면 대문자로 치환되서 나온다.

참고자료( 앞쪽은 바이너리 뒤쪽은 헥사,,결국은 같은 값을 도출했다는 사진임)

PNG확장자의 이미지로도 테스트해봄

728x90