[Java] 특정 폴더에서 원하는 확장자를 가지는 파일 목록 구하기

원하는 폴더 안에.. 특정한 확장자를 가지는 파일 목록을 얻어야 할때가 있습니다. 예를 들어서 D:/TEMP라는 폴더안에 확장자가 SHP인 파일의 목록을 배열 형태로 반환하도록 하는 경우이지요. 이때 사용할만한 함수입니다.

private Vector getFileNames(String targetDirName, String fileExt) {
    Vector fileNames = new Vector();
    File dir = new File(targetDirName);
    fileExt = fileExt.toLowerCase();
  
    if(dir.isDirectory()) {
        String dirName = dir.getPath();
        String[] filenames = dir.list(null);
        int cntFiles = filenames.length;
       
        for(int iFile=0; iFile            String filename = filenames[iFile];
            String fullFileName = dirName + "/" + filename;
            File file = new File(fullFileName);
 
            boolean isDirectory = file.isDirectory();
            if(!isDirectory && filename.toLowerCase().endsWith(fileExt)) {
                fileNames.add(fullFileName);
            }
        }
    }

    return fileNames;
 }

제가 이 함수가 필요했던 이유는.. 특정 폴더에 존재하는 수백개의 항공영상이나 수백개의 SHP 파일을 한꺼번에 레이어로 추가하고자 하는 필요 때문이였습니다.

아래의 코드는 안드로이드 기반의 GIS 엔진인 블랙포인트에서 위의 함수를 사용해 25cm 해상도의 192개의 항공영상(GEOTIFF 기준으로 40GB 이상)과 일정한 격자로 나눈  SHP 파일 185개(전체 용량 85MB)를 올리는 코드예입니다.

LayerManager layerMan = map.getLayerManager();
  
String ess = Environment.getExternalStorageState();   
String sdCardPath = null;   
if(ess.equals(Environment.MEDIA_MOUNTED)) {   
    sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
    String rootDir = sdCardPath + "/mapdata/yp";
    
    // 항공사진 레이어 추가  
    Vector xrrFiles = getFileNames(rootDir +"/XrR", "xrr");
    for(int i=0; i        ILayer layer = new TileImageLayer("xrr_" + i, xrrFiles.get(i), false);
        layerMan.addLayer(layer);
    }

    // 수치지도 레이어 추가
    Vector cassFiles = getFileNames(rootDir + "/CBND", "shp");
    int cntCbndLyr = cassFiles.size();
    for(int i=0; i        ILayer layer = new ShapeLayer("cbnd_" + i, cassFiles.get(i));
        layerMan.addLayer(layer);
       
        ShapeLayerLabel roadLbl = (ShapeLayerLabel)shpLyr.getLabel();
        roadLbl.setFieldName("JIBUN");
        roadLbl.setEnable(true);
        roadLbl.getFontSymbol().setTextSize(11);
        SimpleDrawShapeTheme roadTheme = (SimpleDrawShapeTheme)shpLyr.getTheme();
        roadTheme.getFillSymbol().setHollow(true);
        roadLbl.getFontSymbol().setTextColor(Color.GREEN);
        roadTheme.getStrokeSymbol().setColor(Color.YELLOW);
}

아래는 위의 코드에 반영된 시스템에 대한 실행 화면입니다. 클릭하면 원본 크기로 볼 수 있습니다.

SQL문 기록

업무중에 필요해서 작성한 쿼리문을 기록해 둡니다.

사용자 삽입 이미지
2~7번은 조회하고자 하는 필드와 알리아스(Alias)입니다. 알리아스는 단순히 이름이므로 중복이 가능합니다. 9~10번은 조회 대상이 되는 테이블과 그에 대한 알리아스입니다. 12~21번은 검색 조건입니다. 결과는 아래와 같습니다.

사용자 삽입 이미지
혹시.. 퍼포먼스를 향상시킬 수 있는 개선할 점이나.. 문제가 되는 부분이 있으면 피드백 부탁드립니다.

[Java] URL을 통한 Binary 데이터 받기

자바에서 서버가 제공하는 바이너리 데이터를 받아 저장해 주는 코드입니다. 필요할 때 찾아 보기 쉽도록 정리해 봅니다.

URL url;
try {
    url = new URL("http://somewhere/binary.zip");
  
    URLConnection connection = url.openConnection();
    int contentLength = connection.getContentLength();
    if (contentLength > 0) {
        InputStream raw = connection.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int bytesRead = 0;
        int offset = 0;
        while (offset < contentLength) {
            bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        in.close();
  
        if (offset == contentLength) {
            // 바이너리 데이터 준비 완료 !
            return true;
        }
    }
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

위의 코드는 사용해 보니 문제가 있습니다. 이유는 6번 코드를 통해 서버로부터 받은 데이터의 크기가 항상 옳바르지 않다는 것입니다. 예를 들어 데이터가 클 경우.. -1이 반환되기도 합니다. 이러한 이유로 위의 코드는 사용하면 않되고.. 아래의 코드를 사용하시기 바랍니다.

private boolean requestUrl(String urlString, ByteBuffer out) {
    URL url;
  
    try {
        url = new URL(urlString);
        URLConnection connection = url.openConnection();
        InputStream raw = connection.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] chunk = new byte[1024];
        int bytesRead = 0;

        while((bytesRead = in.read(chunk)) != -1) {
            out.put (chunk, 0, bytesRead);
        }
   
        out.flip();
        in.close();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }  
    
    return true;
}

크롬(Chrome)에서 플래시 디버거 기능 않될때 조치

크롬에서 플래시 빌더를 통해 개발을 할때 디버깅이 않되는 문제가 있습니다. 이에 대한 해결책입니다. 먼저 크롬을 실행하고 주소창에 about:plugins 을 입력하여 아래 창을 표시합니다.

사용자 삽입 이미지
Flash라고 되어 있는 부분에서 사용 중지를 클릭하여 해당 플러그인의 사용을 비활성화 시킨 후.. 다시 Flash PlugIn Debug를 다운받아 설치합니다. 요지는.. 개발자에게 잇어서 Flash는 2가지 버전이 있는데 하나는 Release용이고 하나는 Debug용입니다. 이중 Release는 사용하지 않고 오직 Debug용만 사용한다는 것입니다. 이렇게 하면 Flash Builder에서도 Chrome을 통해 디버깅이 가능해 집니다.

모바일 플래시 업데이트

모바일 웹에서 플래시를 더 이상 지원하지 않겠다고 했던 어도비가 안드로이드 디바이스에서는 아직도 여전히 웹 기반 플래시를 지원하고 있습니다. 어제 새롭게 릴리즈된 플래시 버전 11.1.111.5입니다.

사용자 삽입 이미지
또한 안드로이드나 iOS에서는 플래시를 이용해 앱으로 개발할 수 있는 AIR는 3.1로 버전업되었습니다. 버전업으로 향상된 기능을 살펴보면.. 속도 향상과 보안 및 안정성에 대한 버그 수정이 이뤄졌다고 하니… 한번 테스트 해봐야겠습니다.

단 한번의 개발로 PC에서.. 그리고 Android, iOS 그리고 BlackBerry에서 모두 구동 가능한 앱 개발이 가능한 어도비의 플래시입니다.