- 기본 Java 데이터 유형을 플랫폼에 독립적인 방법으로 기본 입력 스트림에서 읽을 수 있다.
- 필터 스트림이기 때문에 다른 입력 스트림을 생성자의 인자로 받아 객체를 생성한다.
- InputStream, FilterInputStream의 하위 클래스
import java.io.DataInputStream;
import java.io.FileInputStream;
public class Ex016_DataInputStream {
public static void main(String[] args) {
// DataOutputStream으로 저장한 내용은 DataInputStream으로 읽어야 한다.
// 저장한 자료형 순서대로 읽어 들인다.
// 더 이상 읽을 데이터가 없으면 IOException이 발생된다.
try(DataInputStream dis = new DataInputStream(new FileInputStream("text.txt"))) {
System.out.println(dis.readUTF());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readInt());
System.out.println(dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}
java.io.DataOutputStream 클래스
- 기본 Java 데이터 유형을 출력하는 기능을 가진 클래스로 필터 스트림이기 때문에 다른 출력 스트림을 생성자의 인자로 받아 생성한다.
- OutputStream, FilterOutputStream의 하위 클래스
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Ex015_DataOutputStream {
public static void main(String[] args) {
try(DataOutputStream dos = new DataOutputStream(new FileOutputStream("text.txt"))) {
dos.writeUTF("서울");
dos.writeByte(10);
dos.writeChar('A');
dos.writeInt(50);
dos.writeInt(70);
dos.writeUTF("서울");
System.out.println("파일 저장 완료...");
} catch (IOException e) {
e.printStackTrace();
}
}
}
필터 스트림 ?
- 필터 스트림은 기존의 스트림을 원하는 기능을 제공하는 새로운 스트림으로 바꾸어 주는 스트림이다.
- 필터 스트림의 최상위 클래스에는 FilterInputStream과 FilterOutputStream클래스가 있다.
FilterInputStream과 FilterOutputStream 클래스
- 이 클래스를 인스턴스 한 객체는 매개변수로 입력 받은 다른 스트림과 연결되어있다.
- 실제 데이터 소스에서 스트림을 처리하는 것이 아니라 다른 스트림과 연결하는 용도로 사용된다.
따라서 입/출력 스트림에서 받은 데이터를 다른 데이터로 변환하거나 추가 작업을 하는 클래스이다.
- user.txt 파일을 읽어서 합격자만 pass.txt에 저장하는 프로그램 작성 - user.txt 파일 형식 이름,국,영,수 - pass.txt 파일 형식 이름,국,영,수 - 세과목 모두 40점 이상이고 평균이 60점 이상인 경우만 합격자 - pass.txt에 저장할 때는 총점 내림차순으로 저장(단, 이것은 못하겠으면 안해도 됨) - UserDTO 만들고, UserPass 라는 클래스를 만들어서 작성할 것 - ArrayList 사용하면 쉽다. (Map 사용 안함) - 작성할 수 있는데 까지 작성해서 메일로 보내기
Main
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
public class Ex012_PassUser {
public static void main(String[] args) {
UserPass vo = new UserPass();
vo.loadfile();
vo.savefile();
System.out.println("파일 생성 완료...");
}
}
Class
class UserDTO {
private String name;
private Integer kor;
private Integer eng;
private Integer mat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getKor() {
return kor;
}
public void setKor(Integer kor) {
this.kor = kor;
}
public Integer getEng() {
return eng;
}
public void setEng(Integer eng) {
this.eng = eng;
}
public Integer getMat() {
return mat;
}
public void setMat(Integer mat) {
this.mat = mat;
}
}
class UserPass {
private ArrayList<UserDTO> list = new ArrayList<>();
private String pathname1 = "user.txt";
private String pathname2 = "pass.txt";
public void loadfile() {
try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
String s;
while ( (s = br.readLine()) != null ) {
String [] ss = s.split(",");
if(ss.length < 2) {
continue;
}
UserDTO vo = new UserDTO();
vo.setName(ss[0]);
int kor, eng, mat, tot;
long ave;
kor = Integer.parseInt(ss[1]);
eng = Integer.parseInt(ss[2]);
mat = Integer.parseInt(ss[3]);
tot = kor+eng+mat;
ave = tot / 3 ;
if ( ave >=60 && (kor>=40 && eng>=40 && mat >=40)) {
vo.setKor(kor);
vo.setEng(eng);
vo.setMat(mat);
list.add(vo);
} else {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void savefile() {
try(PrintStream ps = new PrintStream(pathname2)) {
Iterator<UserDTO> it = list.iterator();
while(it.hasNext()) {
UserDTO vo = it.next();
ps.println(vo.getName()+"\t"+vo.getKor()+"\t"
+vo.getEng()+"\t"+vo.getMat());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
총점 내림차순은
혼자서 해보다가 못했음.
내가 하려고 했던 방법은,
1) int[] 를 만들어서 총점을 담는다.
2) list.add 할 때 만 총점 배열에 총점을 넣음. 그래야 출력(합격자)할 자료들만 모아지니까
3) list.add 가 끝나면 그 배열을 선택정렬을 통해 정렬할때 리스트도 list.set() 으로 바꿈.
int [] total = new int[] {list.size()};
int count = 0;
total[count++] = tot;
UserDTO vo2;
int c;
for (int i = 0; i<list.size() -1 ; i++){
for(int j = i+1; i<list.size() ; j++){
if(total[i] < total[j]){
c = total[i];
total[i] = total[j];
total[j] = c;
vo2 = list.get(i);
list.set(i, list.get(j));
list.set(j, vo2);
}
}
}
원래 합격자들만 출력한 결과는
이것인데 총점 내림차순은 못했음.
public void loadfile() {
int [] total = new int[] {list.size()};
try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
String s;
while ( (s = br.readLine()) != null ) {
String [] ss = s.split(",");
if(ss.length < 2) {
continue;
}
UserDTO vo = new UserDTO();
vo.setName(ss[0]);
int kor, eng, mat, tot;
long ave;
kor = Integer.parseInt(ss[1]);
eng = Integer.parseInt(ss[2]);
mat = Integer.parseInt(ss[3]);
tot = kor+eng+mat;
ave = tot / 3 ;
if ( ave >=60 && (kor>=40 && eng>=40 && mat >=40)) {
vo.setKor(kor);
vo.setEng(eng);
vo.setMat(mat);
list.add(vo);
int count = 0;
total[count++] = tot;
} else {
continue;
}
UserDTO vo2;
int c;
for (int i = 0; i<total.length-1 ; i++){
for(int j = i+1; i<total.length ; j++){
if(total[i] < total[j]){
c = total[i];
total[i] = total[j];
total[j] = c;
vo2 = list.get(i);
list.set(i, list.get(j));
list.set(j, vo2);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
이렇게 하니까 안터지긴 하는데 결과가 정렬부분 있든 없든 똑같음...
그럼
아예 UserDTO 에 총점입력하는 칸을 넣어서 하는 것이 어떨까?
public class Ex012_PassUser {
public static void main(String[] args) {
UserPass vo = new UserPass();
vo.loadfile();
vo.sort();
vo.savefile();
System.out.println("파일 생성 완료...");
}
}
class UserDTO {
private String name;
private Integer kor;
private Integer eng;
private Integer mat;
private Integer tot;
public Integer getTot() {
return tot;
}
public void setTot(Integer tot) {
this.tot = tot;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getKor() {
return kor;
}
public void setKor(Integer kor) {
this.kor = kor;
}
public Integer getEng() {
return eng;
}
public void setEng(Integer eng) {
this.eng = eng;
}
public Integer getMat() {
return mat;
}
public void setMat(Integer mat) {
this.mat = mat;
}
}
class UserPass {
private ArrayList<UserDTO> list = new ArrayList<>();
private String pathname1 = "user.txt";
private String pathname2 = "pass.txt";
public void loadfile() {
try (BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
String s;
while ((s = br.readLine()) != null) {
String[] ss = s.split(",");
if (ss.length < 2) {
continue;
}
UserDTO vo = new UserDTO();
vo.setName(ss[0]);
int kor, eng, mat, tot;
long ave;
kor = Integer.parseInt(ss[1]);
eng = Integer.parseInt(ss[2]);
mat = Integer.parseInt(ss[3]);
tot = kor + eng + mat;
ave = tot / 3;
if (ave >= 60 && (kor >= 40 && eng >= 40 && mat >= 40)) {
vo.setKor(kor);
vo.setEng(eng);
vo.setMat(mat);
vo.setTot(tot);
list.add(vo);
} else {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void savefile() {
try (PrintStream ps = new PrintStream(pathname2)) {
Iterator<UserDTO> it = list.iterator();
while (it.hasNext()) {
UserDTO vo = it.next();
ps.println(vo.getName() + "\t" + vo.getKor()
+ "\t" + vo.getEng() + "\t" + vo.getMat());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void sort() {
UserDTO vo2;
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
if(list.get(i).getTot() < list.get(j).getTot()) {
vo2 = list.get(i);
list.set(i, list.get(j));
list.set(j, vo2);
}
}
}
}
}
예!! 이렇게 정렬하는 것을 따로 메소드로 만들어서 거기서 총점을 가지고 바꾸는 것을 해보았다.
예! 총점은 확인용으로 출력해보았다.
앗싸 - 이게 맞는지는 내일 수업을 듣고 업데이트 하겠다.
총점 내림 차순 추가
Main
public class Ex012_PassUser {
public static void main(String[] args) {
UserPass vo = new UserPass();
vo.loadfile();
vo.sort();
vo.savefile();
System.out.println("파일 생성 완료...");
}
}
Class
class UserDTO {
private String name;
private Integer kor;
private Integer eng;
private Integer mat;
private Integer tot;
public Integer getTot() {
return tot;
}
public void setTot(Integer tot) {
this.tot = tot;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getKor() {
return kor;
}
public void setKor(Integer kor) {
this.kor = kor;
}
public Integer getEng() {
return eng;
}
public void setEng(Integer eng) {
this.eng = eng;
}
public Integer getMat() {
return mat;
}
public void setMat(Integer mat) {
this.mat = mat;
}
}
class UserPass {
private ArrayList<UserDTO> list = new ArrayList<>();
private String pathname1 = "user.txt";
private String pathname2 = "pass.txt";
public void loadfile() {
try (BufferedReader br = new BufferedReader(new FileReader(pathname1))) {
String s;
while ((s = br.readLine()) != null) {
String[] ss = s.split(",");
if (ss.length < 2) {
continue;
}
UserDTO vo = new UserDTO();
vo.setName(ss[0]);
int kor, eng, mat, tot;
double ave;
kor = Integer.parseInt(ss[1]);
eng = Integer.parseInt(ss[2]);
mat = Integer.parseInt(ss[3]);
tot = kor + eng + mat;
ave = tot / 3;
if (ave >= 60 && (kor >= 40 && eng >= 40 && mat >= 40)) {
vo.setKor(kor);
vo.setEng(eng);
vo.setMat(mat);
vo.setTot(tot);
list.add(vo);
} else {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void savefile() {
try (PrintStream ps = new PrintStream(pathname2)) {
Iterator<UserDTO> it = list.iterator();
while (it.hasNext()) {
UserDTO vo = it.next();
ps.println(vo.getName() + "\t" + vo.getKor()
+ "\t" + vo.getEng() + "\t" + vo.getMat());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void sort() {
UserDTO vo2;
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
if(list.get(i).getTot() < list.get(j).getTot()) {
vo2 = list.get(i);
list.set(i, list.get(j));
list.set(j, vo2);
}
}
}
}
}
System.getProperty("user.dir");으로 현재 작업경로를 알 수 있다.
File.separator : Windows는 \, Mac이나 Linux / 을 나타낸다.
f.exists() : 폴더 또는 파일이 존재하면 true, 없으면 false를 반환
System.exit(0) : 프로그램 종료
File클래스를 통해 파일명, 경로, 절대경로, 표준경로, 파일길이, 생성일자 ... 등을 알 수 있다.
파일 삭제 (1) - 한 개만 삭제
import java.io.File;
public class Ex002_FileDelete {
public static void main(String[] args) {
String appDir = System.getProperty("user.dir"); // 현재 작업 경로
String pathname = appDir + File.separator + "test.txt";
File f = new File(pathname);
if (!f.exists()) {
System.out.println(pathname + "파일이 존재하지 않습니다.");
System.exit(0);
}
boolean b = f.delete();
// 파일 또는 디렉토리 삭제
// 한번에 하나의 파일 또는 디렉토리만 삭제 가능
// 디렉토리는 비어 있어야 삭제가 가능
if (b) {
System.out.println("파일이 삭제 되었습니다.");
} else {
System.out.println("파일 삭제가 실패 했습니다.");
}
}
}
f.delete(); 메소드
- 파일 또는 디렉토리를 삭제한다.
- 한번에 하나의 파일 또는 디렉토리만 삭제가 가능하다.
- 디렉토리는 비어 있어야 삭제가 가능하다.
파일 삭제(2) - 해당 경로에 있는 모든 파일 삭제
import java.io.File;
public class Ex007_FileRemove {
public static void main(String[] args) {
String pathname = "C:"+File.separator + "ex";
FileManager fm = new FileManager();
fm.removeDir(pathname);
System.out.println("디렉토리 또는 파일 삭제 완료...");
}
}
class FileManager {
/**
* 파일 또는 폴더 삭제 (하위 폴더 및 모든 파일도 제거 되므로 조심해라...)
* @param pathname 삭제할 폴더 또는 파일
* @return 폴더 또는 파일 삭제 여부
*/
public boolean removeDir(String pathname) {
boolean b = false;
try {
File f = new File(pathname);
if(f.isDirectory()) { // 폴더이면 속으로 들어가라
removeSubDir(pathname);
}
b = f.delete(); // 폴더가 아니면 삭제
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
private void removeSubDir(String pathname) {
File[] ff = new File(pathname).listFiles();
try {
if(ff.length == 0) // 자식이 없는 경우
return;
for(File f : ff) {
if(f.isDirectory()) { // 폴더면 또 안으로 들어가기
removeSubDir(f.getPath()); // 재귀 호출
}
f.delete();
}
} catch (Exception e) {
}
}
}
f.delete() 폴더가 아니면 삭제하고 자식이 없는 디렉토리일시에도 삭제한다.
디렉토리 일시 안으로 들어가서 파일들을 하나씩 다 삭제하는데, 다시 또 디렉토리면 재귀 호출을 통해 해당 경로에 있는 디렉토리 안으로 들어가서 또 파일을 하나씩 다 삭제한다.
파일 리스트
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Ex004_FileList {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s;
try {
System.out.print("경로 ? ");
s = br.readLine();
dirList(s);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void dirList(String pathname) {
// 폴더에 존재하는 폴더 또는 파일 리스트 확인하기
File file = new File(pathname);
if ( ! file.exists()) {
System.out.println("디렉토리가 존재하지 않습니다.");
return;
}
if(! file.isDirectory()) {
System.out.println("디렉토리가 아닙니다.");
return;
}
File [] ff = file.listFiles();
// 폴더에 존재하는 모든 폴더 또는 파일에 대한 File 객체를 반환
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String s;
for(File f : ff) {
s = sdf.format(new Date(f.lastModified()));
if(f.isFile()) {
System.out.print(f.getName()+"\t");
System.out.print(s+"\t");
System.out.println(f.length()+"bytes");
} else if(file.isDirectory()) {
System.out.println("["+f.getName()+"]...");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
file.exists() 입력한 경로에 파일/디렉토리가 존재하지 않으면 false를 반환한다.
file.isDirectory() 입력한 경로가 디렉토리면 true, 아니면 false를 반환한다.
file.listFiles() 입력한 경로에 존재하는 모든 파일, 디렉토리를 파일 배열로 반환한다.
파일은 파일명, 생성날짜, 파일길이를 출력하고
디렉토리는 [ ] 대괄호로 출력한다.
파일 만들기
import java.io.File;
public class Ex005_FileMakeDir {
public static void main(String[] args) {
String pathname = "c:"+File.separator+"ex"+File.separator+"test";
try {
File f = new File(pathname);
if(! f.exists()) {
f.mkdirs(); // 상위 폴더가 존재하지 않으면 상위 폴더도 생성함
// f.mkdir(); // 상위 폴더가 존재하지 않으면 폴더를 생성하지 않음
System.out.println("디렉토리를 생성했습니다.");
} else {
System.out.println("존재하는 디렉토리입니다.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
f.mkdirs() 상위 폴더가 존재하지 않으면 상위 폴더도 생성한다. 즉 ex가 없으면 ex도 만들고 test도 만든다.
f.mkdir() 상위 폴더가 존재하지 않으면 폴더를 생성하지 않음. 즉, ex가 없으면 test가 만들어지지 않는다.
파일 이름 변경하기
import java.io.File;
import java.util.Calendar;
public class Ex006_FileRename {
public static void main(String[] args) {
String appDir = System.getProperty("user.dir");
String pathname = appDir + File.separator + "ex.txt";
File f = new File(pathname);
if(! f.exists()) {
System.out.println(pathname+" - 존재하지 않음...");
System.exit(0);
}
// 확장자(.txt)
String fileExt = pathname.substring(pathname.lastIndexOf("."));
Calendar cal = Calendar.getInstance(); // 현재 시스템의 날짜/시간을 가지고 있음
String newName = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$ts", cal);
// 1$ 는 첫번째 변수,
newName +=System.nanoTime() + fileExt;
// System.out.println(newName);
try {
String newFilename = appDir + File.separator + newName ;
File dest = new File(newFilename);
// 파일 또는 디렉토리 이름 변경
f.renameTo(dest);
System.out.println("파일 이름 변경 완료...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
f.renameto(File dest); 파일 또는 디렉토리 이름을 변경해준다.
확장자가 변경되면 안되므로 substring을 통해 마지막 . 뒤에는 따로 저장해 놓는다.