파일 열기 창, 저장창을 활용한 파일 복사 예제
- 파일 열기/저장 창
JFileChooser - 확장자 설정
FileNameExtensionFilter - 파일 유형 추가
[열기/저장창 객체].addChoosableFileFilter(확장자 객체) - 파일 유형 기본값
[열기/저장창 객체].setFileFilter(기본값으로 설정할 확장자 객체) - Dialog 창 기본경로
[열기/저장창 객체].setCurrentDirectory(새로운 파일 객체(디렉토리) ) - Dialog 열기
[열기/저장창 객체].showOpenDialog(new Panel()) - Dialog 저장
[열기/저장창 객체].showSaveDialog(new Panel()) - Dialog창이 열렸는지 확인 여부
JFileChooser.APPROVE_OPTION
import java.awt.Panel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
public class FileCopyDialog {
public static void main(String[] args) {
new FileCopyDialog().fileCopyStart();
}
// 시작 메서드
public void fileCopyStart() {
// File sourceFile = new File("d:/d_other/코알라.jpg")
File sourceFile = showDialog("OPEN");
// 취소 눌렀을 때
if(sourceFile==null) {
System.out.println("복사할 원본 파일이 선택되지 않았습니다");
System.out.println("복사 작업 중지..");
return;
}
if (!sourceFile.exists()) {
System.out.println(sourceFile.getPath());
System.out.println("복사 작업을 마칩니다..");
return;
}
File targetFile = showDialog("SAVE");
// 취소 눌렀을 때
if(targetFile==null) {
System.out.println("대상 파일이 선택되지 않았습니다");
System.out.println("복사 작업 중지..");
return;
}
// 원본 파일을 읽어올 스트림 객체 생성
FileInputStream fi = null;
// 대상 파일로 저장될 스트림 생성
FileOutputStream fo = null;
try {
fi = new FileInputStream(sourceFile);
fo = new FileOutputStream(targetFile);
int c;
while ((c = fi.read()) != -1) {
fo.write(c);
}
System.out.println("복사 작업 완료..");
} catch (IOException e) {
// TODO: handle exception
} finally {
if (fi == null) {
try {
fi.close();
} catch (IOException e2) {
// TODO: handle exception
}
}
if (fo == null) {
try {
fo.close();
} catch (IOException e2) {
// TODO: handle exception
}
}
}
}
public File showDialog(String option) {
// SWING의 파일 열기 창, 저장 창 연습
JFileChooser chooser = new JFileChooser();
// 선택할 파일 확장자 설정
FileNameExtensionFilter txt = new FileNameExtensionFilter("텍스트문서(*.txt)", "txt");
// 파일 확장자가 여러 개 일 경우 배열로 선언
FileNameExtensionFilter img = new FileNameExtensionFilter("이미지 파일", new String[] { "jpg", "png", "gif" });
// 가변 변수 처럼 나열해서 쓸 수도 있음
FileNameExtensionFilter doc = new FileNameExtensionFilter("MS Word 파일", "docx", "doc");
// '모든 파일' 목록 표시 여부 설정하기 (true일 때 출력)
chooser.setAcceptAllFileFilterUsed(true);
chooser.addChoosableFileFilter(txt);
chooser.addChoosableFileFilter(img);
chooser.addChoosableFileFilter(doc);
// 확장자 목록 중 기본값으로 선택될 확장자 설정하기
chooser.setFileFilter(txt);
// Dialog 창이 나타낼 기본 경로 설정하기
chooser.setCurrentDirectory(new File("d:/d_other"));
// 창 보여주기
int result;
if ("OPEN".equals(option.toUpperCase())) {
result = chooser.showOpenDialog(new Panel()); // 열기용
} else if ("SAVE".equals(option.toUpperCase())) {
result = chooser.showSaveDialog(new Panel()); // 저장용
} else {
System.out.println("option 매개변수에는 'OPEN'또는 'SAVE'만 사용하세요");
return null;
}
File selectedFile = null;
// 보여진 창에서 파일을 선택한 후 '열기' 또는 '저장' 버튼을 눌렀을 경우 처리하기
if (result == JFileChooser.APPROVE_OPTION) { // 열기나 저장버튼 눌렀는 지 확인
selectedFile = chooser.getSelectedFile();
System.out.println("선택한 파일 : " + selectedFile.getAbsolutePath());
}
return selectedFile;
}
}
Buffered 스트림
- 입출력 효율을 높이기 위해 버퍼를 사용하는 보조 스트림
- 버퍼의 기본 크기는 8KB( 8192 bytes )이다
- 크기를 생성하지 않은 경우 기본 크기를 가진다
write()로 크기만 한 값을 출력하지만
출력작업이 끝나면 버퍼에 남아 있는 데이터를 모두 강제 출력 시켜야한다
이 때 flush()가 그런 역할을 수행한다.
close() 안에도 flush() 기능이 있기 때문에 모든 데이터를 출력시켜주지만 가급적 flush()를 사용해주는 것이 좋음
사이에 다른 작업을 이어서 해줄 때가 있으므로 그 때 출력 작업이 마무리되지 않은 상태로 작업하면 엉뚱하게 일어날 수 있기 때문에 바로 flush()를 사용하여 제대로 출력시켜주는 것이 좋다
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedIOTest01 {
public static void main(String[] args) {
// 입출력의 성능 향상을 위해서 Buffered스트림을 사용한다
try {
FileOutputStream fout = new FileOutputStream("d:/d_other/bufferTest.txt");
// 버퍼의 크기가 5인 버퍼스트림 객체 생성
BufferedOutputStream bout = new BufferedOutputStream(fout, 5);
// 크기가 5임으로 5개 출력
for(int i='1'; i<='9'; i++) {
bout.write(i); // 12345
}
// 출력작업이 끝나면 버퍼에 남아 있는 데이터를 모두 강제 출력 시켜야한다
// 이 때 flush()가 그런 역할을 수행한다.
bout.flush(); // 123456789
// close() 안에도 flush() 기능이 있기 때문에 모든 데이터를 출력시켜주지만 가급적 flush()를 사용해주는 것이 좋음
// 사이에 다른 작업을 이어서 해줄 때가 있으므로 그 때 출력 작업이 마무리되지 않은 상태로 작업하면 엉뚱하게 일어날 수 있기 때문에
// 바로 flush()를 사용하여 제대로 출력시켜주는 것이 좋다
// 스트림 닫기
// 보조 스트림을 닫으면 보조스트림에서 사용한 기반이 되는 스트림도 같이 닫힌다.
bout.close(); // 123456789
System.out.println("출력 작업 끝...");
} catch (IOException e) {
// TODO: handle exception
}
}
}
문자 기반 buffered 스트림
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedIOTest02 {
public static void main(String[] args) {
try {
// 문자 파일읽기
FileReader fr = new FileReader("./src/kr/or/ddit/basic/FileTest01.java");
BufferedReader br = new BufferedReader(fr); // 버퍼의 크기를 지정하지 않으면 8kb
String temp = "";
// readLine 한줄 씩 읽어옴
// 더이상 읽어올 데이터가 없을 때 null반환
for(int i=1; (temp = br.readLine()) != null; i++) {
System.out.printf("%4d : %s\n", i, temp);
}
br.close(); // 스트림 닫기
} catch (IOException e) {
// TODO: handle exception
}
}
}
데이터 저장 / 읽어오기
DataInputStream
DataOutputStream
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataIOTest {
public static void main(String[] args) {
try {
FileOutputStream fout = new FileOutputStream("d:/d_other/dataTest.dat");
// 기본 자료형 단위로 출력할 보조 스트림 객체 생성
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(200); // 정수형으로 출력
dout.writeFloat(123.45f); // 실수형(float)으로 출력
dout.writeBoolean(false); // 논리형으로 출력
dout.writeUTF("ABCDabcd"); // 문자열형식으로 출력
System.out.println("출력 완료...");
dout.close(); // 스트림 닫기
} catch (IOException e) {
// TODO: handle exception
}
System.out.println("============");
// 출력한 자료 읽어오기
try {
FileInputStream fin = new FileInputStream("d:/d_other/dataTest.dat");
DataInputStream din = new DataInputStream(fin);
// 자료를 읽어와 화면에 출력하기
// DataInputStream으로 자료를 읽어올 때는 출력할 때와 같은 순서로 읽어와야 한다
System.out.println("정수형 : "+din.readInt());
System.out.println("실수형 : "+din.readFloat());
System.out.println("논리형 : "+din.readBoolean());
System.out.println("문자열 : "+din.readUTF());
System.out.println();
System.out.println("읽기 작업 완료...");
din.close(); // 스트림 닫기
} catch (IOException e) {
// TODO: handle exception
}
}
}
직렬화(serialization)
transient ==> 직렬화가 되지 않을 멤버 변수에 지정한다.
Object 객체를 저장하는 stream
ObjectOutputStream
ObjectInputStream
입력
import java.io.Serializable;
public class Member implements Serializable {
private String name;
private int age;
private String addr;
public Member(String name, int age, String addr) {
super();
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectIOTest01 {
public static void main(String[] args) {
// Member의 인스턴스 생성
Member mem1 = new Member("홍길동", 20, "대전");
Member mem2 = new Member("홍길서", 20, "인천");
Member mem3 = new Member("홍길남", 30, "부산");
Member mem4 = new Member("홍길북", 40, "속초");
// 객체를 파일로 저장하기
try {
// 출력용 스트림 객체 생성
FileOutputStream fout = new FileOutputStream("d:/d_other/memObj.dat");
BufferedOutputStream bout = new BufferedOutputStream(fout);
ObjectOutputStream oout = new ObjectOutputStream(bout);
// 쓰기 작업
System.out.println("객체 저장 작업 시작..");
oout.writeObject(mem1);
oout.writeObject(mem2);
oout.writeObject(mem3);
oout.writeObject(mem4);
// 객체를 저장할 때 마지막에 null값을 추가하여 EOFException을 방지할 수 있다.
oout.writeObject(null);
System.out.println("객체 저장 작업 완료..");
oout.close(); // 스트림 닫기 (fout bout oout 스트림을 닫음)
} catch (IOException e) {
e.printStackTrace();
// java.io.NotSerializableException
}
}
}
출력
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectIOTest02 {
public static void main(String[] args) {
// 파일에 저장된 객체를 읽어와 그 내용을 화면에 출력하기
try {
// 입력용 스트림 객체 생성
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream("d:/d_other/memObj.dat")));
Object obj = null; // 읽어온 객체를 저장할 변수
System.out.println("객체 읽기 작업 시작..");
// readObject() 메서드가 데이터를 끝까지 다 읽어오면 EOFException이 발생한다
// 오류가 발생되어 반복문 다음 문장이 출력이 되지 않음
// 발생되지 않기 위해 입력할 때 null값을 추가
while((obj = oin.readObject())!=null) {
// 읽어온 데이터는 원래의 객체형으로 변환 후 사용한다.
Member mem = (Member) obj;
System.out.println("이름 : "+mem.getName());
System.out.println("나이 : "+mem.getAge());
System.out.println("주소 : "+mem.getAddr());
System.out.println();
}
System.out.println("반복문 다음 문장 출력");
oin.close();
// }catch (EOFException e) {
// System.out.println("작업 완료...");
} catch (ClassNotFoundException e) { // readObject() 오류 검출
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
만약 age가 transient로 선언될 경우
package kr.or.ddit.basic;
import java.io.Serializable;
public class Member implements Serializable {
// transient ==> 직렬화가 되지 않을 멤버 변수에 지정한다.
private String name;
private transient int age;
private String addr;
public Member(String name, int age, String addr) {
super();
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
직렬화 대상에서 빠지게 되므로 data에 저장이 되지않아
모든 데이터의 age가 0으로 저장이된다
'JAVA > HIGH JAVA' 카테고리의 다른 글
[JAVA] 네트워킹 - InetAddress, URL, URLConnection (0) | 2024.05.08 |
---|---|
5/7 Homework - 전화번호 관리 + 데이터 (0) | 2024.05.08 |
5/3 Homework 사진 파일 복사 (0) | 2024.05.03 |
[JAVA] 입출력( I/O ) - File객체 (0) | 2024.05.02 |
[JAVA] 스레드 - 공통 객체 / 동기화 (1) | 2024.05.01 |