Qt의 QFile::copy()는 Windows와 Symbian에서만 native copy를 사용해 구현되어있다(2011-07-20 기준).
http://bugreports.qt.nokia.com/browse/QTBUG-10369
http://bugreports.qt.nokia.com/browse/QTBUG-10337
따라서 다른 platform에서 copy()를 사용하면 복사된 파일이 copy() 수행 시점의 timestamp를 가지게 된다.
해결:
지금 내 경우에는 생성시간의 유지가 중요한 상황이므로 다음과 같이 간단하게 회피하는 QFileFixed class를 만들어서 해결했다.
// file: QFileFixed.h
//! \author manywaypark at gmail.com http://manywaypark.tistory.com
class QFileFixed : public QFile
{
public:
QFileFixed(const QString &name);
#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))
bool copy(const QString &newName);
static bool copy(const QString &fileName, const QString &newName);
private:
static void copyFileTime(const QFileInfo &srcInfo, const QString &dstPath);
#endif
};
// file: QFileFixed.cpp
//! \author manywaypark at gmail.com http://manywaypark.tistory.com
#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))
#include <sys/time.h>
#endif
QFileFixed::QFileFixed(const QString &name)
: QFile(name)
{}
#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))
bool QFileFixed::copy(const QString &newName){
bool r(QFile::copy(newName));
if (r) copyFileTime(QFileInfo(*this), newName);
return r;
}
bool QFileFixed::copy(const QString &fileName, const QString &newName)
{
bool r(QFile::copy(fileName, newName));
if (r) copyFileTime(QFileInfo(fileName), newName);
return r;
}
void QFileFixed::copyFileTime(const QFileInfo &srcInfo, const QString &dstPath)
{
QDateTime access(srcInfo.lastRead());
QDateTime created(srcInfo.created()); /* created == modification?? */
struct timeval time[2];
time[0].tv_sec = access.toTime_t();
time[0].tv_usec = access.time().msec() * 1000; /* millisecond to microsecond */
time[1].tv_sec = created.toTime_t();
time[1].tv_usec = created.time().msec() * 1000; /* millisecond to microsecond */
int r = utimes(dstPath.toAscii().constData(), time);
Q_ASSERT(r == 0);
}
#endif // !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
Windows와 Mac OSX에서 테스트되었고, 내가 필요한 파일 생성 시간 유지는 잘 되는 것을 확인했다.
happy hackin'