嵌入式Qt版本:Qt5.6.2
交叉编译器:arm-hisiv400-linux-gcc
表现:按照正常流程调用QStorageInfo类,均不能得到正确结果,win/x86 linux下均正常,仅仅arm版不行.
查看qt源码分析:
相关文件:qt/qtbase/src/corelib/io中
qstorageinfo.h
qstorageinfo_p.h
qstorageinfo_unix.cpp
qconfig.h
qcore_unix_p.h
qstorageInfo类实际上仅仅是QStorageInfoPribate类参数的引用而已.
qstorageInfo通过调用QStorageInfoPribate::doStat()函数来检索对应挂载点的文件系统,可用大小等信息.
void QStorageInfoPrivate::doStat()
{
initRootPath();
if (rootPath.isEmpty())
return;
retrieveVolumeInfo();
name = retrieveLabel(device);
}
stat()函数主要是调用retrieveVolumeInfo()来检索获取挂载点的文件系统,是否只读等信息的.此函数的具体实现在qstorageinfo_unix.cpp
void QStorageInfoPrivate::retrieveVolumeInfo()
{
QT_STATFSBUF statfs_buf;
int result;
EINTR_LOOP(result, QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf));
if (result == 0) {
valid = true;
ready = true;
#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize;
bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize;
#else
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
#endif
blockSize = statfs_buf.f_bsize;
#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4)
#if defined(_STATFS_F_FLAGS)
readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
#endif
#else
readOnly = (statfs_buf.f_flag & ST_RDONLY) != 0;
#endif
}
}
retrieveVolumeInfo()中比较关键的就是 :EINTR_LOOP(result, QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf));
//qconfig.h中定义了此宏
#define QT_LARGEFILE_SUPPORT 64
//qstorageinfo_unix.cpp 实现代码
# if defined(QT_LARGEFILE_SUPPORT)
# define QT_STATFSBUF struct statvfs64
# define QT_STATFS ::statvfs64
# else
# define QT_STATFSBUF struct statvfs
# define QT_STATFS ::statvfs
# endif // QT_LARGEFILE_SUPPORT
qcore_unix_p.h 实现
#define EINTR_LOOP(var, cmd) \
do { \
var = cmd; \
} while (var == -1 && errno == EINTR)
![点击并拖拽以移动 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==](https://img-blog.csdnimg.cn/2022010703574784670.gif)
可注意在qconfig中宏QT_LARGEFILE_SUPPORT是直接定义好的,就导致了在qstorageinfo_unix.cpp文件中QT_STATFSBUF使用的是struct statvfs64;QT_STATFS使用的是statvfs64.
但是arm-hisiv400-linux-gcc所对应的板子环境是32位系统,需要使用struct statvfs/statvfs 这就导致了在32位交叉编译的系统中使用QStorageInfo不能获取到正确的信息.
用户可考虑将qconfig中宏QT_LARGEFILE_SUPPORT 注释掉,然后重新编译qt源码生成对应的库,应该可以解决问题.但是此处自己并未做尝试.
可参考:statvfs 获取statvfs()函数的使用方法,以及其所获取到的信息具体含义.