-
입출력 스트림(6) / PrintStream프로그래밍/JAVA 자바 2021. 8. 24.반응형
package ioEx3; import java.io.PrintStream; public class Ex010_PrintStream_File { public static void main(String[] args) { /* * PrintStream 클래스 * System.out은 PrintStream 객체 * 다른 출력 스트림의 기능을 추가하여 다양한 데이터 값의 표현을 편리하게 출력 * IOException이 발생하지 않는다. * 자동으로 flush()가 되도록 생성 가능. */ String name = "홍길동"; int kor = 80; int eng = 90; int mat = 100; try(PrintStream ps = new PrintStream("test.txt")) { //텍스트 파일에 내용 저장 ps.println(name+"\t"+kor+"\t"+eng+"\t"+mat); ps.printf("%10s %5d %5d %5d", name, kor, eng, mat); ps.flush(); // 안해도 되는데 확실히 저장 시키기 위한다면 사용 System.out.println("파일 저장 완료"); } catch (Exception e) { e.printStackTrace(); } } }
- 그동안 출력을 위해서 System.out.println(); 을 사용 했었는데 이걸 객체로 만들 수 있다.
- System.out은 PrintStream의 객체이다
- PrintStream ps = new PrintStream("test.txt") 이렇게 하면 test.txt를 참조하는 객체 ps를 만들 수 있다.
- 출력할때 ps.println()으로 가능하다.
package ioEx3; import java.io.BufferedReader; import java.io.FileReader; import java.io.PrintStream; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; /* * user1.txt 파일과 user2.txt 파일을 이용하여 user3.txt 파일을 작성한다. * * user1.txt 파일에 없는 학번이 user2.txt 파일에 존재하는 경우 user3.txt 파일에 저장하지 않는다. * * user2.txt에는 학번과 과목별 점수가 무작위로 존재한다. * * user2.txt 파일에 과목 점수가 없는 것은 공백(탭)으로 처리한다. * * user3.txt 파일 출력은 다음과 같은 형식으로 한다. * 학번 이름 국어 영어 수학 */ public class Ex011_userEx { public static void main(String[] args) { // TODO Auto-generated method stub User ob = new User(); ob.loadFile1(); ob.loadFile2(); ob.saveFile(); System.out.println("파일 저장 완료"); } } class UserVO { 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; } @Override public String toString() { // TODO Auto-generated method stub String s = name+"\t"; s+= kor == null ? "\t" : kor+"\t"; s+= eng == null ? "\t" : eng+"\t"; s+= mat == null ? "\t" : mat+"\t"; return s; } } class User{ /* * TreeMap = 키로 정렬하여 저장 * private Map<String, UserVO> map = new TreeMap<>(); * * LinkedHashMap = 등록된 순서로 저장 * private Map<String, UserVO> map = new LinkedHashMap<String, UserVO>(); * * HashMap = 등록 순서는 랜덤 * private Map<String, UserVO> map = new HashMap<String, UserVO>(); */ private Map<String, UserVO> map = new TreeMap<>(); private String pathname1 = "user1.txt"; private String pathname2 = "user2.txt"; private String pathname3 = "user3.txt"; public void loadFile1() { try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) { String s; while((s = br.readLine()) != null) { String[] ss = s.split(","); if(ss.length != 2) { //유저1 텍본 파일에서 콤마로 나누고 나면 2개여야 하는데 혹시 아니면 처리 안한다. continue; } UserVO vo = new UserVO(); vo.setName(ss[1]); // 국영수는 null map.put(ss[0], vo); } } catch (Exception e) { e.printStackTrace(); } } public void loadFile2() { try(BufferedReader br = new BufferedReader(new FileReader(pathname2))) { String s; while((s = br.readLine()) != null) { String [] ss = s.split(","); if(ss.length<2) { continue; } UserVO vo = map.get(ss[0]); // 학번의 데이터를 Map에서 가져오기 if(vo == null) { continue; // 데이터가 없으면 } int n; for(int i=1; i<ss.length; i++) { String[] c = ss[i].split(":"); n = Integer.parseInt(c[1]); if(c[0].equals("kor")) { vo.setKor(n); } else if(c[0].equals("eng")) { vo.setEng(n); } else if(c[0].equals("mat")) { vo.setMat(n); } } } } catch (Exception e) { e.printStackTrace(); } } public void saveFile() { try(PrintStream ps = new PrintStream(pathname3)) { Iterator<String> it = map.keySet().iterator(); while(it.hasNext()) { String hak = it.next(); UserVO vo = map.get(hak); ps.println(hak + "\t" + vo); } } catch (Exception e) { e.printStackTrace(); } } }
- UserVO 클래스는 한 사람분의 정보를 담는다.
- private 변수니까 getter, setter를 만들어 준다. (게터세터로 수정 및 불러오기 해야함)
- toString()의 오버라이드(재정의)을 한 이유 = 출력할때 보다 편하게 하기 위해서
(User 클래스)
- User 클래스 실질적인 작업 공간
- 값들을 저장해야하니까 Map을 이용하는데 Map에서 키 값(학번) 순서로 저장하기 위해서 TreeMap사용
(제네릭 형식은 <String, UserVO>)
- user1~3 텍본 파일들을 사용하기 위해 미리 변수 지정
- lodaFile1() 함수는 user1텍본 파일 불러오기 위함
- BufferedReader와 readLine()을 이용해서 파일 내용 읽어서 ,콤마 단위로 자르고 UserVO 객체인 vo에 저장
- vo에 setName으로 이름 먼저 저장하고
- map에는 값 들을 넣어주는데 처음에 만든 형식대로 처음엔 String형태의 학번이고 두번째는 UserVO를 넣어야 하니까 만들어둔 UserVO의 객체 vo를 넣어주자.
- 중간에 if문은 콤마로 나누었을때 2개로 나뉘어서 값은 2개가 되야하는데 그러지 않을경우를 대비해서 만든것
- loadFile2() 함수는 user2.txt의 내용을 가져오기 위함.
- 처음에 먼저 user2의 내용을 가져와서 ,콤마 순으로 나눔 (학번과, 나머지 데이터들로 나뉨)
- 그럼 배열 0번째 인덱스에는 학번이 들어가있는 점을 이용해서 아까 저장했던 map 데이터에 지금 가져온 학번을 UserVO의 객체 vo에 넣는다.
- UserVO vo = map.get(ss[0]); 를 이용해서 안에 데이터가 있는지 확인이 되면
- for문을 이용해서 ":"를 단위로 스플릿을 해주고 값을 넣어준다.
- saveFIle()는 위에서 한 작업들을 새로운 텍스트 파일에 저장하는 것
- 파일 저장을 위해 PrintStream 을 이용한다.
- map에 담겨있는 데이터들을 가져오기 위해 Iterator를 사용
- 메인에서 함수 호출로 프로그램 실행
package ioEx3; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Ex012_PassUser_Answer { public static void main(String[] args) { UserPass2 p = new UserPass2(); p.loadFile(); p.saveFile(); System.out.println("합격자 정보 저장 완료"); } } class UserDTO2 { private String name; private int kor; private int eng; private int mat; private int tot; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getKor() { return kor; } public void setKor(int kor) { this.kor = kor; } public int getEng() { return eng; } public void setEng(int eng) { this.eng = eng; } public int getMat() { return mat; } public void setMat(int mat) { this.mat = mat; } public int getTot() { tot = kor + eng + mat; return tot; } } class UserPass2 { private String pathname1 = "user.txt"; private String pathname2 = "pass.txt"; private List<UserDTO2> list = new ArrayList<UserDTO2>(); public void loadFile() { try(BufferedReader br = new BufferedReader(new FileReader(pathname1))) { String s; int k,e,m; while((s=br.readLine()) != null) { String[]ss = s.split(","); if(ss.length != 4) { continue; } k = Integer.parseInt(ss[1]); e = Integer.parseInt(ss[2]); m = Integer.parseInt(ss[3]); if(k>=40 && e>=40 && m>=40 && (k+e+m)/3 >= 60) { UserDTO2 dto = new UserDTO2(); dto.setName(ss[0]); dto.setKor(k); dto.setEng(e); dto.setMat(m); list.add(dto); } } } catch (NumberFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void saveFile() { // 총점 내림차순 정렬 Comparator<UserDTO2> comp = new Comparator<UserDTO2>() { @Override public int compare(UserDTO2 o1, UserDTO2 o2) { return -(o1.getTot() - o2.getTot()); } }; Collections.sort(list,comp); // 파일에 저장 try(PrintStream ps = new PrintStream(pathname2)) { for(UserDTO2 dto : list) { ps.print(dto.getName() + ","); ps.print(dto.getKor() + ","); ps.print(dto.getEng() + ","); ps.print(dto.getMat() + "\n"); } } catch (Exception e) { e.printStackTrace(); } } }
user.txt 파일을 읽어서 합격자만 pass.txt에 저장하는 프로그램
user.txt = 이름,국,영,수 순으로 저장
pass.txt = 이름,국,영,수 순으로 저장
*
세과목 모두 40점 이상이고 평균이 60점 이상인 경우만 합격자
pass.txt에 저장할 때는 총점 내림차순으로 저장
UserDTO 만들고, UserPass라는 클래스 만들어서 작성- UserPass2 클래스
- 값들 저장할 List생성 및 객체에 ArryList부여
- loadFile() 함수는 user.txt의 정보를 읽어옴.
- 따로 개별 함수 k,e,m을 만들어서 요구 조건을 해결한다.
- 그리고 적합한 조건들의 값만 UserDTO에 전송 후
- list에도 추가해준다.
- saveFile() 클래스
- 내림차순 정렬을 위해 Comparator생성
- 오버라이드로 내림차순으로 정렬 해준다.
- Collections.sort로 정렬 마무리
- 그리고 정렬된 애들을 새로운 파일에 써준다 PrintStream 이용
- for문으로 객체 돌려가면서 한 사람분의 데이터 값을 반복해서 넣어준다.
반응형'프로그래밍 > JAVA 자바' 카테고리의 다른 글
자바로 DB 연동해서 작업하기 Statement 활용 예제 (0) 2021.08.27 자바로 오라클 DB 간섭하기 / Statement / ResultSet (0) 2021.08.26 입출력 스트림(5) / File (0) 2021.08.24 입출력 스트림(4) / FileCopy / FileWriter / FileReader (0) 2021.08.24 입출력 스트림(2) / Reader / 예제 소스 분석 (0) 2021.08.24