학원 24일차 - Java

·2021년 7월 10일
0

2021.04.29

문제 풀이 - Q27

package com.test.java.file;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;

public class Ex70_File {
	
	public final static String Q004;
	public final static String Q005;
	public final static String Q008;
	public final static String Q009;
	public final static String Q010;
	
	//생성자(초기화)
	static {
		//문제의 파일 경로가 고정이기 때문에 상수 취급.
		Q004 = "C:\\Users\\82106\\Desktop\\개발\\과제\\2021.04.28 파일, 폴더\\027_파일_디렉토리\\파일_디렉토리_문제\\음악 파일";
		Q005 = "C:\\Users\\82106\\Desktop\\개발\\과제\\2021.04.28 파일, 폴더\\027_파일_디렉토리\\파일_디렉토리_문제\\확장자별 카운트";
		Q008 = "C:\\Users\\82106\\Desktop\\개발\\과제\\2021.04.28 파일, 폴더\\027_파일_디렉토리\\파일_디렉토리_문제\\폴더 삭제\\delete";
		Q009 = "T:\\java\\file\\파일_디렉토리_문제\\크기 정렬";
		Q010 = "T:\\java\\file\\파일_디렉토리_문제\\직원";
	}
	
	public static void main(String[] args) {
		
		//Ex70_File.java
		//q004();
		q005();
		//q008();
		//q009();
		//q010();
		
		//디렉토리 구조 제어 -> 재귀 호출
		
	}//main

	private static void q010() {
		
		File dir = new File(Q010);
		File[] list = dir.listFiles();
		
		for (File file : list) {
			
			if (file.isFile()) {
				
				//아무게_2014__17.txt
				String[] temp = getName(file.getName());
				System.out.println(Arrays.toString(temp));
				
				//D:\class\java\file\직원\아무개\2014\
				File subDir = new File(Q010 + "\\" + temp[0] + "\\" + temp[1]);
				subDir.mkdirs();
				
				//파일 이동
				file.renameTo(new File(subDir.getAbsoluteFile() + "\\" + file.getName()));
				
			}
			
		}
		
	}

	private static String[] getName(String name) {
		
		//아무게_2014__17.txt
		String[] temp = new String[2];
		
		int index = name.indexOf("_");
		temp[0] = name.substring(0, index); //직원명
		
		int index2 = name.indexOf("_", index+1);
		temp[1] = name.substring(index+1, index2); //년도
		
		return temp;
	}

	private static void q009() {
		
		//폴더의 위치와 상관없이 모든 폴더 내의 파일들을 찾아 한번에 크기를 비교하고, 크기가 큰 순으로 정렬하시오.
		File dir = new File(Q009);
		ArrayList<File> flist = new ArrayList<File>();
		
		addFile(dir, flist);
		
		for (File file : flist) {
			
			System.out.printf("%s\t%s\n", file.getName(), file.getAbsolutePath());
			
		}
		
	}
	
	private static void addFile(File dir, ArrayList<File> flist) {
		
		File[] list = dir.listFiles();
		
		for (File file : list) {
			if (file.isFile()) {
				flist.add(file);
			}
		}
		
		for (File sub : list) {
			if (sub.isDirectory()) {
				addFile(sub, flist);
			}
		}
		
	}

	private static void q008() {

		//'delete' 폴더를 삭제하시오.
		// -> 내용물이 있는 폴더는 삭제를 못한다.
		// -> 내용물? -> 파일(빈폴더)
		// -> 재귀구조 ★★★★★

		//모든 파일 지우기
		File dir = new File(Q008);

		deleteFile(dir);

	}

	private static void deleteFile(File dir) {
		
		File[] list = dir.listFiles();
		
		//현재 폴더가 가지는 모든 파일 삭제
		for (File file : list) {
			if (file.isFile()) {
				file.delete();
			}
		}
		
		//자식 폴더로 들어가서 동일한 일을 반복 -> 재귀
		for (File sub : list) {
			if (sub.isDirectory()) {
				deleteFile(sub);
			}
		}
		
		//현재 폴더에는 아무것도 없다
		dir.delete();
	}

	private static void q005() {
		
		//이미지 파일이 확장자별로 있다. 확장자별로 파일이 몇개 있는지 세시오.
		File dir = new File(Q005);
		
		//파일목록
		File[] list = dir.listFiles();
		
		//컬렉션 사용.
		HashMap<String,Integer> count = new HashMap<String,Integer>();
		
		for (File file : list) {
			
			//마우스.gif
			//광.마우스.gif
			//.찾을때 indexOf쓰지말고 lastIndexOf쓰기
			
			//System.out.println(file.getName()); //파일명 확인
			
			//확장자만 뽑아오기
			String ext = file.getName().substring(file.getName().lastIndexOf(".")+1);
			//System.out.println(ext);
			
			//key가 존재하는지 확인
			if (count.containsKey(ext)) {
				
				//put(key, value): value 덮어쓰기(수정), get(key): value 가져오기
				count.put(ext, count.get(ext) + 1); //count = count + 1 누적
			} else {
				count.put(ext, 1); //없으면 처음으로 집어넣는 거니까 (확장자, 1)
			}
			
		}
		
		//출력 -> 새로운 확장자를 집어넣었을 때 값을 지정하지 않으면 반응 X. 
		System.out.printf(".gif: %d개\n", count.get("gif"));
		System.out.printf(".jpg: %d개\n", count.get("jpg"));
		System.out.printf(".png: %d개\n", count.get("png"));
		System.out.printf(".txt: %d개\n", count.get("txt"));
		System.out.println();
		
		//HashMap -> 루프 가능..
		//.keySet() -> key들의 집합.
		Set<String> keys = count.keySet();
		
		for (String key : keys) {
			//System.out.println(key); // key들이 들어있음.
			System.out.printf(".%s: %d개\n", key, count.get(key));
		}
		
	}

	private static void q004() {
		
		//음악 파일이 100개 있다. 파일명 앞에 일련 번호를 붙이시오.
		//listFiles() + renameTo()
		
		File dir = new File(Q004);
		
		//폴더 목록 가져오기
		File[] list = dir.listFiles(); //****
		
		//누적변수
		int temp = 0;

		for (int i=0; i<list.length; i++) {
			
			//System.out.println(list[i].getName());
			
			String filename = list[i].getName(); //파일명을 하나씩 가져와서 변수에 저장
			
			if (filename.toLowerCase().endsWith(".mp3")) {//endWith : 문자열안에 내가 찾는 문자열이 있으면 true, 없으면 false를 반환한다.
				
				//음악 파일만 걸러내기
				//System.out.println(filename);
				
				//파일명에 숫자 붙여주기
				filename = String.format("[%03d]%s", (temp+1), filename); //****
				System.out.println(filename);//바뀐 파일명 
				temp++;
				
				//파일명 바꾸기 -> 원본파일.renameTo(바뀔경로와 이름)
				list[i].renameTo(new File(Q004 + "\\" + filename)); //****
				
			}			
		}
    }
}

파일 입출력

  • 자바 프로그램 -> 데이터 -> 메모리(주기억장치) -> 휘발성(전원이 공급 + 데이터 유지)
  • HDD, SDD, Memory(보조기억장치) -> 영구성(전원 공급 무관 + 데이터 유지)
  • 자바프로그램 <-> (데이터) <-> 보조 기억장치
파일 입출력
  1. 텍스트 입출력
    • 문자(열) 입출력
    • 메모장
    • "홍길동" -> (변환) -> 10101001001001010110 //파일 쓰기
    • 10101001001001010110 -> (변환) -> "홍길동" //파일읽기
  2. 바이너리 입출력
    • 이미지, 동영상, 압축파일, 실행파일 등(텍스트 파일이 아닌 데이터)

  • 인코딩, Encoding
    • 문자 코드를 부호화(0,1)하는 작업
    • 내보내기(쓰기)
  • 디코딩, Decoding
    • 부호 데이터를 문자코드로 변환하는 작업
    • 복호화
    • 가져오기(읽기)
인코딩/디코딩 규칙
  1. ISO-8859-1
  2. EUC_KR
  3. ANSI
  4. UTF-8
  5. UTF-16
  6. MS949

ANSI, ISO-8859-1, EUC_KR, MS949

  1. 영어: 1byte
  2. 한글: 2byte

UTF-8(국제 표준..)

  1. 영어: 1byte
  2. 한글: 3byte

UTF-16

  1. 영어: 2byte
  2. 한글: 2byte

★동일한 방식으로 입출력하자 -> 안그러면 한글이 깨진다.

인코딩 방식 사용 + 파일 입출력


FileOutputStream - 쓰기

public class Ex71_File {

	public static void main(String[] args) {
        
        //쓰기
		// - 바이트 단위 쓰기
		// - 1byte 단위만 저장한다.(한글 불가능)
		
		//파일에 데이터 저장하기(쓰기)
		//1. 스트림 객체 생성하기(스트림 열기) - 빨대를 음료컵에 꽂기
		//2. 스트림 객체 사용하기(쓰기)
		//3. 스트림 객체 닫기(스트림 닫기) - 마무리 작업
		
        //외부환경과 입출력하는 건 예외처리 필수 -> 내가 통제하는 것만으로는 통제할 수 없기 때문
		try {
			
			//쓰기 전용 스트림
			// - FileOutputStream
			// - 파일이 존재하지 않으면 해당 파일을 생성 후 기록한다.
			// - 쓰기 모드
			//	a. 생성 모드, Create Mode(******)
			//		- 기본 모드
			//		- 기존에 있어도 무조건 덮어쓰기를 한다.
			
			//	b. 추가 모드, Append Mode
			//		- 기존에 있는 데이터를 추가로 쓰기를 한다.
			//		- FileOutputStream stream = new FileOutputStream("C:\\class\\java\\file\\data.txt", true);
			//		- true를 쓰면 추가모드, 안쓰거나 false를 쓰면 쓰기 모드
			
			//1.스트림 생성 + 열기
			FileOutputStream stream = new FileOutputStream("C:\\class\\java\\file\\data.txt", true);
			
			//2. 데이터 쓰기
			
			//행 바꾸기
//			stream.write(13); //\r
//			stream.write(10); //\n
//			
//			stream.write(65); //문자 코드 사용 A
//			stream.write(66); //B
//			stream.write(67); //C
			
			
			Scanner scan = new Scanner(System.in);
			
			System.out.print("문장: ");
			String line = scan.nextLine();
			
			for(int i=0; i<line.length(); i++) {
				char c = line.charAt(i);
				
				stream.write(c);//암시적 형변환 char -> int
			}
			stream.write('\r');
			stream.write('\n');
			
			
			//3. 스트림 닫기
			stream.close();
			
			System.out.println("완료");
			
		} catch (Exception e) {
			
			System.out.println(e);
		}
    }
}

FileInputStream - 읽기

public class Ex71_File {

	public static void main(String[] args) {
        
        // 읽기
		// - 바이트 단위 읽기
		// - 1byte 단위만 저장한다.(한글 불가능)
		// - System.in.read()와 비슷
		
		try {
			
			//1. 읽기 전용 스트림 객체 만들기
			FileInputStream stream = new FileInputStream("C:\\class\\java\\file\\data.txt");
			
			//2. 사용
//			int code = stream.read();
//			System.out.println(code);
//
//			code = stream.read();
//			System.out.println(code);
//			
//			code = stream.read();
//			System.out.println(code);
			
			
			//이 루프 암기~~~!!!★★★
			int code = -1;
			
			while((code = stream.read()) != -1){ //-1 : 더이상 돌려줄 값이 없을때 돌려주는 값, 문자코드는 0부터 값이 할당되어 있음
				System.out.print((char)code);
			}
			
			//3. 닫기
			stream.close();
			
		} catch (Exception e) {
			System.out.println(e);
		}
    }
}

image-20210429210818515


FileWriter - 쓰기

public class Ex71_File {

	public static void main(String[] args) {
        
        //쓰기
		// - 문자 단위 쓰기 (2byte)
		// - 한글 쓰기 가능
		
		try {
			
			//FileOutputStream -> FileWriter
			FileWriter writer = new FileWriter("C:\\class\\java\\file\\data2.txt", true); //이어쓰기 모드 
			
//			writer.write("홍길동");
//			writer.write("\r\n"); //줄바꿈
//			writer.write("안녕하세요.");
			
			Scanner scan = new Scanner(System.in);
			
			System.out.print("입력: ");
			String line = scan.nextLine();
			
			writer.write(line);
			writer.write("\r\n");
			
			writer.close();
			
			System.out.println("완료");
			
		} catch (Exception e) {
			System.out.println(e);
		}
    }
}

FileReader - 읽기

public class Ex71_File {

	public static void main(String[] args) {
        
        // 읽기
		// - 문자 단위 읽기(2byte)
		// - 한글 읽기 가능
		
		try {
			//FileOutputStream -> FileWriter
			//FileInputStream -> FileReader
			
			FileReader reader = new FileReader("C:\\class\\java\\file\\data2.txt");
			
//			int code = reader.read();
//			System.out.println((char)code);
//			
//			code = reader.read();
//			System.out.println((char)code);
//			
//			code = reader.read();
//			System.out.println((char)code);
			
			
			//루프
			int code = -1;
			
			while ((code = reader.read()) != -1) {
				System.out.print((char)code);
			}
			
			reader.close();
			
		} catch (Exception e) {
			System.out.println(e);
		}
    }
}
public class Ex71_File {

	public static void main(String[] args) {
        
        // 읽기 - 자바파일 읽어오기
		try {
			
			FileReader reader = new FileReader("C:\\class\\java\\JavaTest\\src\\com\\test\\java\\file\\Ex71_File.java");
			
			int code = -1;
			
			while ((code = reader.read()) != -1) {
				System.out.print((char)code);
			}
			
			reader.close();
			
		} catch (Exception e) {
			System.out.println(e);
		}
    }
}

BufferedWriter - 쓰기

public class Ex71_File {

	public static void main(String[] args) {
        
        // 쓰기
		// FileOutputStream -> FileWriter -> BufferedWriter
		// FileInputStream -> FileReader -> BufferedReader
		
		try {
			
			//Wrapper Class -> 사용법 향상, 기능 추가 등등..하기 위해 랩핑..
			BufferedWriter writer = new BufferedWriter(new FileWriter("C:\\class\\java\\file\\data3.txt"));
			
			writer.write("안녕하세요");
			writer.newLine();
			
			writer.write("홍길동입니다.");
			writer.newLine();
			
			writer.close();
			
		} catch (Exception e) {
			
			System.out.println(e);
		}
    }
}

BufferedReader - 읽기

public class Ex71_File {

	public static void main(String[] args) {
        
        // 읽기
		try {
            
			//키보드 읽기
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			
			//파일 읽기
			BufferedReader reader2 = new BufferedReader(new FileReader("C:\\class\\java\\file\\data3.txt")); 
			
			String line = reader2.readLine(); //라인단위로 읽음.
			System.out.println(line);
			
			reader.close();
			reader2.close();
			
		} catch (Exception e) {
			System.out.println(e);
		}
    }
}
public class Ex71_File {

    public static void main(String[] args) {
        
        try {

            BufferedReader reader = new BufferedReader(new FileReader("C:\\class\\java\\JavaTest\\src\\com\\test\\java\\file\\Ex71_File.java")); 

            String line = "";
            int n = 1;

            while((line = reader.readLine()) != null) {
                System.out.printf("%03d: %s\n", n, line);
                n++;
            }

            reader.close();

        } catch (Exception e) {

            System.out.println(e);
        }
    }
}

파일 입출력 기반 예제

  • 입력한 정보가 사라지지 않게 데이터를 지속적으로 관리하기 .
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class Ex72_File {
	
    //공용으로 쓰이는 자원들
	private static Scanner scan;
	private final static String DATA; //경로는 고정이기때문에 상수로 지정
	
	static {
		
		scan = new Scanner(System.in);
		DATA = "dat\\student.dat"; //상대 경로(.\\dat\\student.dat) -> .은 현재 디렉토리(현재 폴더)
		//DATA = "T:\\java\\JavaTest\\dat\\student.dat" //절대 경로
		
	}
	
	public static void main(String[] args) {
		//경로 확인 -> 파일 확인
		//File file = new File(DATA);
		//System.out.println(file.exists());
		
		//학생 정보 관리
		// - 순수 파일 입출력 기반
		// - 데이터를 지속적으로 관리를 하기 위해(****) -> 데이터 구조 설계(저장할 파일생성 + 저장할 구조(패턴))를 해야함.
        //		2.파일생성
		//		- JavaTest > dat 폴더 생성
		//			- student.dat 파일 생성
		
		// 1. 데이터의 정의
		//		- 학생 정보?
		//			- 이름, 나이, 국어, 영어, 수학 
        //			저장 구조 => CSV(Comma-Separated values) 콤마로 값을 구분하는 표기법
		//			- 홍길동,14,100,90,80
		
		//데이터 조작 -> CRUD -> Create, Read, Update, Delete
		
		//기능
		// - 학생 정보 저장하기(C)
		// - 학생 정보 목록(R)
		// - 학생 정보 삭제하기(D)
		
		System.out.println("[학생 정보 관리]");
		
		boolean loop = true;//사용자가 프로그램 사용을 몇 회 사용할지 모르기 때문에 무한 루프.
		
		while (loop) {
			
			//메뉴 출력
			//선택
			//분기
			
			String seq = menu();//선택한 번호
			
			if (seq.equals("1")) {
				add();
			} else if (seq.equals("2")) {
				list();
			} else if (seq.equals("3")) {
				delete();
			} else {
				loop = false;
			}
		}
		System.out.println("프로그램 종료");
	}//main
	
    //화면이 넘어가지 않도록 일시정지.
	private static void pause() {
		System.out.println("엔터를 누르시면 다음으로 진행합니다.");
		scan.nextLine();//Block
	}
	
	private static void delete() {
		
		//*** 중요 ***
		System.out.println("[학생 삭제]");
		
		try {
            
			//학생 명단 출력 -> 삭제할 학생 선택
			BufferedReader reader = new BufferedReader(new FileReader(DATA));
			
			String line = ""; //이름 저장할 변수
			
			System.out.println("[이름]");
			
			while ((line = reader.readLine()) != null) {
				
				String[] temp = line.split(",");
				System.out.printf("%s\n", temp[0]);
				
			}
			
			reader.close();
			
			System.out.println("삭제할 학생을 선택하세요.");
			System.out.print("선택(이름): ");
            
			//삭제할 학생 선택
			String name = scan.nextLine(); 
			
            //선택한 학생 지우기
            //수정 : 원본 -> 원본에서 지울 내용을 빼고 읽음 -> 기존의 원본은 지움 -> 수정된 내용으로 전체를 다시 덮어씀.
			reader = new BufferedReader(new FileReader(DATA));
			
			String result = "";//누적 변수
			line = "";
			
			while ((line = reader.readLine()) != null) {
				
				String[] temp = line.split(",");
				
				if (!temp[0].equals(name)) { //이름 비교 
					result += line + "\r\n"; //읽을때 엔터가 사라졌기 때문에 엔터를 넣어준다.
				}
			}
			
			reader.close();
			
			//덮어쓰기
			BufferedWriter writer = new BufferedWriter(new FileWriter(DATA));
			writer.write(result);
			writer.close();
			
		} catch (Exception e) {
			System.out.println(e);
		}
		
		pause();
	}

	private static void list() {
		
		System.out.println("[학생 목록]");
		
		try {
			//읽기
			BufferedReader reader = new BufferedReader(new FileReader(DATA));
			
			String line = "";
			
			System.out.println("[이름]\t[나이]\t[국어]\t[영어]\t[수학]");
			
			while ((line = reader.readLine()) != null) {
				
				//학생 1명씩(1라인씩) -> 모든 학생 탐색
				//홍길동,12,100,90,80
				//System.out.println(line);
				
				String[] temp = line.split(","); //.split() -> ,를 기준으로 쪼갬
				System.out.printf("%s\t%5s\t%5s\t%5s\t%5s\n"
									, temp[0]
									, temp[1]
									, temp[2]
									, temp[3]
									, temp[4]);
				
			}
			
			reader.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		pause();
	}

	private static void add() { //추가
		
		Util util = new Util(); //입력받는 코드를 따로 클래스로 만들어둠.
		
		System.out.println("[학생 추가]");
		
		System.out.print("이름: ");
		String name = scan.nextLine();
		
		String age = util.get("나이");
		String kor = util.get("국어");
		String eng = util.get("영어");
		String math = util.get("수학");
		
		try {
			//쓰기(입력)
			BufferedWriter writer = new BufferedWriter(new FileWriter(DATA, true));
			
			//홍길동,12,100,90,80
			writer.write(String.format("%s,%s,%s,%s,%s\n", name, age, kor, eng, math));
			
			writer.close();
			
		} catch (IOException e) {
			e.printStackTrace(); //예외 출력해주는 메소드
		}
				
		pause();
	}

	private static String menu() {
		
		System.out.println("===================");
		System.out.println("1. 학생 정보 등록하기");
		System.out.println("2. 학생 정보 목록보기");
		System.out.println("3. 학생 정보 삭제하기");
		System.out.println("4. 종료");
		System.out.println("===================");
		System.out.print("선택: ");
		
		String sel = scan.nextLine(); //번호 선택
		
		return sel;//선택한 번호 리턴
	}

}
  • 자주 쓰는 기능 클래스로 분리
import java.util.Scanner;

public class Util {
	
	public String get(String label) {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.print(label + ": ");
		
		return scan.nextLine();
	}

}
profile
모르면 괴롭고 알면 즐겁다.

0개의 댓글