ejyoo's 개발 노트

JAVA IO - File Class 2 - 파일 존재 여부에 따라 새로 생성하기 / 윈도우 cmd - dir 명령어 구현하기(작성중) 본문

BackEnd/Java

JAVA IO - File Class 2 - 파일 존재 여부에 따라 새로 생성하기 / 윈도우 cmd - dir 명령어 구현하기(작성중)

ejyoovV 2021. 3. 20. 15:27

파일 클래스를 활용해서

 

파일 존재 여부를 판단하고 있으면 생성하지 않고 없으면 새로 생성하는 기능과

 

윈도우 cmd 명령어 중 dir 명령어(파일목록을 보여주는) 기능을

Java 코드로 작성해보았습니다.

 

먼저 파일을 새로 생성하는 기능부터 살펴보겠습니다.


파일을 생성하기 위해서는

어디에 어떤 파일을 생성할지에 대한 파일 객체를 생성해야 합니다.

그리고 파일이 존재하는지 존재하지 않는지에 대한 판단은 exists() 메서드를 사용합니다.

exist() 도 리턴타입이 boolean 입니다.

또한 파일을 생성하려면 createNewFile() 메서드를 사용합니다.

createNewFile()은 리턴타입이 boolean 입니다.

createNewFile()로 한것은 그냥 파일만 생성한 것일 뿐 내용을 담진 않습니다.(Size : 0)

File 객체는 이렇게 생성만 할 수 있고 내용을 수정하는 것은 없습니다.

핸들링만 가능합니다 즉 필요한 정보만 얻을 수 있습니다.

실제 파일에 원하는 데이터를 작업하는 것은 스트림을 사용합니다.


다음 코드는 File에 담겨져있는 목록들이 파일인지 디렉토리인지 구분하는 코드입니다.

 

코드를 살펴보겠습니다.

File 객체는 디렉토리, 파일목록을 담을 수 있다고 했습니다.

여기에서는 File에서 설정한 경로 내에 있는 파일 목록을 가져와서

파일인지 디렉토리인지 확인하여 파일이면 파일 디렉토리면 디렉토리를 출력하는 코드입니다.

 

디렉토리가 담겨져 있는 File 객체를 통해 listFiles() 메서드를 호출할 수 있는데,

이때 반환값이 File 배열입니다. 이 File배열은 'f3'변수에 들어있는 파일 객체의 디렉토리 또는 파일과 같은 정보를 가지고 있습니다.

이렇게 받아온 File 배열을 가지고 하나씩 비교하면서

파일인지 확인하고자 하는 경우에는 isFile() 메서드 사용

디렉토리인지 확인하고자 하는 경우에는 isDirectory() 메서드를 사용합니다.

출력값은 아래와 같습니다.


여기서부터는 MAC 환경에서 포스팅을 이어가겠습니다.

맥 환경도 윈도우 환경과 동일하게 코드는 작성되었고 다만 다른건 경로입니다.

 

이어서 포스팅 작성을 시작하겠습니다.

아래의 코드는 파일 이름만 가져와도 될 때 사용하는 코드입니다.

list() 메서드는 반환값이 File배열이 아닌 String배열입니다.

이 코드는 위와 다르게 이름만 가져오게되며, 파일인지 디렉토리인지 확인할 수 없습니다.

 

파일 이름만 갖고오게되어 파일 객체를 들고오는 것은 아니므로

list() 메서드로 할 수 있는 일은 파일 목록만 사용할 수 있습니다.

파일 이름만 필요한 기능인 경우 굳이 파일 배열로 받는 listFiles()보다는 list()를 사용하여 구현합니다.

반대로 파일에 대한 세부 내용을 파악하고 싶은 경우, list()보다는 listFiles()가 적절합니다.

 

상황에 따라 필요한 코드를 작성하면 좋을 것 같습니다.

코드 실행 결과를 확인해보겠습니다.


다음은 윈도우 cmd에서 명령어 dir을 사용했을 때 나오는 파일 목록을 JAVA 콘솔로 구현하려 합니다.

listFiles()라는 메서드가 제공하는 기능에서 기능을 조금 더해 구현한 코드라고 생각하면 되겠습니다.

 

코드를 먼저 보도록 하겠습니다.

먼저 목록을 확인할 파일 객체를 생성한 뒤 displayFileList() 메서드에 파일객체를 담아 호출합니다.

이 파일 객체가 있어야 핸들링을 할 수 있습니다.

 

 

파라미터로 받은 파일 객체를 가지고 파일 객체의 절대 디렉토리 경로를 추출합니다.

파일 객체 디렉토리 내 파일 목록을 가져오기 위해

파일목록을 가져오는 listFiles() 메서드를 사용하여 파일배열로 목록을 가져옵니다.

다음 코드는 현재 파일객체 디렉토리에 또 다른 하위파일이 있을 수 있기 때문에 

하위 디렉토리에 대한 인덱스 값을 저장하기 위한 ArrayList를 생성합니다.

파일의 시간을 가져오기 위해 (원하는 날짜 포맷을 가져오기 위해)

SimpleDateFormat을 사용합니다. 

설정한 포맷 방식은 년도 4자리-월-일 [오전|오후] 시간:분 형식입니다.

그 다음 for문을 돌려서 files 내에 있는 실제 파일 정보를 얻어오게 됩니다.(파일리스트 순회)

꺼낼 때, 파일인지 디렉토리인지 만 출력하는 것이 아닌

다른 의미있는 데이터를 추출하기 위해 File객체 내에 있는 다른 메서드를 사용합니다.

 

일단 기본적으로 파일의 속성 정보를 읽어오는 attr 변수를 생성합니다. 이 변수에는 파일 객체에 있는 리스트 목록이 읽기,쓰기,히든 상태인지 디렉토리인지 표시합니다.

파일의 용량을 담을 size 변수를 생성합니다. 이 변수에는 파일이 가지고 있는 사이즈를 출력합니다.(length메서드)

 

그 다음 파일객체 리스트가 디렉토리인지 파일인지 구분하고 (isDirectory() 메서드 사용) 디렉토리인 경우

attr 변수에 <DIR> 이라고 디렉토리 의미를 표시하고 이 디렉토리를 파일 배열의 인덱스(i값) 을 subDirList 에 저장합니다.

이렇게 저장된 subDirList는 나중에 인덱스 값을 가지고 해당 디렉토리 정보를 갖고올 수 있게됩니다.(임시저장 의미로)

그 다음 파일 배열 객체에 인덱스 값을 사용하면 그 파일 객체를 바로 얻어올 수 있습니다.

 

디렉토리가 아닌 경우는 파일이라는 의미입니다.

파일 내에 있는 정보 출력은 다음과 같습니다.

length() : 파일 사이즈 (byte단위로 가져옴)

canRead() : 읽기 가능한지

canWrite() : 쓰기 가능한지

isHidden() : 숨김 파일인지

 

canRead(), canWrite(), isHidden() 의 결과값은 윈도우라는 운영체제에서 파일을 제어하는 것입니다.

그말은 즉 자바 가지고 파일 리소스 접근할 떄, 권한이 없는 파일에 접근할 수 없는 의미가 됩니다.

그래서 윈도우가 파일제어하는 정보들을 canRead(), canWrite(), isHidden() 메서드를 가지고 가져올 수 있는 것입니다.

 

이 파일 제어 정보를 가지고 자바에서 처리를 하는데, 이때 삼항 연산자를 사용하였습니다.

읽기 가능한지 알기위해서 canRead() 메서드를 호출하고 canRead()의 반환값은 boolean 입니다.

읽기가 가능한 상태이면 true -> attr = "R" / 읽기 가능한 상태가 아니면 false -> attr = " ";가 됩니다.

 

이렇게 해서 적절하게 메서드를 호출해여

파일인 경우 여러가지 메서드를 사용하여 파일의 사이즈, 읽기권한인지 쓰기권한인지 숨김파일인지 표시합니다.

이제 준비된 정보를 가지고 출력을 하게 되는데,

다양한 포맷 방식과 정렬 방식을 표시하기 위해 printf를 사용하여 

포맷 방식을 표시합니다.

이때 포맷 방식 앞에 -가 존재하면 좌측정렬이고 +이면 우측 정렬입니다.

%5s 의 의미는 문자열을 5자리만 출력하겠다 라고 제어하는 것입니다.

시간 출력 시 사이즈를 제한하지 않은 이유는 

처음에 시간 객체 호출할 떄, 포맷을 설정하였기 때문에 자리수는 동일하여 굳이 사이즈를 설정하지 않아도 되기 때문에 사용하지 않은것입니다.

getName() 을 사용하여 가져온 파일 이름은 정확하 사이즈를 알 수 없으므로 %s라고 하였습니다.

파일 목록에 대한 처리를 모두 하고 나면

파일이 몇개이고 디렉토리가 몇개인지 개수를 출력하는 코드입니다.

이제 남은 작업은 하위 디렉토리에 대한 처리입니다.

하위 디렉토리는 하위 디렉토리 내 파일이 존재할 수 있으므로 목록을 출력해야 합니다.

 

그래서 현재 메서드를 다시 호출해야 하는 상황이 발생합니다.(재귀호출 - 현재 자기 메서드를 호출하는 것)

파일인지 디렉토리인지 검사할 때 디렉토리이면 subDirList에 디렉토리 인덱스 값을 저장했었습니다.

 

하위 디렉토리에 대한 File객체를 다시 넣어 재귀 호출을 하면 하위 목록까지 출력할 수 있는 코드가 완성됩니다.

 

이 코드로 인해서 File 클래스 내에 제공하는 listFiles() 메서드는

파일 객체 생성할 때, 즉 new File('파일 또는 디렉토리 경로') 에서 들어가는 '파일 또는 디렉토리 경로'를 기본으로 하는 파일 객체를 반환하는 것으로 생각할 수 있게 됩니다.

 

위의 코드를 작성하고 난 뒤 출력 결과는 아래와 같습니다.