달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
.. .. ..

Thread 를 테스트 해보았다.

 

1.

 

Thread serverThread = Thread.currentThread();

 

System.out.println("Name : " + serverThread.getName());

 

결과값은 Main 이 나온다. 기본적으로 Java 의 Main 을 실행시키면 Main 은 Thread로 실행되기 때문이다.

 

2.    

 

this.serverThread.interrupt();

Thread.sleep(2000);

 

결과는 sleep interrupt 라는 Exception 이 나온다. 아마도 interrupt 라는 명령은 더이상 main Thread(메서드)

 

가 추가 Thread(sleep 스레드 건 부분) 를 생성할수 없게 한듯 하다.

 

3.

this.serverThread.join();

System.out.println("Hello");

 

결과는 무한 대기를 탄다. 이유는 join() 을 실행하면 main 메서드가 끝나기를 기다렸다가(락) 지정 스레드(main)가

 

끝이 나아 다음으로 진행하기 때문이다. (이부분은 테스트로 확인됨.)

'I.lib() > I.lib(Java)' 카테고리의 다른 글

[펌] Java File Writing 성능 비교  (0) 2013.01.21
BlockingQueue  (0) 2013.01.15
[암호화] 메시지 다이제스트(Message Digest)  (0) 2012.07.06
base64 인코딩 & 디코딩 원리  (0) 2012.07.02
dwr 사용방법  (0) 2012.03.22
.
:
Posted by .07274.
.. .. ..

[펌] http://blog.naver.com/xxrcn11?Redirect=Log&logNo=20135507694

 

자세한 내용을 알고 싶은 분은 다음의 블로그를 참조하세요

http://blog.naver.com/dury00?Redirect=Log&logNo=130044978311

내용

가) 일종의 데이터 지문

나) 데이터가 바뀌지 않았다는 것을 증명

다) 데이터의 길이에 상관없이 보통 16 또는 20byte

라) FTP파일 검증에 많이 사용

마) 해쉬를 이용

바) 한 방향 변환이고 역으로는 불가능

자바에서의 메시지 다이제스트 사용

가) java.security.MessageDigest

getInstance()로 인자 생성

MD5, SHA-1이 주로 사용됨

나) update()

데이터를 해쉬 함

다) digest()

바이트 배열로 해쉬를 반환

적은 데이터일 경우 digest에 직접 입력 가능

라) 파일의 메시지 다이제스트 계산

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import com.Ostermiller.util.Base64;

public class DigestFile {

public static void main(String[] args) throws NoSuchAlgorithmException, IOException {

MessageDigest md = MessageDigest.getInstance("MD5");

BufferedInputStream in = new BufferedInputStream(new FileInputStream("c:\\test.txt"));

int theByte = 0;

while((theByte = in.read()) != -1)

md.update((byte)theByte);

in.close();

byte[] theDigest = md.digest();

System.out.println(Base64.encode(theDigest));

}

}

마) 실행결과

test.txt 파일에는 ‘this is a test file’이 들어 있음 : [B@1a758

‘this is a test file.’로 수정한 결과 : [B@1b67f74

바) 스트림에서의 메시지 다이제스트

DigestInputStream & DigestOutputStream

MessageDigest messageDigest = MessageDigest.getInstance(“MD5”);

DigestOutputStream output = new

DigestOutputStream(existingOutputStream, messageDigest);

출력에 쓰는 모든 바이트가 자동으로 메시지 다이제스트를 계산할 때 사용됨

예제

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.security.DigestInputStream;

import java.security.MessageDigest;

import com.Ostermiller.util.Base64;

public class DigestStreamExample {

public static void main(String[] args) throws Exception{

MessageDigest md = MessageDigest.getInstance("MD5");

BufferedInputStream in = new BufferedInputStream(new FileInputStream("c:\\test.txt"));

//DigestInputStream 생성한다.

DigestInputStream digestIn = new DigestInputStream(in, md);

// 모든 데이터를 읽어들인다.

while(digestIn.read() != -1);

byte[] theDigest = md.digest();

System.out.println(Base64.encode(theDigest));

}

}

패스워드 인증

가) 의미

패스워드를 해쉬하여 저장할 경우 복호화는 불가능하지만 모든 가능한 패스워드를 해쉬한 다음 비교해서 추즉하는게 가능함

이런 공격을 막기 위해 salt와 패스워드를 같이 저장해야 함

서버가 실제 패스워드를 알 필요 없이 사용자가 정한 패스워드를 검증하는게 목적

나) 패스워드 저장

랜덤 salt 생성하여 패스워드 앞에 붙임

이것을 해쉬함

패스워드 입력될 때마다 비교를 위해 salt와 해쉬 결과를 붙여서 저장



다) 패스워드 인증

저장된 패스워드의 salt와 사용자가 입력한 패스워드를 합친다.

salt와 패스워드를 해쉬한다.

결과 해쉬값을 파일에 저장된 것을 비교한다. 같다면 패스워드가 같은 것이다.

라) 예제

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.security.MessageDigest;

import java.security.SecureRandom;

import java.util.Arrays;

public class Passwordauthenticator {

public static void main(String[] args) throws Exception{

createPassword("iloveyou");

authenticatePassword("iloveyou");

}

private static void createPassword(String password) throws Exception {

// salt 생성

SecureRandom random = new SecureRandom();

byte[] salt = new byte[12];

random.nextBytes(salt);

// salt 패스워드를 붙여서 해쉬한다.

MessageDigest md = MessageDigest.getInstance("MD5");

md.update(salt);

md.update(password.getBytes("UTF-8"));

byte[] digest = md.digest();

// salt 해쉬 결과를 파일에 저장한다.

FileOutputStream fos = new FileOutputStream("c:\\password.txt");

fos.write(salt);

fos.write(digest);

fos.close();

}

private static void authenticatePassword(String password) throws Exception {

// 파일을 읽어들인다.

ByteArrayOutputStream baos = new ByteArrayOutputStream();

FileInputStream fis = new FileInputStream("c:\\password.txt");

int theByte = 0;

while((theByte = fis.read()) != -1)

baos.write(theByte);

fis.close();

byte[] hashedPasswordWithSalt = baos.toByteArray();

baos.reset();

//salt 얻는다.

byte[] salt = new byte[12];

System.arraycopy(hashedPasswordWithSalt, 0, salt, 0, 12);

// salt 입력한 패스워드를 붙여서 해쉬한다.

MessageDigest md = MessageDigest.getInstance("MD5");

md.update(salt);

md.update(password.getBytes("UTF-8"));

byte[] digest = md.digest();

// 파일에 있는 내용과 비교한다.

byte[] digestInFile = new byte[hashedPasswordWithSalt.length-12];

System.arraycopy(hashedPasswordWithSalt, 12, digestInFile, 0, hashedPasswordWithSalt.length-12);

if(Arrays.equals(digest, digestInFile))

System.out.println("Password matches.");

else

System.out.println("Password does not matches.");

}

}

'I.lib() > I.lib(Java)' 카테고리의 다른 글

BlockingQueue  (0) 2013.01.15
Thread 의 currentThread() , interrupt() , join() 테스트 결과  (0) 2013.01.15
base64 인코딩 & 디코딩 원리  (0) 2012.07.02
dwr 사용방법  (0) 2012.03.22
JAVA 로 MAIL 보내기.(SMTP 방식?! )  (2) 2011.09.26
.
:
Posted by .07274.
2012. 7. 2. 15:46

base64 인코딩 & 디코딩 원리 I.lib()/I.lib(Java)2012. 7. 2. 15:46

.. .. ..

바이너리 데이터를 텍스트 데이터로 변환할 때 쓰는 Base64인코딩에 대한 구현이 자바의 sun 패키지에 포함되어 있지만, sun.misc.BASE64Encoder와 sun.misc.BASE64Decoder는 사용해서 안되는 클래스라고 합니다. 예전에 어떤 SDK 샘플에 있어 그대로 사용한 적이 있었는데, 기본적으로 sun 패키지에 포함된 클래스는 직접적으로 써서는 안된다고 합니다 (Why Developers Should Not Write Programs That Call 'sun' Packages).

 

 

 

 

[펌] : http://bbolmin.tistory.com/46

 

Base64 인코딩은 64개의 문자를 이용하여 바이너리 데이터를 아스키 텍스트 데이터로 표현하기 위해 사용됩니다.

base64는 8bit의 데이터(바이너리)를 6bit의 크기로 표현합니다. 따라서 24bit를 단위로 하여 3개의 문자에서 4개의 문자를 얻게 되는 것입니다.

위와 같이 abc를 base64 인코딩 하여 YWJj를 얻을 수 있게 됩니다.

여기서 6bit의 이진수는 아래의 base64 table을 이용하여 문자로 바꿔줍니다.

그리고 base64 인코딩 24bit 단위인데 인코딩할 문자가 3개(24bit) 단위가 아닐 때는 어떻게 되는지 알아보겠습니다.

위의 결과를 보면 a라는 문자 하나를 넣었을 때는 YQ==으로 base64 table에 없는 '=' 문자가 추가된 것을 알 수 있습니다. '='은 bit수를 맞춰주기 위해 0으로 채워주는 패딩이라는 것 입니다.

그럼 문자의 개수가 3n+1개 일 때는 '='이 2개가 될 것이고, 3n+2개 일 때는 '='이 1개가 되는 것을 생각해 볼 수 있습니다.


Tip. secuinside2012 IU 문제를 보고 base64의 decoding시 충돌이 있는 것을 알게 되었는데요 -

예를 들어 위에서 'a'를 base64인코딩 하여 YQ==를 얻었습니다. 따라서 YQ==를 디코딩하면 'a'를 얻게 됩니다.

그런데 YR==, YS==, YT== 등 을 디코딩 해보면 모두 'a'가 나오는 것을 볼 수 있습니다.

아래 그림을 보면서 생각해보면 왜 그런지 알수 있습니다.

여기서 '='이 2개 이므로 디코딩시 문자가 3n+1개 라는 것을 알 수 있습니다. 그러면 Q(16)을 디코딩시 010000에서 패딩으로 채워진 0000의 4bit는 0이든 1이든 관계가 없다는 것 입니다.

따라서 3n+1개의 문자일 때는 충돌 가지수가 2의 4승인 16개가 생길 것이고, 3n+2개의 문자일 때는 2의 2승인 4개가 생기고, 3n개의 문자일 때는 충돌이 생기지 않게 됩니다.

▶ base64 인코딩, 디코딩 사이트 : http://ostermiller.org/calc/encode.html

.
:
Posted by .07274.
2012. 3. 22. 16:25

dwr 사용방법 I.lib()/I.lib(Java)2012. 3. 22. 16:25

.. .. ..

[펌] : http://innoc99.blog.me/140046778698

Eclipse에서 Web Project 생성.

Project Name : DWR-Test

dwr.jar 파일을 Project내의 WEB-INF/lib에 넣어준다.

(첨부파일에서는 -leepcs 부분을 지운후에..)

web.xml에 아래 내용 추가.

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<!-- If you are using DWR 1.x then servlet-class line shoud contain the following -->
<!-- uk.ltd.getahead.dwr.DWRServlet -->

<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

중간 파란색 부분은 dwr 버전이 1.x라면 uk.ltd로 시작하는것을 servlet-class로 적어주어야만 한다. 무조건.

dwr.xml 만들기.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="HelloTest" >
<param name="class" value="dwr.test.SimpleText"/>
<include method="hello"/>
</create>
</allow>
</dwr>

creator에 new라는 것은 객체를 만들어서 사용한다는 것이고.. HelloTest는 jsp나 html에서 객체의 이름으로 사용할 것을 적는당.

param의 class란 java파일이므로 class라 한 것이고... value의 dwr.test.SimpleText는 java파일의 경로를 적은 것.

hello란 것은 SimpleText Class의 메소드로 hello가 있다는 것을 정의해준 것.(그냥 쓸거 정의하면 됨..)

SimpleText.java 만들기

src 아래에 패키지 만들기를 통해 dwr.test를 만든 후 test 아래에 SimpleText class를 만든다.

package dwr.test;

public class SimpleText {

public String hello(String value){
return "Hello ~ "+value;
}

}

hello는 dwr.xml에서 정의한 것(자신이 쓸 메소드)과 일치시켜주면 된다.

이제 톰캣에 Project를 올리고 서버를 실행시킨후에

http://localhost:{your_port}/{your_app}/dwr/

위 주소로 들어가게 되면 dwr.xml에 정의했던 Class 목록이 나오게 된다.

위와 똑같이 했다면 이런 화면....

그리고 HelloTest를 눌러보면은.. 아래와 같이 나오게 된다..

위 그림에서 보면 script 구문이 3줄이 있다.

DWR이 알아서 저걸 만들어 준다는 것이다.

그리고 그 아래에는 Test를 할 수 있는 부분이 있다.

WebContent/index.jsp 만들기.

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
<script type='text/javascript' src='/DWR-Test/dwr/interface/HelloTest.js'></script>
<script type='text/javascript' src='/DWR-Test/dwr/engine.js'></script>
<script type='text/javascript' src='/DWR-Test/dwr/util.js'></script>
<script type="text/javascript">
function test(){
var value = dwr.util.getValue('demo');
//var value = document.getElementById('demo').value;
HelloTest.hello(value,

function(data) { dwr.util.setValue("here", data); }

);

}
</script>
</head>
<body>
<input type="text" value="" size="20" id='demo'>
<input type="button" value="send" onclick="test()"/>
<br>
<input type="text" id="here" value=""/>
</body>
</html>

send를 클릭하게 되면 JavaScript의 test() function이 호출이 된다.

test에서는 demo에 적혀진 text를 value로 저장해 DWR에서 정의한 객체(HelloTest)의 메소드(hello)를 호출한다.

그런데 hello 메서드를 보게 되면 매개변수가 하나 였는데 script내에서는 2개이다..

why?

이를 callback function이라 하는데, return값이 있다면 return 값을 처리하는 함수이다.

왜 저렇게 쓰냐고 하면... 그냥 간단히 하기 위해서??

왜 복잡한지 궁금하다면..

function test(){

var value = dwr.util.getValue("demo");

HelloTest.hello(value, cb_function);

}

function cb_function(data){

dwr.util.setValue("here", data);

}

이렇게 사용하느니 그냥 줄여서 사용한다 이거다.

위 예제는 정말 간단하게 DWR 설명이 가능한 예제이다..

jsp -> Java로 가는 대부분의 과정을 DWR이 처리해주고 있다..

무분별한 사용은 금지..

데이터가 많을 경우 메모리 급상승 최악에는 서버가 죽어버린다..

아래 링크에서 확인할 수 있다.

http://javaora.tistory.com/109

.
:
Posted by .07274.
2011. 9. 26. 18:18

JAVA 로 MAIL 보내기.(SMTP 방식?! ) I.lib()/I.lib(Java)2011. 9. 26. 18:18

.. .. ..
종일 삽질...
이건 뭐 아무것도 모르고 시작하려니 머리 뽀개진다.

JAVA로 MAIL 을 쓰고싶다고 구글링과 네이년에게 물어서 이리저리 찾아보면

요즘 대세는

http://blog.naver.com/5boon?Redirect=Log&logNo=101676325

이 방법이라고 앵간한 곳에서 찾으면 다 나온다. 그중 삽질했던 부분만 집중~!

우선 SMTP를 사용시.. PORT를 확인해본다. 사이트(Daum , Google)가서 확인해보니

iMAP 은 400번대 port를 사용하고 POP3 는 900번대 port를 사용하더라. 근데
이걸 사용한다고 설정을 안하면 절대 사용 못한다. 사용합니다에 체크하고 저장해야
smtp로 메일 수신과 발신이 모두 가능....(이정도는 알아서.. )

다음 삽질했던 부분은 설정 부분이다.

SimpleEmail email = new SimpleEmail(); // 선언을 한다
  
  email.setCharset("UTF-8");     // 인코딩을 설정한다.
  //email.setHostName("smtp.daum.net");     //요놈은 다음
  email.setHostName("smtp.gmail.com");      //요놈은 구글지메일
  email.setSmtpPort(465);                             //이건 서버마다 포트가 다르니 찾아서 얌전히 물어보기~!
   email.setFrom("메일주소", "이름"); //보내는 사람
   email.setSSL(true);    // 안써도 잘된다 하는데 혹시 안되면 설정~!
   email.setAuthentication("아이디", "패스워드"); //SMTP 인증이 필요할 경우(없으면 지워버린다.)
   email.addTo("이메일주소", "손님"); //받는사람
   email.setSubject("메일의 제목입니다."); //메일 제목
   email.setMsg("메일의 내용입니다."); //메일 내용
   email.send(); //메일 발송

기존에 올라왔던 글들에 몇개 더 추가~!
저렇게 하고 돌리니 자꾸 멍청한 에러가 나온다.
저 위에대로 다 했는데 에러가 나면 분명... 라이브러리 3개를 클레스 패스로 지정 안해서 이다.
위의 링크 따라가서 꼭 3개의 라이브러리를 클레스 패스로 지정한다. 라고 다른 글들은 써있다.
activation.jar , commons-email-1.1.jar , mailapi.jar
위 세개를 해서 돌렸더니 안된다!!!!! 아어!!!!!!!!!!!!!!!!!!!!!!
알고 봤더니 smtp.jar 라이브러리도 추가해 줘야 한다......
글을 쓰려면 잘쓰던가!!

이렇게 했는데도 안되면?
머리를 탓하라.. 이렇게 정성스레 글써서 알려줬는데 안되면...
댓글을 남기면 알려주리라...... 모두 선방하길....

.....
댓글은 안남기게?
이렇게 읽고 안남기게??

'I.lib() > I.lib(Java)' 카테고리의 다른 글

base64 인코딩 & 디코딩 원리  (0) 2012.07.02
dwr 사용방법  (0) 2012.03.22
필터 스트림  (1) 2011.08.02
JAVA에서 엑셀 파일 읽고 쓰기  (0) 2011.07.04
Spy 설정 방법.  (1) 2011.03.31
.
:
Posted by .07274.
2011. 8. 2. 18:16

필터 스트림 I.lib()/I.lib(Java)2011. 8. 2. 18:16

.. .. ..
[펌] : http://force44.blog.me/130096406237

5. 필터 스트림

앞에서 본 입출력 스트림들만으로는 기능이 부족한 경우가 있다. 이런 경우에는 자신이 원하는 입출력 기능을 사용하기 위하여 기존의 스트림에 필터를 적용하게 된다. (2차 스트림이라고도 부른다.)

필터 스트림(2차 스트림)은 기본 스트림의 기능을 확장시키거나 사용하기 쉽게 변환해주는 스트림으로써 많은 데이터를 입출력해야 할 경우에도 자주 사용된다. 예를들어 FileReader 스트림 클래스 자체에는 줄 단위로 읽어 들이는 메서드가 존재 하지 않지만 filter스트림을 상속받은 BufferedReader는 줄 단위로 읽는 메서드가 존재 하기 때문에 사용하면 속도가 빠르다.


1. FilterInputStream


FilterInputStream 클래스는 필터 바이트 입력 스트림이므로 실제 데이터 원본과 연결된 바이트 입력 스트림을 내부적으로 가지고 있다. 그리고 이 바이트 입력 스트림으로부터 데이터를 읽고, 원하는 형태로 변환하기 위한 기능을 추가적으로 제공해준다.


2. FilterOutputStream


FilterOutputStream 클래스는 필터 바이트 출력 스트림이므로 실제 데이터 대상과 연결된 바이트 출력 스트림을 내부적으로 가지고 있다. 이 바이트 출력 스트림데이터를 쓰기 전에, 데이터를 원하는 형태로 변환하기 위한 기능을 추가적으로 제공해 준다.


3. Data Stream

일반적인 스트림은 바이트나 문자 단위의 처리를 기본으로 하는 스트림이다. 바이트나 문자 단위가 아닌 데이터 타입 단위의 처리를 하고자 할때 도 있다. 가령 int 형 숫자 100을 스트림에 기록한다면 1바이트 저장하는 방식이기 때문에 100은 1바이트로 기록될 것이다. 데이터를 읽어올 때도 당연히 1바이트를 기준으로 읽어오게 된다. 1바이트가 아닌 int형(4바이트)으로 메모리에 기록하고 싶다면 Data 스트림을 이용하면 된다.

DataInputStream과 DataOutputStream은 각각 Filter In/Out스트림을 상속받은 클래스로서 기본 데이터를 직접 읽고 쓸수 있도록하는 클래스이다.


3.1 DataOutputStream


파일 출력을 위해서 FileOutputStream 객체를 생성할 때에는 출력 파일명을 생성자에 직접 기술했었다. 하지만 DataOutputStrea 객체를 생성하기 위해서는 파일명을 직접 기술하지 못한다. 그림에서와 같이 File에 바로 접근하는게 아니고 FileOutputStream으로 접근하기 때문이다.

예1 - DataOutputStream 생성하기

FileOutputStream fos = new FileOutputStream("ㅅㅂ.txt");

DataOutputStream dos = new DataOutputStream(fos);

/* 두줄을 한줄로 DataOuputStream의 매개변수로 바로 FileOutStream 객체 생성

DataOutputStream dos = new DataOutputStream(new FileOutputStream("ㅅㅂ.txt"));

*/


3.2 DataInputStream

DataInputStream 클래스 역시 파일로 데이터를 읽어오기 위해서는 파일명을 직접 쓸수 없다.


그림에서와 같이 FileInputStream으로 받은 Data를 원하는 스트림으로 변하기 위해서 DataInputStream을 사용하는 것이다.

예2 - DataInputStream 생성하기

FileInputStream fis = new FileInputStream("ㅅㅂ.txt");

DataInputStream dis = new DataInputStream(fis);

// 역시 한줄로 쓸수 있다.


※ 학생 정보를 파일에 저장하고 읽어오는 프로그래밍을 보자.

( public static void main(String[] args) throws FileNotFoundException, IOException )

예3 - DataInputStream과 DataOutputStream 사용해보기

//파일에 학생정보 입력하기

FileOutputStream fos = new FileOutputStream("ㅅㅂ.dat");

DataOutputStream dos = new DataOutputStream(fos);

String name = "니나노";

String address = "현실은 시궁창"; //이름과 주소를 저장하기 위해 String

int age = 23 ; //나이를 저장하기 위해 int

double height = 160.6; // 키를 저장하기 위해 double

dos.writeUTF(name); // Stirng으로 읽어오기위한 메서드

dos.writeUTF(address);

dos.writeInt(age);

dos.writeDouble(height);

dos.close();

fos.close();

//입력된 파일을 읽기

FileInputStream fis = new FileInputStream("ㅅㅂ.dat");

DataInputStream dis = new DataInputStream(fis);

String r_name = dis.readUTF();

String r_address = dis.readUTF();

int r_age = dis.readInt();

double r_height = dis.readDouble();

System.out.println(r_name + "," + r_address + "," + r_age + "," + r_height);

dis.close();

fis.close();

run:

니나노,현실은 시궁창,23,160.6

BUILD SUCCESSFUL (total time: 0 seconds)



버퍼 스트림도 필터 스트림의 일종으로 메모리 버퍼를 사용하여 데이터를 입출력하는 스트림이다. 버퍼를 사용하기 때문에 데이터를 읽고 쓰는 속도를 향상할 수 있다. 버퍼 메모리에 data가 다 차면 일괄처리 하는 것이다.


예4 - 버퍼 스트림을 이용한 복사와 그냥 복사 차이를 알아보자

public class Main {

public static void main(String[] args) throws FileNotFoundException, IOException {

int i, len=0 ;

//그냥 스트림으로 연결

FileInputStream fis = new FileInputStream("lotto.txt");

FileOutputStream copy_file = new FileOutputStream("lottoCopy.txt");

long time = System.currentTimeMillis();

while ((i= fis.read()) != -1){

copy_file.write(i);

len++;

}

time = System.currentTimeMillis() - time;

fis.close(); copy_file.close();

System.out.println(len + " byte" + "," + time +"milisec");

}

run:

8507 byte,78milisec

BUILD SUCCESSFUL (total time: 1 second)

버퍼 스트림 이용

public class Main {

public static void main(String[] args) throws FileNotFoundException, IOException {

int i, len=0 ;

//버퍼스트림 생성자로 객체생성 대입 //한줄

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("lotto.txt"));

BufferedOutputStream bos

= new BufferedOutputStream(new FileOutputStream("b_lottoCopy.txt"));

long time = System.currentTimeMillis();

while ((i= bis.read()) != -1){

bos.write(i);

len++;

}

time = System.currentTimeMillis() - time;

bis.close(); bos.close();

System.out.println(len + " byte" + "," + time +"milisec");

}

}

run:

8507 byte,16milisec

BUILD SUCCESSFUL (total time: 0 seconds)

78 milsec -> 16 milsec 으로 줄었다. ★ 버퍼 스트림을 쓰는 가장 큰이유

'I.lib() > I.lib(Java)' 카테고리의 다른 글

dwr 사용방법  (0) 2012.03.22
JAVA 로 MAIL 보내기.(SMTP 방식?! )  (2) 2011.09.26
JAVA에서 엑셀 파일 읽고 쓰기  (0) 2011.07.04
Spy 설정 방법.  (1) 2011.03.31
SPY 설정 방법. ( tomcat + axis2 + ibatis )  (0) 2010.10.28
.
:
Posted by .07274.
2011. 7. 4. 13:26

JAVA에서 엑셀 파일 읽고 쓰기 I.lib()/I.lib(Java)2011. 7. 4. 13:26

.. .. ..
 우선 http://www.andykhan.com/jexcelapi/download.html 에 가서 jexcelapi_2_4_5.tar.gz 파일을 다운로드해서 압출을 해제한다.
압축 파일안에 보면 jxl.jar 파일이 있다. java classpath에 이 파일을 걸어준다.
아래 링크는 Tutorial이 나와있는 사이트이다.



자바로 엑셀을 핸들링 할 수 있는 방법은 크게 두가지로 나누어 진다.

1. Java Excel API
http://www.andykhan.com/jexcelapi/
2. POI
http://jakarta.apache.org/poi/index.html

※ 흔히 POI를 엑셀을 핸들링 하기 위한 것으로만 오해하기 쉬운데, POI 프로젝트는 마이크로소프트 OLE 2 복합 도큐먼트 포맷의 파일을 순수 자바를 이용하여 핸들링하는 APIs로 구성되어 있다. OLE 2 복합 도큐먼트 포맷의 파일은 Microsoft 엑셀 혹은 워드 파일 등의 대부분의 오피스 파일들을 나타낸다.

일반적으로 엑셀에 대한 핸들링만을 수행할 때에는 Jxl을 권장한다. 엑셀을 핸들링 할 때 엑셀에서 가장 작은 단위는 "셀"이다. 모든 작업은 이 셀을 중심으로 이루어진다.

※ 주의할 점
  1. 엑셀 쉬트상에 "C15"라는 셀에 데이터가 있다고 가정하자 (15행 C열을 나타낸다). 이 때 Jxl에서는 A1 (1행 A열)부터 C15까지는 실제 데이터가 없을 경우에라도 null이 아닌 빈데이터가 있다고 인식한다. 즉, D열 이상이나, 16행 이상을 접근 할 때에 null로 인식한다. 하지만 POI에서는 C15 이내에 있다 하더라도 실제 데이터가 없을 때에는 null로 인식한다.

  2. Jxl에서는 각 셀의 데이터 타입을 실제 엑셀 파일에서 지정된 셀의 타입을 따르고, POI에서는 셀의 실제 데이터 형을 따른다. 예를 들어 특정 셀의 타입을 text 로 잡아놓고, 데이터를 1234로 입력하면 Jxl에서는 "12345"로 인식하고, POI에서는 12345.00 이런 식으로 인식한다.


ex) Java Excel API를 이용한 Excel 읽기
import jxl.*;

// .. 중간생략

Workbook workbook = null;
Sheet sheet = null;
Cell cell = null;

try
{
//엑셀파일을 인식
workbook = Workbook.getWorkbook( new File( szFileName));

//엑셀파일에 포함된 sheet의 배열을 리턴한다.
//workbook.getSheets();

if( workbook != null)
{
//엑셀파일에서 첫번째 Sheet를 인식
sheet = workbook.getSheet(0);

if( sheet != null)
{
//셀인식 Cell a1 = sheet.getCell( 컬럼 Index, 열 Index);
//셀 내용 String stringa1 = a1.getContents();

//기록물철의 경우 실제 데이터가 시작되는 Row지정
int nRowStartIndex = 5;
//기록물철의 경우 실제 데이터가 끝 Row지정
int nRowEndIndex = sheet.getColumn( 2).length - 1;

//기록물철의 경우 실제 데이터가 시작되는 Column지정
int nColumnStartIndex = 2;
//기록물철의 경우 실제 데이터가 끝나는 Column지정
int nColumnEndIndex = sheet.getRow( 2).length - 1;

String szValue = "";

for( int nRow = nRowStartIndex; nRow <= nRowEndIndex; nRow++ )
{
for( int nColumn = nColumnStartIndex; nColumn <= nColumnEndIndex ; nColumn++)
{
szValue = sheet.getCell( nColumn, nRow).getContents();
System.out.print( szValue);
System.out.print( "\t" );
}
System.out.println();
}
}
else
{
System.out.println( "Sheet is null!!" );
}
}
else
{
System.out.println( "WorkBook is null!!" );
}
}
catch( Exception e)
{
e.printStackTrace();
}
finally
{
if( workbook != null)
{
workbook.close();
}
}


ex) Jxl을 이용하여 Excel에 데이터 저장하기
import jxl.*;

// .. 중간생략

WritableWorkbook workbook = null;
WritableSheet sheet = null;

File excelFile = new File( szFileName);
Label label = null;

long start = 0;
long end = 0;

try
{
for(int i = 0 ; i < 10; i++)
{
workbook = Workbook.createWorkbook( excelFile);
workbook.createSheet("sheet1", 0);
sheet = workbook.getSheet(0);

for( int j = 0; j < 10000; j++){
label = new Label( j, 0, "test cell");
sheet.addCell( label);
}

kidsbook.write();
kidsbook.close();
}
}
catch( Exception e)
{
}


ex) POI를 이용한 Excel 파일 읽기
import org.apache.poi.hssf.usermodel.*;

// .. 중간 생략

HSSFWorkbook workbook = null;
HSSFSheet sheet = null;
HSSFRow row = null;
HSSFCell cell = null;

try
{
workbook = new HSSFWorkbook( new FileInputStream( new File( szFileName)));

if( workbook != null)
{
sheet = workbook.getSheetAt( 0);

if( sheet != null)
{
//기록물철의 경우 실제 데이터가 시작되는 Row지정
int nRowStartIndex = 5;
//기록물철의 경우 실제 데이터가 끝 Row지정
int nRowEndIndex = sheet.getLastRowNum();

//기록물철의 경우 실제 데이터가 시작되는 Column지정
int nColumnStartIndex = 2;
//기록물철의 경우 실제 데이터가 끝나는 Column지정
int nColumnEndIndex = sheet.getRow( 2).getLastCellNum();

String szValue = "";

for( int i = nRowStartIndex; i <= nRowEndIndex ; i++)
{
row = sheet.getRow( i);

for( int nColumn = nColumnStartIndex; nColumn <= nColumnEndIndex ; nColumn++)
{
cell = row.getCell(( short ) nColumn);

if( cell == null)
{
continue;
}
if( cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
{
szValue = String.valueOf( cell.getNumericCellValue());
}
else
{
szValue = cell.getStringCellValue();
}

System.out.print( szValue);
System.out.print( "\t" );
}
System.out.println();
}
}
else
{
System.out.println( "Sheet is null!!" );
}
}
else
{
System.out.println( "WorkBook is null!!" );
}
}
catch(Exception e){
e.printStackTrace();
}


ex) POI를 이용한 브라우저에서 Excel에 데이터 저장하여 보여주기

import org.apache.poi.hssf.usermodel.*;

// ... 생략

public void writeStream( PTSEvaluation[] arrPTSEvaluation) throws Exception
{
try
{
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet( "new sheet");
HSSFRow row = null;
HSSFCell cell = null;
HSSFCellStyle style = null;

ServletOutputStream excelOut = ServiceContext.getResponse().getOutputStream();
ServiceContext.getResponse().setHeader( "Content-Disposition", "attachment;filename=EvaluationCompensationList.xls");
ServiceContext.getResponse().setContentType( MimeType.getMimeType( "xls"));

//로우 생성
row = sheet.createRow( ( short)0);
row.setHeightInPoints( 30);

//셀에 적용한 스타일을 생성한다.
style = PTSUtil.setExcelHeaderStyle( wb);

// 셀 생성
cell = row.createCell( (short)0);

//한글 처리
cell.setEncoding( HSSFCell.ENCODING_UTF_16);

//셀에 데이터 입력하기
cell.setCellValue( "값");

//셀에 스타일 적용하기
cell.setCellStyle(style);

//.. 중간생략 ( 이런 방식으로 로우와 셀을 증가 시키면서 작업을 수행하면 된다.

wb.write( excelOut);
excelOut.flush();
}
catch( Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
ServiceContext.getResponse().getOutputStream().close();
}
}


-----------------------------------------------------------------------------------
HSSF를 이용해 자바에서 간단한 엑셀 파일을 생성하는 방법을 살펴보도록 하겠다. HSSF를 사용하기 위해서는 먼저 POI 라이브러리를 다운받아야 하는데 아래의 주소에 가서 라이브러리를 다운받은 후 클래스 패스를 잡아주면 된다.


아래의 소스는 간단한 엑셀파일 생성에 관한 소스이다.
import java.io.*;
import org.apache.poi.hssf.usermodel.*;

public class NumberForm {
public static void main(String[] args) throws IOException, InterruptedException {
// 먼저 파일이 되는 workbook부분을 생성한다.
HSSFWorkbook workbook = new HSSFWorkbook();

// workbook부분에 sheet를 새로 생성한다.
HSSFSheet sheet = workbook.createSheet("new");

// sheet부분에 행을 새로 생성한다.
HSSFRow row = sheet.createRow((short)0);

// 새로 생성된 행 부분에 셀을 추가한다.
HSSFCell cell = row.createCell((short)0);

// 셀 값을 집어넣는다(숫자형)
cell.setCellValue(1);

// 셀 값을 집어넣는다(실수형)
row.createCell((short)1).setCellValue(1.2);
// 셀 값을 집어넣는다(문자형)
row.createCell((short)2).setCellValue("string");
// 셀 값을 집어넣는다(boolean형)
row.createCell((short)3).setCellValue(true);

FileOutputStream outFile = new FileOutputStream("newexcelfile.xls");
workbook.write(outFile);
outFile.close();
}
}


새로이 Excel파일을 만드는 방법은 기본적으로 다음과 같다.

1. WorkBook를 만든다 (즉, 파일이 될 부분을 만든다)
2. WorkBook안에 sheet를 만든다
3. sheet안에 행을 만든다
4. 행 안에 기본단위인 셀을 만든다

* 이때 하늘색 바탕으로 표시된 부분이 인텍스 값이 되며, 인덱스는 0부터 시작한다.

[펌] http://jetzt.tistory.com/18

'I.lib() > I.lib(Java)' 카테고리의 다른 글

JAVA 로 MAIL 보내기.(SMTP 방식?! )  (2) 2011.09.26
필터 스트림  (1) 2011.08.02
Spy 설정 방법.  (1) 2011.03.31
SPY 설정 방법. ( tomcat + axis2 + ibatis )  (0) 2010.10.28
JNI (JAVA Native Interface ) 란? & 사용법.  (0) 2010.07.27
.
:
Posted by .07274.
2011. 3. 31. 16:00

Spy 설정 방법. I.lib()/I.lib(Java)2011. 3. 31. 16:00

.. .. ..


# SPY 설정 방법.
1. SPY 라이브러리를 복사하여 적용한다.

2. SPY.properties 파일을 설정한다.  

    realdriver=Altibase.jdbc.driver.AltibaseDriver   <-- Driver 설정
    log4j.appender.SQL=org.apache.log4j.DailyRollingFileAppender <- Log 설정.
    log4j.appender.SQL.layout=org.apache.log4j.PatternLayout
    log4j.appender.SQL.datePattern=yyyy-MM-dd
    log4j.appender.SQL.layout.ConversionPattern=p6spy - %m%n
    log4j.appender.SQL.file=C:/pcas-workspace/logs/pcas-spysql.log

  
3. DataSource에 DriverClassName에 SPY Driver 를 설정한다.

 ex. META-INF/context.xml
  <Context docBase="pcas" path="/pcas" reloadable="true">
  <Resource name="jdbc/pcss" auth="Container"
   type="javax.sql.DataSource"
   factory="org.apache.commons.dbcp.BasicDataSourceFactory"
   maxActive="20"
   maxIdle="10"
   maxWait="-1"
   username="pcss"
   password="pcss123"
   driverClassName="com.p6spy.engine.spy.P6SpyDriver"
   url="jdbc:Altibase://111.111.111.11:20300/mydb"  
         removeAbandoned="true"
         removeAbandonedTimeout="10"
   validationQuery="SELECT 1 FROM dual"
         logAbandoned="true"/>
  </Context>
 


4. 끝~! 

'I.lib() > I.lib(Java)' 카테고리의 다른 글

필터 스트림  (1) 2011.08.02
JAVA에서 엑셀 파일 읽고 쓰기  (0) 2011.07.04
SPY 설정 방법. ( tomcat + axis2 + ibatis )  (0) 2010.10.28
JNI (JAVA Native Interface ) 란? & 사용법.  (0) 2010.07.27
Heapdump 파일 생성 이유  (0) 2010.05.19
.
:
Posted by .07274.
.. .. ..
1. 파일 2가지를 준비한다.
     spy.properties , p6spy.jar

2. Jar 파일은 lib 폴더같은곳에 넣어 Tomcat이 돌때 같이 올라갈수 있도록 둔다.

3. properties 파일은 classes 파일에 log4j.properties에 두는곳과 같은곳에 둔다.

4. driverclassname 에 com.p6spy.engine.spy.P6SpyDriver 라고 Spy Driver Class 이름을 적어준다.

5. spy.properties 에 realdriver=Altibase.jdbc.driver.AltibaseDriver라고 설정해준다.
   ( altibase 일때.. 다른 DB를 사용할 경우 그 db의 DriveClassname 을 적어준다.)

6. 원리
DB요청 - > Tomcat -> Axis2 - > Service - > 설정된 driverclass Load(  Spy Driver Class 로 설정되있으므로 Spy Load)
-> Spy는 spy.properties 파일을 Load하고 설정된 Drive로 연결 - > DB 접속.
 이때 spy를 거치고 DB를 in/out 하기때문에  spy.properties에 설정된 Log 부분에 Query 문을 저장하게 된다.

'I.lib() > I.lib(Java)' 카테고리의 다른 글

JAVA에서 엑셀 파일 읽고 쓰기  (0) 2011.07.04
Spy 설정 방법.  (1) 2011.03.31
JNI (JAVA Native Interface ) 란? & 사용법.  (0) 2010.07.27
Heapdump 파일 생성 이유  (0) 2010.05.19
JNDI 란?  (1) 2010.04.08
.
:
Posted by .07274.
.. .. ..

JNI ( JAVA Native Interface )

ㅇ 제작 : 리눅스포털(www.superuser.co.kr) 수퍼유저코리아 개발팀 이재석


SULINUX 홈페이지 : www.sulinux.net

ㅇ 리눅스포털 홈페이지 : www.superuser.co.kr


  1. JNI ( JAVA Native Interface ) ?

자바로 만들어진 프로그램에서 특정 플랫폼에서만 실행되는 코드

(Native Code)에 접근하기 위한 API이다.


Native code를 생성하는 다른 언어와 함께 공동작업을 하거나

하드웨어어 보다 깊게 접근하여 컨트롤도 가능하지만

플랫폼이 제한된다는 단접이 있다.


  1. 사용방법 및 코드 작성법


1단계 : Native Method를 선언하는 자바 클래스 작성

2단계 : 1단계에서 작성한 클래스 컴파일

3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성

4단계 : C언어로 Native Method 실제 구현

5단계 : C 코드와 헤더 파일을 컴파일

6단계 : 자바 프로그램 실행



위에서 보는것 처럼 6단계로 나누어 작업을 하게 된다.



1단계 : Native Method를 선언하는 자바 클래스 작성



public class tt {

  static {
      //
시스템 라이브러리 로드(so,dll)
      System.loadLibrary("tt");

      System.out.println("=== library was loaded");

  }

  //native method 선언
  public native String main1();
  public native String main2();

  public static void main(String[] args)  throws Exception {

      mains1();
      mains2();

  }

  public static String mains1()  throws Exception {

      return new tt().main1();

  }

  public static String mains2()  throws Exception {

      return new tt().main2();

  }

}





2단계 : 1단계에서 작성한 클래스 컴파일



javac tt.java





3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성



javah tt





4단계 : C언어로 Native Method 실제 구현



#include <jni.h>
#include "tt.h"
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_tt_main1(JNIEnv *, jobject)
{
   printf("Hello, world\n");

   return 0;
}

JNIEXPORT jstring JNICALL Java_tt_main2(JNIEnv *, jobject)
{
   printf("Hello, world1\n");

   return 0;
}





5단계 : C 코드와 헤더 파일을 컴파일



vc   : cl -Ic:\jdk1.3.1\include -Ic:\jdk1.3.1\include\win32 -LD HelloWorld.c


gcc  : cc –G –I/usr/local/java/include –I/usr/local/java/include/solaris HelloWorld.c –o libhelloworld.so



6단계 : 자바 프로그램 실행



java tt

=== library was loaded
Hello, world
Hello, world1





3. JAVA에서 Native code로 파라메타 넘겨주기


JAVA SOURCE


public class Test {

  public native String maint(String msg);

    static {
        System.loadLibrary("Test");
    }

}


NATIVE SOURCE

#include <jni.h>
#include "Test.h"
#include "NativeStringUtil.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

JNIEXPORT jstring JNICALL
Java_Test_maint(JNIEnv *env, jobject obj, jstring str)
{
    char buf[1024];
    char *str;
    str1 = jbyteArray2str1( env, javaGetBytes(env, str) );
    sprintf(buf, "%s:%s", str1, "반가워요 이건 C함수에서 넘겨준 겁니다.");
    return javaNewString( env, cstr2jbyteArray(env, buf));
}



            java에서 public native String maint(String msg)
            여기서 넘어온 스트링값을  Native code에서
            str1 = jbyteArray2str1( env, javaGetBytes(env,
            str) ); 위와 같은  방식으로  받아온다.


       4. 마치며

           앞에서도 언급 하였듯이 java에서 직접 네이티브 코드를 호출하여 
           이용할 수 있다.

           네이티브 코드를 생상할수 있는 다른 언어와도 협업작업이 쉬워지고 
           아키텍쳐에 따른 하드웨어 콘트롤 역시 가능하며 
 
            메모리 컨트롤이나 CPU컨트롤시 보다 디테일 하게 컨트롤이 가능하다

           하지만 Native code를 생산하고 이용하게 됨으로 
           특정 아키텍쳐나 플랫폼에 종속될수 밖에 없고 
           다양한 플랫폼을 지원 하려면 그많큼 수고로울수 밖에 없다 .
           
           보는바와 같이 장단점을 잘 숙지해야 하겠다. 

'I.lib() > I.lib(Java)' 카테고리의 다른 글

Spy 설정 방법.  (1) 2011.03.31
SPY 설정 방법. ( tomcat + axis2 + ibatis )  (0) 2010.10.28
Heapdump 파일 생성 이유  (0) 2010.05.19
JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
.
:
Posted by .07274.