버퍼를 이용한 파일 읽기와 쓰기는 서로 대응되는 메소드를 이용하면 되므로,
이곳에서는 파일을 Write 하는 방법만 기술합니다.
FileOutputStream 는 FileInputStream, BufferedOutputStream 는 BufferedInputStream 입니다.
덤으로, DB 에 Long Raw 로 저장된 내용을 가져와서 이미지 파일을 생성해 보겠습니다.
커넥션 맺는 부분은 환경에 따라 다르므로 이곳에서는 설명을 하지 않아요.
import 해야 하는 패키지는 머리를 굴려서 생각해 보세요..
Connection 과 PreapredStatement, ResultSet 등은 java.sql 패키지,
File FileOutputStream BufferedOutputStream 등은 java.io 패키지에 존재합니다.
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
File file = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
conn = ... ; /* 이 부분은 환경에 맞춰서 코딩해 주세요. */
StringBuffer sb = new StringBuffer(); // 사실은 쿼리가 긴데 편의를 위해서 줄였고요, String 보다는 StringBuffer 가 좋져
sb.append("select id, image from tableA");
ps = conn.prepareStatement(sb.toString());
conn.setString(1, ...); // PreparedStatement 라고 해서 반드시 파라미터가 있어야 하는 것은 아니지만..
...
rs = ps.executeQuery();
int cnt = 0; // 진행상황을 보려구 설정하였습니다.
while(rs.next()){
byte[] photo = rs.getBytes("photo"); // 이진파일을 다루려면 getString 하면 안 되고, getBytes 해야 합니다.
String resno = rs.getString("id"); // 아이디에 맞춰서 파일을 생성하기 때문에.. 아이디를 따 왔습니다. 물론, Unique
file = new File("/data1/dir1/" +resno+ ".jpg"); // 경로는 환경에 맞게 맞추세요. Stream 대상을 정의합니다.
fos = new FileOutputStream(file); // 먼저는 Buffer 에 넣지만 다시 File 쪽으로 보내는 거죠.
bos = new BufferedOutputStream(fos); // Buffer 에 넣기 때문에 남아있는 메모리 사이즈는 신경써야 하죠.
bos.write(photo, 0, photo.length); // Buffer 에 담은 것을 파일에 I/O 합니다.
bos.flush(); // FileOutputStream 에는 flush 가 없지요. flush 를 해야지 메모리에 남기지 않고 몽땅 파일에 저장해요.
if(++cnt % 100 == 0) System.out.println("Progress : "+cnt+".."); // 이 부분은 진행상황을 보려구요..
} /* while(rs.next()){ */
}catch(Exception e){
StringBuffer sbLog = new StringBuffer(); // 버퍼에 담았다가 저장
sbLog.append("\n"); // 다른 로그와 섞일까봐..
sbLog.append("+++.메소드나 JSP 명을 넣으면 구분하기 쉽겠죠..\n");
sbLog.append("+++.Exception:" +e.toString()+ "..\n");
System.out.println(sbLog); // println 이기 때문에 맨 뒤에는 sbLog.append("\n"); 불필요.
}finally{
if (rs != null) try{ rs.close(); } finally { rs = null; } // ResultSet 도 close() 하는 습관을 들이세요.
if (ps != null) try{ ps.close(); } finally { ps = null; } // PreparedStatement 도 close() 하는 습관을 들이세요.
if (conn != null) try{ conn.close(); } finally { conn = null; } // Connection 도 close() 하는 습관을 들이세요.
if (bos != null) try{ bos.close(); } finally { bos = null; } // BufferedOutputStream 도 close() 하는 습관을 들이세요.
if (fos != null) try{ fos.close(); } finally { fos = null; } // FileOutputStream 도 close() 하는 습관을 들이세요.
}
개략적으로 다시 설명하면,
File 개체를 생성해서 필요한 파일을 설정하고
(File 개체를 생성해도 파일이 실제로 생성되는 것은 아닙니다. 물론 이미 생성된 파일이라도 열어놓지도 않죠..),
FileOutputStream 과 BufferedOutputStream 를 이용하여 필요한 개체를 차례로 생성하고
(new BufferedOutputStream(new FileOutputStream(new File("..."))) 하는 분도 있던데 말리지는 않지만..),
저장할 내용을 BufferedOutputStream.write() 하고 BufferedOutputStream.flush() 로 버퍼 내용을 떨어낸 다음
(fush() 는 반드시 기술해 주어야 합니다. 간혹 메모리에서 파일로 저장하기 전에 close() 할 수 있습니다),
BufferedOutputStream.close() 와 FileOutputStream.close() 작업을 합니다
(BufferedOutputStream 와 FileOutputStream 양쪽 모두 close() 해 주세요.).
정상적으로 처리가 된다면 불필요 하게 예외 처리와 예외 처리를 위한 준비작업을 할 필요는 없겠지요.
그러나, 어떤 조건이나 상황에서든 예외는 발생하기 때문에 반드시 예외 처리를 해 주어야 합니다.
'컴퓨터 이야기 > 프로그래밍' 카테고리의 다른 글
누가 말도 안 되는 말을, 파이어폭스에서는 form 태그를 table 밖에 두어야 한다는..? (7) | 2009.12.12 |
---|---|
의도하지 않는 빈 줄이 생기지 않도록 form 태그와 table, iframe 태그들을 배열하는 순서 (5) | 2009.12.10 |
innerHTML 에 태그값을 넣을때 주의하세요. innerHTML 은 웹브라우저가 XML DOM 구조로 이해를 합니다. (7) | 2009.12.02 |
하나의 웹페이지 안에서 특정 위치로 포커스 이동, focus() 와 location.hash (6) | 2009.11.25 |
overflow 와 overflow-y 를 사용하여 필요한 경우에만 스크롤이 생기게 하자. (2) | 2009.11.05 |