QFile
- 파일을 쓰거나 읽기 위한 인터페이스를 제공하는 클래스.
- 텍스트와 바이너리 파일, 리소스를 읽거나 쓸 수 있는 입출력 장치. QTextStream이나 QDataStream과 사용하면 좀 더 편리하게 사용할 수 있다.
- 일반적으로 생성자를 통해 파일 이름을 넘기지만, setFileName() 함수를 사용해 추후에 따로 설정해 줄 수도 있다.
- 운영체제에 상관없이 '\'가 아닌 '/'를 사용함에 유의한다!
- exists() 함수를 사용하여 파일이 있는지 체크할 수 있고, remove()로 파일을 지울 수 있다.
- open(), close(), flush()
- 일반적으로 데이터를 읽을 때 QDataStream이나 QTextStream을 사용하지만, QIODevice에 있는 read(), readLine(), readAll(), write() 함수도 호출할 수 있다. 한 번에 한 글자씩 다루려면 getChar(), putChar(), ungetChar()를 사용한다.
- size(), pos() - position, seek() - 다른 위치로 이동
- 파일의 끝에 도달하면 atEnd() 함수가 true를 반환한다.
https://doc.qt.io/qt-5/qfile.html
QFile Class | Qt Core 5.15.2
QFile Class The QFile class provides an interface for reading from and writing to files. More... Note: All functions in this class are reentrant. Public Types Public Functions QFile(const QString &name, QObject *parent) QFile(QObject *parent) QFile(const Q
doc.qt.io
QDir
- 디렉토리 구조와 그 내용에 대한 접근을 제공하는 클래스이다.
- 폴더 구분자로 '/'를 사용하면 Qt가 알아서 OS에 맞춰서 변환해 준다.
- QDir는 상대/절대 경로를 사용해 파일을 가리킬 수 있다. 절대 경로는 폴더 구분자로 시작하고, 상태 경로는 폴더나 파일 이름으로 시작해서 현재 폴더에 대한 상대적인 경로를 나타낸다.
- 절대 경로
- QDir("/home/user/Documents");
- QDir("C:/Documents and Settings");
- 상대 경로
- QDir("images/landscape.png");
- isRelative(), isAbsolute() 함수를 이용해서 체크할 수 있고, makeAbsolute()를 사용하여 상대 경로를 절대 경로로 변환할 수 있다.
- toNativeSeperators() - 각 OS에 맞는 구분자를 넣은 경로를 반환하는 함수
https://doc.qt.io/qt-5/qdir.html
QDir Class | Qt Core 5.15.2
QDir Class The QDir class provides access to directory structures and their contents. More... Header: #include qmake: QT += core Note: All functions in this class are reentrant. Public Types enum Filter { Dirs, AllDirs, Files, Drives, NoSymLinks, …, Case
doc.qt.io
boost::filesystem::filesystem_error
이슈 해결을 위해 디버깅을 하던 중, DEBUG 창에 다음과 같은 메시지가 뜨면서 애플리케이션이 종료되었다.
Qt Concurrent has caught an exception thrown from a worker thread.
This is not supported, exceptions thrown in worker threads must be caught before control returns to Qt Concurrent.
이는 QtConcurrent로 돌고 있는 쓰레드 내부에서 exception이 발생한 것이며, 나의 경우에는 boost::filesystem::remove()를 사용한 부분이 문제였다. boost에 대해 전혀 모르고 있었기 때문에 깨나 애를 먹었다...
pathname에 정상적으로 값이 들어가지 않는 듯해서 Log를 찍어 봤는데, 뭔가 라이브러리 내부에서 동작하다가 에러가 나서 값이 바뀌는 듯했다. 에러 메시지는 "ERROR_DIR_NOT_EMPTY".
뭔가 Concurrent 내부에서 예외를 잡지 못하는 뉘앙스인 것 같으니 try-catch문을 Concurrent 실행하는 바깥 쪽에서 돌려야 하나 고민을 하다가, 먼저 catch문의 조건을 바꿔 보기로 했다.
catch (const boost::exception& e) => catch (...)
모든 예외를 잡게끔 처리해 버리니까 정상적으로 작동했고, 이는 캐치하지 못해서 문제가 됐던 예외가 boost::exception의 종류가 아니라는 것을 알게 되었다.
따라서 수소문 끝에 boost::filesystem::filesystem_error로 잡으니까 모든 예외를 처리하는 무시무시한 코드가 없이도 잘 작동하게 되었다.
일단 예외 처리는 마무리되었는데, 아직 제대로 이슈 테스트를 못 해 봐서... 내일 마저 해결해 보려고 한다. 😄