Spring 앱을 실행시킬 때 데이터베이스에 테스트데이터를 넣어놓기로 했다(스프링 시작시 로직을 실행하는 방법 참고하기). 1,000,000 개의 데이터를 넣었는데 시간이 너무 오래걸려서 보는 재미라도 있으면 좋겠다 라고 생각했다. 그래서 콘솔에 작업률 애니메이션을 넣어보기로 하였다.
(사실 데이터를 하나씩 넣지 않고, update 를 이용한 복사 쿼리를 날리거나 아예 saveAll 을 이용해 한 번에 저장하면 데이터를 훨씬 빠르게 넣을 수 있는데 딴짓엔 이유가 없다.)
결론: '\r' 을 이용해 출력을 덮어씌웠다.
\r 은 캐리지 리턴(CR) 이라는 탈출문자(escape char) 이다. 아마 C 를 공부했던 사람은 한번쯤 봤을 것이다.
파일이나 콘솔에 글을 출력하면 마우스(캐럿이라고도 함) 위치를 기준으로 출력이 되는데, '\r' 은 커서를 해당 라인의 맨 앞으로 옮겨준다. 또한, 표준출력에서 커서위치에 이미 글자가 있으면 그냥 덮어 씌워버린다.
예를들어,
System.out.print("123");
System.out.print("\r");
System.out.print("456");
을 실행하면 456
만 출력된다. 123
을 출력한 뒤 '\r'으로 커서를 가장 앞으로 옮겼기 때문이다.
본론으로 돌아와, 진행률을 계속 갱신하는것은 '\r'을 이용해 해당 라인을 계속 덮어씌우는 방법을 사용하면 된다.
바로 보자.
System.out.println("==========Start to Generate User Table==========");
char[] animationChars = new char[] { '|', '/', '-', '\\' };
for (int i = 0; i < 1000000; i++) {
System.out.print("Processing: " + String.format("%.3f",i/10000f) + "% " + animationChars[i % 4] + "\r");
userRepository.save(new User(String.format("name%07d", i), 10L));
}
System.out.println("==========Fin.==========");
print 부분을 보면 [Procession: 진행률%] 를 계속 갱신한다는 것을 알 수 있다.