java에서 압축파일을 생성하기 위한 편리한 유틸들도 있지만 기본적인 java 기반으로 압축파일을 생성하는 예제를 작성해 보았습니다.

 

일단 임의의 폴더에 압축 테스트를 진행할 몇개의 파일들을 준비해 줍니다.

 

 

 

zip 파일도 일반 파일과 동일하게 입출력을 통하여 생성을 하기 때문에 입출력에 사용되는 IOStream들을 선언 합니다.

 

               FileInputStream fis = null;

               FileOutputStream fos = null;

               ZipOutputStream zos = null;

 

파일을 읽어오기 위한 스트림과 파일에 쓰기위한 스트림, 나머지 하나는 압축파일에 쓰기위한 스트림 이렇게 3개의 stream을 선언합니다.

3개의 stream을 보면 감이 잡히겠지만 FileInputStream으로 압축하려는 파일을 읽어오고 FileOutputStream으로 읽어온 데이터를 기록하는데 이것을 ZipOutputStream의 입력으로 보내서 쓰게되면 압축파일이 생성되는 프로세스 입니다.

 

간단한 내용이니 소스를 바로 보도록 합니다.

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.zip.ZipEntry;

import java.util.zip.ZipOutputStream;

 

 

public class ZipTest {

 

       public static void main(String[] args) {

               // TODO Auto-generated method stub

               FileInputStream fis = null;

               FileOutputStream fos = null;

               ZipOutputStream zos = null;

 

               String fileFolder = "C:/del/ziptest";

               File file = new File(fileFolder);

               File[] fileList = file.listFiles();

              

               try {

                      fos = new FileOutputStream("C:/del/ziptest/test.zip");

                      zos = new ZipOutputStream(fos);

                     

                      for(File f : fileList) {

                             fis = new FileInputStream(f);

                             ZipEntry zipEntry = new ZipEntry(f.getName());

                             zos.putNextEntry(zipEntry);

                            

                             byte[] bytes = new byte[1024];

                             int length;

                             while((length = fis.read(bytes)) >= 0) {

                                    zos.write(bytes, 0, length);

                             }

                             fis.close();

                             zos.closeEntry();

                      }

                      zos.close();

                      fos.close();

               } catch(IOException ie) {

                      ie.getMessage();

               }

       }

 }

 

 

폴더에 있는 압축하려는 파일 목록을 가져오는 부분의 소스는

 

               String fileFolder = "C:/del/ziptest";

               File file = new File(fileFolder);

               File[] fileList = file.listFiles();

 

이렇게 File[] 배열로 받아옵니다.

 

읽어온 파일을 기록하는 output 스트림의 방향을 zip으로 보내는 부분은

 

                      fos = new FileOutputStream("C:/del/ziptest/test.zip");

                      zos = new ZipOutputStream(fos);

 

여기입니다.

저장하려는 파일 위치와 파일명(C:/del/ziptest/test.zip)을 설정합니다.

 

폴더에 파일이 여러 개 이므로 for 문을 이용하여 파일을 하나씩 불러와 zos에 기록하면 작업이 완료 됩니다.

 

                   for(File f : fileList) {

                             fis = new FileInputStream(f);

                             ZipEntry zipEntry = new ZipEntry(f.getName());

                             zos.putNextEntry(zipEntry);

                            

                             byte[] bytes = new byte[1024];

                             int length;

                             while((length = fis.read(bytes)) >= 0) {

                                    zos.write(bytes, 0, length);

                             }

                             fis.close();

                             zos.closeEntry();

                      }

 

프로그램을 실행합니다. 압축파일이 생성되겠죠.

 

 

 

 

생성된 압축파일 test.zip을 열어보면 처음에 준비한 파일 3개파일이 압축되어 들어있는 것을 볼 수 있습니다.

 

 

- copy coding -

 

 

JDBC Batch는 프로젝트와 별개로 작업하고 실행을 할 수 있어서 수정사항 발생시 바로바로 적용을 할 수 있다는 점이 운영하는 측에서는 편한 작업이 될 수 있습니다.  그러나 Batch job의 개수가 많아지거나 Table 사이즈가 크거나 작업의 우선 순위가 있어야 하는 경우 등의 상황에서는 다른 방법과 병행해서 사용하는게 개인적으로는 좋았던 것 같습니다.

 

 

 

오늘 기록해 놓으려는 소스는 SELECT 문을 사용해 key값의 데이터가 기존에 입력 되어있는지 확인하고 존재하면 UPDATE, 없으면 INSERT하는 단순 작업입니다.

 

1. DB 접속

먼저 DB 접속을 정의합니다.

 

Connection conn = null;
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mariadb://127.0.0.1:3306", "db_id","db_passwd");
conn.setAutoCommit(false);

 

Driver는 사용하는 DB에 맞게 수정하면 됩니다.

 

2. Select 사용

 

기존에 입력된 데이터가 있는지 확인을 하기위해 함수를 하나 만들어서 결과를 리턴 받습니다.

int iCnt = getInsertCnt(conn, yesterday);

DB 접속 정보와 날짜를 파라미터로 데이터가 있는지 조회하는 쿼리입니다.

 

PreparedStatement pstmt = null;
int nCnt = 0;
ResultSet rs = null;
                    
try {
 
           StringBuilder sql = new StringBuilder();
           sql.append("SELECT count(*) AS CNT FROM test.statistics WHERE INSERT_DT = ?");
          
           pstmt = conn.prepareStatement(sql.toString());
           pstmt.setString(1, yesterDay);
                        
           rs = pstmt.executeQuery();
           while(rs.next()) {
               nCnt =  rs.getInt(1);
               System.out.println("=== CNT : " + rs + "/" + nCnt);
           }
           rs.close();
           pstmt.close();
}

 

PreparedStatement : 쿼리를 높은 효율성으로 반복적으로 사용하기위한 저장 객체.

ResultSet : SQL 쿼리를 실행한 결과를 저장하는 객체.

nCnt : SELECT 결과의 개수를 저장하려고 만든 변수입니다.

 

쿼리 생성시 사용하는 변수를 물음표(?)로 표시하고 값을 대입해서 쿼리를 완성하게 됩니다.

변수가 변경되면 쿼리는 수정하지 않고 변수 값만 수정해주면 반복해서 쿼리를 사용할 수 있게됩니다.

물음표에 해당하는 값을 대입하는데 사용되는 메소드는 아래처럼 정수, 실수, 문자등을 구분해서 대입하게 됩니다.

 

 

public void setInt(int index, int value)
public void setString(int index, String value)
public void setFloat(int index, float value)
public void setDouble(int index, double value)

 

index는 물음표의 순번으로 첫번째 물음표는 1이 됩니다.

 

쿼리를 실행하는 메소드는 여러 종류가 있는데 여기서는 SELECT 결과를 ResultSet에 담아야 하기때문에 리턴 값이 ResultSet인 메소드 executeQuery()를 선택해서 사용했습니다.

 

좀더 자세한 PreparedStatement 관련 메소드는 아래 링크를 참조하면 도움이 됩니다.

https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html

 

JDBC는 업무 로직이 복잡하면 어려워지는거고 실제 사용법은 간단합니다.  SELECT문 하나만으로 필요한 내용 설명은 거의 설명이 되는군요.

 

 

3. Insert / update

 

Insert문도 PreparedStatement 와 변수 대입을 위한 setString()을 사용합니다.

PreparedStatement pstmt = null;
                    
                     try {
                               
                    StringBuilder sql = new StringBuilder();
                    sql.append("INSERT INTO test.statistics (");
                    sql.append("  INSERT_DT");
                    sql.append(", VISIT_CNT");
                    sql.append(", PAGE_VIEW_CNT");
                    sql.append(", INST_DT");
                    sql.append(", INST_ID");
                    sql.append(") VALUES (");
                    sql.append(" ?");
                    sql.append(", (select 1 from dual)");
                    sql.append(", (select 2 from dual)");
                    sql.append(", date_format(now(), '%Y%m%d%H%i%s')");
                    sql.append(", 'tester'");
                    sql.append(")");
                   
                    pstmt = conn.prepareStatement(sql.toString());
                    pstmt.setString(1, yesterDay);
 

 

Select에서는 쿼리 실행을 위해 pstmt.executeQuery()를 사용하고 InsertUpdate에서는 addBatch()executeBatch()을 사용했습니다.

addBatch()는 쿼리를 바로 실행하지 않고 쿼리 구문을 메모리에 올려두었다가, 실행 명령(executeBatch)이 있으면 한번에 DB쪽으로 쿼리를 보내어 처리를 하게 됩니다.  , 한 번의 SQL 수행으로 대량의 로우를 동시에 insert / update / delete를 진행할 수 있어 대용량 처리를 하는데 적합한 방법입니다.

여기서는 달랑 하나 처리했는데 동일한 작업을 진행하려면 loop 문을 이용해서 작업을 하면 됩니다.

 

간단히 설명이 끝났습니다.

 

아래 소스를 보면 좀더 파악이 쉬우리라 생각하며 소스를 첨부합니다.

 

 

package com.example.demo.test;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
 
public class Job {
 
           public static void main(String[] args) {
                     
                     Connection conn = null;
 
               try {
                Class.forName("org.mariadb.jdbc.Driver");
                conn = DriverManager.getConnection("jdbc:mariadb://127.0.0.1:3306", "root","will99");
                conn.setAutoCommit(false);
               
                String yesterday = getYesterday();
               
               
                      int iCnt = getInsertCnt(conn, yesterday);
               
                      if(iCnt < 1) {
                                 System.out.println("======  insert ==================");
                       insertData(conn, yesterday);
                      } else {
                                 System.out.println("======  update ==================");
                         updateData(conn, yesterday);
                      }
                      
                      conn.close();
                 
               } catch (Exception e) {
               
                  e.printStackTrace();
               } finally {
                if(conn != null) {
                 try {
                      conn.close();
                 } catch (Exception e) {}
                }
               }
           }
          
           private static int getInsertCnt(Connection conn, String yesterDay) {
                     PreparedStatement pstmt = null;
                     int nCnt = 0;
                     ResultSet rs = null;
                    
                     try {
                               
                                StringBuilder sql = new StringBuilder();
                         sql.append("SELECT count(*) AS CNT FROM test.statistics WHERE INSERT_DT = ?");
          
                         pstmt = conn.prepareStatement(sql.toString());
                         pstmt.setString(1, yesterDay);
                        
                         rs = pstmt.executeQuery();
                         while(rs.next()) {
                              nCnt =  rs.getInt(1);
                                    System.out.println("=== CNT : " + rs + "/" + nCnt);
                         }
                         rs.close();
                         pstmt.close();
 
              
                     } catch (Exception e) {
                      
                    e.printStackTrace();
                 } finally {
                      if(pstmt != null) {
                                 try {
                                 pstmt.close();
                                 } catch (Exception e) {}
                       }
        }
 
                     return nCnt;
           }
          
           private static void insertData(Connection conn, String yesterDay) {
                     PreparedStatement pstmt = null;
                    
                     try {
                               
                    StringBuilder sql = new StringBuilder();
                    sql.append("INSERT INTO test.statistics (");
                    sql.append("  INSERT_DT");
                    sql.append(", VISIT_CNT");
                    sql.append(", PAGE_VIEW_CNT");
                    sql.append(", INST_DT");
                    sql.append(", INST_ID");
                    sql.append(") VALUES (");
                    sql.append(" ?");
                    sql.append(", (select 1 from dual)");
                    sql.append(", (select 2 from dual)");
                    sql.append(", date_format(now(), '%Y%m%d%H%i%s')");
                    sql.append(", 'tester'");
                    sql.append(")");
                   
                    pstmt = conn.prepareStatement(sql.toString());
                    pstmt.setString(1, yesterDay);
                   
                    pstmt.addBatch();
                   
                    pstmt.clearParameters();
 
                    pstmt.executeBatch();
                   
                    pstmt.clearBatch();
                   
                    conn.commit();
                   
                    pstmt.close();
                  
                 } catch (Exception e) {
                      
                    e.printStackTrace();
                 } finally {
                      if(pstmt != null) {
                                 try {
                                 pstmt.close();
                                 } catch (Exception e) {}
                      }
                 }
           }
          
           private static void updateData(Connection conn, String yesterDay) {
                     PreparedStatement pstmt = null;
                    
                     try {
                               
                    StringBuilder sql = new StringBuilder();
                    sql.append("UPDATE test.statistics SET ");
                    sql.append("VISIT_CNT = (select 1 from dual)");
                    sql.append(", PAGE_VIEW_CNT = (select 1 from dual)");
                    sql.append(", UPDT_DT = date_format(now(), '%Y%m%d%H%i%s')");
                    sql.append(", UPDT_ID = 'tester'");
                    sql.append("where INSERT_DT = ?");
                   
                    pstmt = conn.prepareStatement(sql.toString());
                    pstmt.setString(1, yesterDay);
 
                    pstmt.addBatch();
                   
                    pstmt.clearParameters();
 
                    pstmt.executeBatch();
                   
                    pstmt.clearBatch();
                   
                    conn.commit();
                   
                    pstmt.close();
                  
                 } catch (Exception e) {
                      
                    e.printStackTrace();
                 } finally {
                      if(pstmt != null) {
                                 try {
                                 pstmt.close();
                                 } catch (Exception e) {}
                      }
                 }
           }
          
           private static String getYesterday() {
                     Date today = new Date();
                     SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                     String fmDate = sdf.format(today);
                     System.out.println("=== today : " + fmDate);
                    
                     Calendar cal = Calendar.getInstance();
                     cal.setTime(today);
                    
                     cal.add(Calendar.DATE, -1);
                     String fmDate2 = sdf.format(cal.getTime());
                     System.out.println("=== yesterday : " + fmDate2);
                    
                     return fmDate2;
           }
 
}

 

 - copy coding -

 

OpenCV를 안드로이드에서 사용하려면 SDK를 이용해야 합니다. OpenCVC++로 되어있어서 설치하는 과정이 복잡했는데 요즘에는 쉽게 사용이 가능합니다. SDKOpenCV에서 제공하고 있는데 안드로이드 버전에 따라 맞는 버전을 선택 해야 하고 저는 최신 버전(현재 OpenCV-4.7.0)으로 테스트 해보려고 하였으나 계속되는 에러로 실패를 하고 다른 버전으로 몇 번을 시도한 후에 적합한 버전을 찾게 되었습니다.

 

안드로이드 버전을 많이 타는것 같습니다.  참고로 제 핸드폰의 Android version 9 입니다. 

OpenCV-4.4.0 버전이 제 핸드폰에는 적합하고 gradle 버전도 맞춰야 하고 dependencies 설정도 적절하게 손을 봐야 합니다.

 

 

아래에 설명되는 글들중 이미지에 버전이 4.7.0로 된 부분이 있다면 4.4.0임을 참고하시기 바랍니다.

처음 캡쳐하고 에러나서 여러번 테스트 하면서 다시 캡쳐를 하지 않았네요.

저는 OpenCV 5개의 버전을 테스트 해서 제가 가지고 있는 핸드폰에 적합한 환경을 설정 했습니다.  핸드폰 버전에 따라 조금씩은 환경 설정에 시간을 소비해야 하지 않을까 생각 됩니다.

 

 

1. SDK 다운로드

 

 

OpenCV SDK를 다운로드 받기 위해 홈페이지에 접속합니다.

 

https://opencv.org/

 

 

 

첫화면의 Library에 마우스를 올려 놓으면 서브메뉴가 나타나고 Releases를 선택합니다.

 

Library > Releases

 

최신 버전순으로 SDK 리스트와 지원하는 운영체제를 볼 수 있습니다.

자신의 핸드폰에 적합하다고 생각되는 버전을 선택합니다.

 

 

 

저는 OpenCV-4.4.0 버전에서 운영체제는 Android를 선택했습니다.

 

opencv-4.4.0-android-sdk.zip  211MB

 

다운로드 받은 파일을 적당한 폴더에서 압축을 풀어줍니다.

 

 

압축을 풀어 준 폴더에 들어가 보면 samples sdk 두개의 폴더가 보입니다.

샘플은 말 그대로 예제 이고 SDK 폴더를 사용합니다.

 

 

2. Android Project 생성

 

안드로이드 스튜디오에 SDK를 적용하여 개발 환경을 구축하기 위해 프로젝트를 하나 생성합니다.

 

 

Empty Activity를 선택하고 [Next] 버튼을 클릭 합니다.

 

 

프로젝트 명을 기입하고 기타 다른 선택도 자신의 환경에 맞게 해 줍니다.

저는 java로 개발하는것을 설명 드립니다.

 

 

3. SDK module 추가

 

이제 여기서 부터가 opencv SDK를 적용하는 부분입니다.

OpenCV를 모듈로 추가합니다.

 

 

메뉴에서 모듈을 import 하기위해

File > New > import Module

순서대로 선택을 하면 module 추가 팝업 창이 나타납니다.

 

 

여기에서 폴더모양 아이콘을 이용하여 다운받은 파일의 압축을 풀어 준 OpenCV sdk 폴더를 선택해줍니다.

 

 

[OK] 버튼을 클릭하면 앞으로 사용할 모듈에 대한 엘리어스 명칭을 입력합니다.

처음에는 폴더명대로 sdk로 되어있는데 이런 이름으로는 구분이 안되겠죠.

 

 

뭐라고 하든 상관은 없지만 혼동을 줄 명칭은 피해서 입력합니다. 대부분 OpenCV 또는 OpenCV4로 입력을 하리라 생각됩니다.

저는 OpenCV로 입력을

:OpenCV

이렇게 했습니다.

 

모듈이 추가되면 프로젝트에 OpenCV가 추가됩니다.

 

 

 

4. OpenCV gradle 수정

 

모듈이 추가되면서 OpenCV 설정gradle도 아래 이름으로 생성됩니다.

build.gradle(Module: OpencvTest.OpenCV)

 

 

 

java로 개발하기 때문에 코틀린 플러그인 오류가 발생 합니다.  sdk에 따라 안나오는 경우도 있습니다.

오류가 발생한 apply plugin: ‘kotlin-android’ 라인을 삭제합니다.

 

 

 

targetSdkVersion 26도 오류가 발생 하는데 29이상 지원이 된다고 하니 29로 변경 합니다.

. 저의 경우는 이렇게 해야 하는거고 개발환경이 다르신 분들은 32또는 33으로 하셔도 됩니다.

나중에 build할때 계속 변경하면서 찾으면 됩니다.

 

apply plugin: 'com.android.library'

def
openCVersionName = "4.4.0"
def
openCVersionCode = ((4 * 100 + 4) * 100 + 0) * 10 + 0

println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFile

android {
   
compileSdkVersion
29

   
defaultConfig {
       
minSdkVersion
21
       
targetSdkVersion 29

 

수정이 완료 되었습니다.

이제 app gradle 수정을 합니다.

 

build.gradle (Module: OpencvTest.app)

 

android {
   
compileSdkVersion
29
   
buildToolsVersion "29.0.0"

   
defaultConfig {
       
applicationId
"copycoding.tistory.opencvtest"
       
minSdkVersion 26
       
targetSdkVersion 29
       
versionCode 1
        
versionName "1.0"

 
dependencies {

   
implementation
'androidx.appcompat:appcompat:1.3.0'
   
implementation 'com.google.android.material:material:1.4.0'

 

여기도 버전과 dependencies 를 적당하게 수정해 줍니다.

아니면 나중에 build 할때 오류가 발생하면 수정합니다.

수정을 했으면 우측 상단의 [Try Again] 또는 [Sync Now]를 클릭해줍니다.

 

 

5. OpenCVapp에 적용

 

이제 추가된 OpenCV Module app에 적용하는 방법입니다.

 

 

 

안드로이드 스튜디오 상단메뉴에서

File > Project Structure

를 선택 합니다.

 

 

 

현재 제가 사용하고 있는 Android gradle plugin version  Gradle version입니다.

좌측 메뉴에서 Dependencies를 선택해줍니다.

 

 

좀 설명이 복잡할 수 있는데

Dependencies 다음 단계에 있는 Modules에서 맨 아래의 app을 선택합니다.

그리고 다음 단계 Declared Dependencies에서 + 기호를 선택 하면 나타나는 3번째 Module Dependency를 클릭 합니다.

 

Dependencies > app > [+] > Module Dependency

 

그러면 SDK module을 추가할때 이름지은 항목이 나타나는데 OpenCV 또는 OpenCV4등으로 기입한 이름입니다.

 

 

 

저는 OpenCV.로 설정을 하였는데 선택하고 [OK] 버튼을 클릭 합니다.

선택이 완료되면 다시 이전 화면으로 돌아갑니다.

 

 

여기에서 선택을 적용하기 위해 [Apply] 버튼을 먼저 클릭하고 잠시 반영작업이 완료된 후 [OK] 버튼을 클릭합니다. 적용이 완료되면 Apply 버튼이 비활성화 됩니다.

[Apply] > [OK]

 

이제 모든 설정이 완료 되었고 코딩만 진행하면 됩니다.

 

 

6. OpenCV SDK 적용 확인

 

OpenCV sdk가 추가되었는지 간단하게 테스트 해봅니다.

 

MainActivity에 다음과 같은 코드를 추가 합니다.

 

private static String Tag_Log = "OpenCV Test : ";

@Override
protected void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
    setContentView(R.layout.
activity_main);

   
if(OpenCVLoader.initDebug()) {
        Log.d(
Tag_Log, "OpenCV Initiallize");
    }
else {
        Log.d(
Tag_Log, "OpenCV Not Initiallize");
    }

}

 

OpenCV SDK가 로드 되는지 확인하는 간단한 코드 입니다.

다른 소스는 전혀 손대지 않아서 if 문만 추가하고 테스트 하면 됩니다.

 

 

Logcat에 설정한 문자가 잘 나오면 성공한것 입니다.

이제 지금까지 학습한 OpenCV관련 소스를 가지고 테스트를 진행하면 됩니다.

 

- copy coding -

 

코딩할때 tab을 사용하거나 space를 사용하거나 한가지만 잘 사용하면 되는데 사람에 따라 두가지를 혼용하여 사용하면서 문제가 발생하게 됩니다.

특히 공통을 적용하거나 한번에 모든 소스를 수정할 때에 가끔 어려움을 격어야 하기도 하고 문서 작업할 때 소스를 복사하면 들쑥날쑥해서 한번더 손을 대야하는 경우가 발생 합니다.

이런 상황을 방지하기 위해서는 tab 보다는 space를 사용하는게 좋은데 eclipse는 기본적으로 tab을 적용하게 되어 있어서 space를 사용하려면 한번 설정을 해줘야 합니다.

 

설정 방법은 파일 종류별로 하나씩 설정을 할 수도 있고

한번에 모든 파일에 적용되게 할 수도 있으며

기존에 작업한 파일들도 한방에 space로 전부 변경할 수도 있습니다.

하나씩 알아보도록 하겠습니다.

 

 

 

I. file 종류별 설정

 

 

1. Preferences 설정 창 열기

 

Eclipse 또는 STS(Spring boot)를 열고 메뉴에서

Windows > Preferences를 선택 하면 설정 창이 오픈 됩니다.

 

 

 

 

2. tab 검색

 

Preferences 창의 “type filter text” 부분에 설정을 위헤 tab을 입력해 검색을 진행 합니다.

 

 

좌측에 탭을 설정해야할 파일 종류별 목록들이 다 보이는 군요.  차례대로 하나씩 설정을 진행 합니다.

스페이스로 변경해야 하는 파일 종류만 선택해서 작업을 진행 하면 됩니다.

CSS는 디자이너랑 싸우기 싫은뎅…. 걍 넘어가야지….

 

 

3. java 파일 설정

 

파일 확장자가 java인 파일들의 tab 간격을 space로 변경하도록 합니다.

Java > Code Style > Formatter를 선택 하고

 

 

 

우측에서 [New] 버튼을 선택 하면 새로운 창이 나오는데

 

 

 

Profile name에 구분하기 좋은 임의의 명칭을 입력해 줍니다.   저는 java space로 입력 했습니다.

name 입력을 하였으면 [OK]버튼을 클릭 합니다.

 

 

이제 실제 설정 창이 나타나는데

Indentation > Tab policy에서 Tabs only로 선택되어 있는데 이것을 Spaces only로 변경하고

 

 

 

하단 우측의 [OK] 또는 [Apply] 버튼을 클릭 하여 설정화면을 닫습니다.

 

 

 

다시 Preferences 창으로 돌아와 보면 FormatterActive profilejava space로 변경이 되었습니다.  만약 변경이 안되었다면 클릭해서 방금 수정한 java space를 선택하고 우측 하단 [Apply] 버튼을 클릭해서 설정이 반영되도록 합니다.

java만 설정하려는 거라면 [Apply and Close] 버튼을 클릭하여 Preferences 창을 닫으면 됩니다.

 

 

 

4. JavaScript 파일 설정

 

JavaScript 파일도 java 설정 방법과 동일하게 좌측 메뉴에서 Formatter를 선택하고

 

 

우측에서 [New] 버튼을 클릭해서 이름 설정 창을 오픈 합니다.

 

 

 

Profile name에 기억하기 좋은 이름을 입력하고 [OK] 버튼을 클릭 클릭하여 설정 창을 오픈 합니다.

 

 

 

설정 창 Indentation 탭에서 Spaces only를 선택하고 우측 하단의 [OK] 버튼을 클릭 합니다.

 

 

 

다시 Preference 창으로 돌아와 Active profile에 방금 설정한 이름으로 변경이 되었는지 확인 하고 우측 하단의 [Apply] 버튼을 클릭해서 설정을 반영 합니다.

 

 

 

5. css 파일 설정

 

 

css 파일 설정은 위에서 했던 설정 방법과는 조금 다르게 진행 되는데 좌측에서 Editor 메뉴를 선택합니다.

 

 

 

그리고 우측에서 Indent using spaces를 선택 하고 탭 사이즈도 알맞게 변경한 후에 [Apply] 버튼을 클릭해서 설정을 반영 합니다.

 

 

6. html 파일 설정

 

htmlcss 파일 설정과 동일한 방법으로 좌측에서 Editor 를 선택 하고

 

 

 

우측에서 Indent using spaces를 선택 하고 탭 사이즈도 알맞게 변경한 후에 [Apply] 버튼을 클릭해서 설정을 반영 합니다.

 

 

7. xml 파일 설정

 

xml 파일도 Editor를 선택 하고

 

 

 

우측에서 Indent using spaces를 선택 하고 탭 사이즈도 알맞게 변경한 후에 [Apply] 버튼을 클릭해서 설정을 반영 합니다.

 

 

이렇게 해서 tabspace로 변경이 필요한 파일 종류별로 설정하는 방법을 알아 보았습니다.

 

 

 

II. 모든 파일 설정 변경 방법

 

이번에는 각각의 파일 종류와 관계 없이 프로젝트에 포함된 모든 파일들에 대해 tabspace로 한번에 변경하는 벙법에 대해 알아봅니다.

 

 

1. Preferences 창 열기

 

설정 창을 오픈하는 방법은 위에서 사용한 방법과 동일 합니다.

 

Eclipse 또는 STS를 열고 메뉴에서

Windows > Preferences를 선택 합니다.

 

 

 

2. tab 검색

 

Preferences 창의 “type filter text” 부분에 검색을 위헤 tab을 입력해 줍니다.

그리고 검색 결과에서 General >Editors > Text Editors를 선택 합니다.

 

 

 

우측에서 Insert spaces for tabs를 체크 하고 탭 간격(여기서는 4)을 입력해 줍니다.

설정이 완료되면 [Apply and Close] 버튼을 클릭 해서 설정을 반영 합니다.

모든 파일의 tab 간격을 space로 변경해야 한다면 정말 간단한 방법입니다.

 

 

 

III. space 설정 작업 반영하기

 

 

위에서 파일 종류별 설정 방법과 모든 파일에 대한 설정 방법에 대한 두가지 방법으로 tabspace로 설정하는 것을 알아보았습니다.

그런데 설정을 했다고 기존에 tab으로 된 부분이 space로 자동으로 변경되는 것이 아니고 tab으로 작업된 부분은 그냥 원래대로 tab으로 남아있고 새로 작업하는 부분부터 space가 적용됩니다.

그래서 기존에 작업해 놓은 파일들에 대한 수정을 해야 하는데 이걸 한번에 수정하는 방법입니다.

 

I번 방법대로 하나의 파일 종류만 선택한 경우는 해당 종류만 변경되고

II번 방법대로 전체 파일에 대해 선택한 경우에는 모든 파일이 변경 됩니다.

 

프로젝트에 마우스를 놓고 우측 버튼을 클릭 합니다.

 

 

 

Source > Format을 클릭해 줍니다.

 

끝입니다.

모두 수정 되었습니다.

 

 

 

IV. 수정사항 확인

 

지금까지 여러 방법으로 설정을 해 보았는데 실제로 tabspace로 변경이 되는지 확인해 보도록 하겠습니다.

설정을 통해 space tab이 기호로 표기되어 잘 보이도록 합니다.

 

상단메뉴에서

Window > Preference를 선택 하여 Preferences 팝업 창을 오픈하고

 

 

 

General > Editors > Text Editors를 선택 합니다.

 

우측에서 Show whitespace characters를 체크하고 하단에 있는 [Apply and Close] 버튼을 클릭 합니다

 

 

파일 하나를 열어보면 tabspace()가 특수 기호로 보입니다.

1011번 라인은 java 파일에 대해 space를 적용하고 탭을 사용한 경우 getId()에 탭 대신 공백이 반영된 모습입니다.

보다시피 기존의 tab은 변함이 없고 신규로 작업하는 경우에만 tabspace로 나타납니다.

 

이런경우 프로젝트 전체에 대해 설정을 반영하여 한번에 변경하는 방법을 사용해 보겠습니다.

 

위에서 III번에 해당하는 작업을 실행 합니다.(Project에 우측 마우스 클릭 > Source > Format 선택)

 

 

탭이 모두 스페이스로 수정 된것을 확인할 수 있습니다.

 

수정된 space를 다시 tab으로 되돌리고 싶으면 Ctrl + Z를 클릭하면 됩니다.

 

 

여기서 [OK] 버튼을 클릭하면 전체 수정 반영 이전으로 돌아갑니다.

 

필요한 부분만 잘 적용해서 사용하세요.

 

- copy coding -


1234

+ Recent posts