2011년 8월 8일 월요일

List 일부분만 정렬 하기

참고: http://stackoverflow.com/questions/5164902/sorting-a-part-of-java-arraylist
List.subList(int fromIndex, int toIndex) 함수를 사용한다.

예)
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collections;

public class Main {
 public static void main(String[] args) throws Exception {
  ArrayList<String> list = new ArrayList<String>();
  
  list.add("i");
  list.add("e");
  list.add("a");
  list.add("b");
  list.add("g");
  list.add("c");
  list.add("d");
  list.add("f");
  list.add("h");
  
  Collections.sort(list.subList(1, list.size()-1));
  
  System.out.println(list.toString());
  
 }
}
결과:
[i, a, b, c, d, e, f, g, h]

2011년 8월 3일 수요일

file lastModifed 값을 Date 로 변경

File file = new File("myfile"); 
 
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date(file.lastModified()));
cal.getTime(); // Date 값을 return 한다.

2011년 7월 25일 월요일

InvalidKeyException: Illegal key size 문제

JKS 에서 BKS 로 변형하는데 InvalidKeyException: Illegal key size 에러가 발생했다.

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy 파일을 설치하여 해결하였다.

위 링크로 들어가 맨 아래 보면 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6 를 다운로드 받을 수 있다.

설치:
압축을 풀고
/lib/security 에 파일을 복사한다.
기존에 같은 이름의 파일들을 덮어쓴다.

2011년 6월 25일 토요일

폴더 내 모든 java 파일 컴파일



폴더 구성
소스 폴더 : src
클래스 폴더 : class

컴파일 방법1:
1) find 명령을 이용해 src 폴더 내 모든 .java 파일 목록을 sources_list.txt 라는 파일명으로 저장한다.
$ find ./src -name *.java > sources_list.txt
2) sources_list.txt 파일에 저장된 .java 파일 목록들을 class 폴더에 컴파일한다.
 !) -d 옵션을 주면 해당 폴더에 .class 파일들이 저장된다.
$ javac -cp . -d class @sources_list.txt

참고: http://stas-blogspot.blogspot.com/2010/01/compile-recursively-with-javac.html

컴파일 방법2:
$ javac -cp . -d class $(find ./src -name *.java)


실행하기:
$ java -cp ./class [패키지명].[class명]
예)
$ java -cp ./class com.test.Main

팁) 윈도에서 .java 파일 목록을 파일로 만들기
> dir .\src\*.java /a:-d /b /s > sources_list.txt
 참고: http://www.unix.com/windows-dos-issues-discussions/126864-find-command-windows.html

2011년 6월 13일 월요일

html 내용 출력

BufferedReader 를 이용하여 html 내용 출력

package http.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

public class Reader {
 public static void main(String[] args) throws Exception {
  URL url = new URL("http://www.w3.org/");
  InputStream is = url.openStream();
  BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
  String line = null;
  while ((line = reader.readLine()) != null) {
   System.out.println(line);
  }
  is.close();
 }
}

2011년 6월 10일 금요일

ByteBuffer 사용

참고: http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html

네트워크 통신 등의 버퍼를 사용하는 작업에는 ByteBuffer 클래스를 많이 사용한다.
byte 배열을 사용하는 경우 잦은 GC(garbage collection) 가 성능에 영향을 줄 수 있다.

목차
1)ByteBuffer instance 생성: allocate, allocateDirect
2)ByteBuffer 초기화: clear
3)ByteBuffer 사용 가능 크기 변경: limit
4)ByteBuffer 쓰기: put*
5)ByteBuffer 읽기: get*
6)ByteBuffer 읽기/쓰기 작업 병행시: flip
7)ByteBuffer 에 남은 데이터 처리: compact


1)ByteBuffer instance 생성: allocate, allocateDirect
ByteBuffer 클래스에는 allocate 함수와 allocateDirect 함수가 있다.
두 함수 모두 static 이고 int 값을 파라미터로 전달받으며 버퍼의 크기를 지정한다.

예)
ByteBuffer buffer = ByteBuffer.allocate(1024);
allocateDirect 함수의 경우 사용하는 플랫폼(안드로이드 등의 모바일 플랫폼) 에 따라 정상적으로 동작하지 않는 경우도 있으므로 반드시 플랫폼이 지원을 하는지 테스트해 보고 사용하길 권한다.

2)ByteBuffer 초기화: clear
clear 함수는 해당 ByteBuffer instance 가 생성되었을 때 상태로 만들어 준다.

3)ByteBuffer 사용 가능 크기 변경: limit
limit(int newLimit) 함수를 사용하여 쓰기 가능 영역 크기를 조정할 수 있다.
파라미터로 넘기는 값이 allocate 로 지정한 capacity 를 초과할 수 없다.

예)
ByteBuffer buffer = ByteBuffer.allocate(1024);

buffer.limit(); // 1024 를 리턴

buffer.limit(50);

//buffer.limit(2048); // 허용되지 않음

buffer.limit(); // 50 를 리턴

4)ByteBuffer 쓰기: put*
put* 함수들을 이용해서 데이터를 ByteBuffer 에 넣어준다.

예)
ByteBuffer buffer = ByteBuffer.allocate(1024);

buffer.put((byte)0x01);

buffer.put(new byte[] {0x02, 0x03});

buffer.put((byte)0x04);
결과:
buffer.array() => [0x01, 0x02, 0x03, 0x0x04, ...]

5)ByteBuffer 읽기: get*
get* 함수들을 이용해서 원하는 데이터 크기만큼 데이터를 읽을 수 있다.
get* 함수를 이용해서 데이터를 읽으면 다음 get* 함수 이용시 이전 get* 함수를 이용해 읽은 다음 부분부터 값을 읽는다.

예)
ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06});

byte a = buffer.get();

byte b = buffer.get();

byte[] c = new byte[2];

buffer.get(c);

byte d = buffer.get();

결과:
a => 0x01
b => 0x02
c => [0x03, 0x04]
d => 0x05

6)ByteBuffer 읽기/쓰기 작업 병행시: flip
put* 함수를 이용해서 값을 쓰거나 SocketChannel 의 read 함수로 ByteBuffer instance 에 값을 쓰고 나서 데이터를 읽기 전에 ByteBuffer 클래스의 flip 함수를 한번 호출해야 한다.

예) http://download.oracle.com/javase/6/docs/api/java/nio/Buffer.html#flip()
buf.put(magic); // Prepend header

in.read(buf); // Read data into rest of buffer

buf.flip(); // Flip buffer

out.write(buf); // Write header + data to channel
buf.put(magic) 과 in.read(buf) 모두 buf 에 데이터를 쓴다.
데이터를 쓰고 나서 buf.flip() 으로 모드 변환을 해주고
out.write(buf) 로 buf 의 내용을 읽는다.

7)ByteBuffer 에 남은 데이터 처리: compact
socket 통신의 경우 buffer 에 읽을 수 있는 양이 찰 때까지 read 함수로 buffer 를 채우고 buffer 가 충분히 차면 의미있는 범위까지 데이터를 읽고 buffer 의 남은 부분을 유지하고 남은 부분 다음부터 데이터를 채우는 작업을 반복하는 경우가 있다.

이때 데이터의 남은 부분을 buffer 의 앞으로 이동시키고 남은 부분 다음부터 쓸 수 있게 하는 함수가 compact 함수이다.

예)
ByteBuffer buffer = ByteBuffer.allocate(1024);

byte[] data = new byte[16];

buffer.clear(); // ByteBuffer 초기화

int len = 0;

while ((len = in.read(buffer)) > 0) { // ByteBuffer 쓰기

 buffer.flip(); // 쓰기 작업이 끝나고 읽기 작업을 위해 flip

 while (buffer.remaining() > 16) { // remaining 함수는 읽을 수 있는 크기를 리턴

  buffer.get(data); // 16 바이트만큼 데이터를 읽음
  
  // data 처리

 }

 buffer.compact(); // 남은 부분을 ByteBuffer 맨 앞으로 이동 

 // 다음 read 작업에서 남은 부분 다음부터 채움
}