본문 바로가기
프로젝트/자바로 간단하게 프로그래밍!

[파일]선택한 폴더 내의 파일들의 이름을 일괄 변경하는 프로그램

by 으노으뇨 2023. 8. 22.
728x90
반응형
SMALL

안녕하세요! 

이번엔 특정 폴더 내부의 파일들의 이름을 일괄 변경하는 프로그램을 만들어 보겠습니다.!!

이전 포스팅으로는 특정폴더내의 폴더들의 내부 파일들을 모두 상위 폴더로 이동하는 프로그램을 만들었었습니다

https://uno-kim.tistory.com/390

 

[파일]특정 폴더 하위 폴더의 파일들을 이동시키는 프로그램

안녕하세요! 그 동안 제가 취미(??) 생활로 이것저것 수집을 좋아해서 수집활동을 꾸준히 하고있는데 웹상에서 떠돌고있는 폴더들을 크롤링 또는 다운로드를 특정 폴더에 받게끔하면 폴더안에

uno-kim.tistory.com

이번엔 그와 조금 연결(??) 되는 프로그램인 

폴더 내의 파일명을 일괄 변경 프로그램

을 만들어보겠습니다! 


요구사항

현재 IT기업에서 근무하고 있는 A씨는 취미생활로 자료들을 수집하는데

수집하는 자료는 항상 (폴더 -> 파일 )이렇게 폴더로 한번 바인딩되어있어서 30개의 자료를 수집했다고 하면

30개의 파일명이 [qwe@필요한 파일명.bmp] 이렇게 저장되고 수집이 된다.

매번 손으로 하나하나 구분자 @를 기준으로 이후 파일명을 가져오는데 시간을 많이 소비하고 있다.

이에 따라 자동화를 하고자한다.


간단한 설계
  1. 폴더내의 파일들을 읽는다.
  2. 폴더 내에 @를 가지고 있는 파일들을 대상으로 이름을 변경한다.
  3. 만약 @외에도 다른 구분자가 있다면 그 구분자도 이후로 추가될수있게끔 확장가능하게 설계한다.

실행결과

프로그래밍 상세

디렉터리 체크

	/** 파일선택하는 이벤트 */
	public static void main(String[] args) {
		JFrame frame = new JFrame("파일 이름 변경 프로그램");
		JButton button = new JButton("폴더 선택");
		button.addActionListener(e -> {
        	/** 파일선택!! */
			JFileChooser fileChooser = new JFileChooser();
			fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			int option = fileChooser.showOpenDialog(frame);
            if (option == JFileChooser.APPROVE_OPTION) {
                File folder = fileChooser.getSelectedFile();
                int confirmResult = JOptionPane.showConfirmDialog(frame,"변환하겠습니까?","확인",
                        JOptionPane.YES_NO_OPTION
                );
                if (confirmResult == JOptionPane.YES_OPTION) {
                    checkFilesAndRenameFiles(folder);
                }
		});
		frame.getContentPane().add(button);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
	/** 중간 생략*/
    private static boolean checkDirectory(File file) {
		return (file != null && file.isDirectory());
	}

디렉터리 체크하는 방법은 J프레임으로 선택한 폴더를 사용했다.

이때 중요한건 fileChooser객체에 fileSelectionMode로 [디렉터리 온리]를 사용한것이다. 안그럼 계속 파일하나씩 선택해야하는 불상사가 발생할 것이다.

그리고 선택을 완료하면 해당 옵션객체 값이 0로 바뀌는데 이 값이 디렉터리가 선택되었다는 것을 의미한다.

그렇게 변경된것을 인지한뒤 바로 확인 창을 띄워 유저에게 ["변환하겠습니까?"] 라고 확인창을 띄워 확인을 누르면 그 값에 따라 바로 변환 함수를 실행시킨다.

파일명중 구분자 확인 함수

/* 전역변수로 구분자와 구분자별 동작함수를 매핑시키는 Map 객체선언*/
private static HashMap<String, Function<String, String>> functionMap = new HashMap<>();
private static void renameFile(File toFolder, File file) {
    if (file.isFile()) {
        String originFileName = file.getName();
        String newFilename = originFileName;
        Set<String> separators = functionMap.keySet();
        for (String separator : separators) {
            if (newFilename.contains(separator)) {
                newFilename = functionMap.get(separator).apply(newFilename);
            }
        }
      /* 파일 명 변경하는 함수부*/
	rename(toFolder, file, newFilename);
    }
}
private static void setFunctionMap() {
    functionMap.put("@", filename -> filename.substring(filename.lastIndexOf("@") + 1));
    functionMap.put("%", filename -> filename.substring(filename.indexOf("%") + 1, filename.lastIndexOf(".")));
}

여기서 주의 깊게 봐야할것은 전역변수로 Map객체를 생성하는데 이것을 구분자 = 함수 이렇게 매핑을 시킨것이다.

따라서 구분자 "@" 가 있으면 "@"와 매핑된 함수를 실행하고 "%"면 "%"와 매핑된 함수를 실행시킨다.

그리고 파일명이 해당 구분자 들이 포함되어있는지 확인하는 방법으로는 전역변수 "functionMap"의 KeySet을 통해 확인할 수 있다.

따라서 파일 명을 For Roop를 통해 돌면서 해당 구분자가 있는지 확인하며 파일명을 변경한다.

파일명 변경하는 함수부

private static void rename(File toFolder, File file, String newFilename) {
    File newFile = new File(toFolder, newFilename);
    try {
        Files.move(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "파일 이름 변경 중 오류가 발생했습니다.");
        return;
    }
}

이동할 원본 파일의 경로와 이동할 파일의 경로를 나타낸다. 

그리고 StandardCopyOption.REPLACE_EXISTING 옵션으로 대상파일이 이미 존재하면 덮어쓰는 것으로 설정했다. 이는 변경하는 듯한 효과를 줍니다.


이것으로 파일 명을 일괄 변경시키는 프로그램을 만들어보았습니다.

다음 포스트로는 이전의 포스트로 소개드렸던 "폴더 일괄 이동 프로그램" 과 기능을 합쳐서

해당 공정이 모두 자동화 되도록 소스를 합쳐 프로그램을 만들어보고 소개해드리겟습니다.

긴 글 읽어주셔서 감사합니다!

728x90
반응형
LIST

댓글