在支持回收站功能的操作系统中,是否有Qt函数可用于将文件移动到回收站而非真正删除它们,或者我需要使用特定于操作系统的代码?
在支持回收站功能的操作系统中,是否有Qt函数可用于将文件移动到回收站而非真正删除它们,或者我需要使用特定于操作系统的代码?
从Qt 5.15.0 Alpha版本开始,已添加了此方法,这应该是您正在寻找的内容。
bool QFile::moveToTrash()
这些相关的代码更改可以在这里找到。
(这个问题是旧的,相应的Bugreport已经发布在https://bugreports.qt.io/browse/QTBUG-47703,但我目前缺少发表评论的声誉,并且认为这些信息很有用。)
#ifdef Q_OS_WIN32
#include "windows.h"
void MoveToTrashImpl( QString file ){
QFileInfo fileinfo( file );
if( !fileinfo.exists() )
throw OdtCore::Exception( "File doesnt exists, cant move to trash" );
WCHAR from[ MAX_PATH ];
memset( from, 0, sizeof( from ));
int l = fileinfo.absoluteFilePath().toWCharArray( from );
Q_ASSERT( 0 <= l && l < MAX_PATH );
from[ l ] = '\0';
SHFILEOPSTRUCT fileop;
memset( &fileop, 0, sizeof( fileop ) );
fileop.wFunc = FO_DELETE;
fileop.pFrom = from;
fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
int rv = SHFileOperation( &fileop );
if( 0 != rv ){
qDebug() << rv << QString::number( rv ).toInt( 0, 8 );
throw OdtCore::Exception( "move to trash failed" );
}
}
#endif
同时也适用于Linux系统
#ifdef Q_OS_LINUX
bool TrashInitialized = false;
QString TrashPath;
QString TrashPathInfo;
QString TrashPathFiles;
void MoveToTrashImpl( QString file ){
#ifdef QT_GUI_LIB
if( !TrashInitialized ){
QStringList paths;
const char* xdg_data_home = getenv( "XDG_DATA_HOME" );
if( xdg_data_home ){
qDebug() << "XDG_DATA_HOME not yet tested";
QString xdgTrash( xdg_data_home );
paths.append( xdgTrash + "/Trash" );
}
QString home = QStandardPaths::writableLocation( QStandardPaths::HomeLocation );
paths.append( home + "/.local/share/Trash" );
paths.append( home + "/.trash" );
foreach( QString path, paths ){
if( TrashPath.isEmpty() ){
QDir dir( path );
if( dir.exists() ){
TrashPath = path;
}
}
}
if( TrashPath.isEmpty() )
throw Exception( "Cant detect trash folder" );
TrashPathInfo = TrashPath + "/info";
TrashPathFiles = TrashPath + "/files";
if( !QDir( TrashPathInfo ).exists() || !QDir( TrashPathFiles ).exists() )
throw Exception( "Trash doesnt looks like FreeDesktop.org Trash specification" );
TrashInitialized = true;
}
QFileInfo original( file );
if( !original.exists() )
throw Exception( "File doesnt exists, cant move to trash" );
QString info;
info += "[Trash Info]\nPath=";
info += original.absoluteFilePath();
info += "\nDeletionDate=";
info += QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss.zzzZ");
info += "\n";
QString trashname = original.fileName();
QString infopath = TrashPathInfo + "/" + trashname + ".trashinfo";
QString filepath = TrashPathFiles + "/" + trashname;
int nr = 1;
while( QFileInfo( infopath ).exists() || QFileInfo( filepath ).exists() ){
nr++;
trashname = original.baseName() + "." + QString::number( nr );
if( !original.completeSuffix().isEmpty() ){
trashname += QString( "." ) + original.completeSuffix();
}
infopath = TrashPathInfo + "/" + trashname + ".trashinfo";
filepath = TrashPathFiles + "/" + trashname;
}
QDir dir;
if( !dir.rename( original.absoluteFilePath(), filepath ) ){
throw Exception( "move to trash failed" );
}
File infofile;
infofile.createUtf8( infopath, info );
#else
Q_UNUSED( file );
throw Exception( "Trash in server-mode not supported" );
#endif
}
#endif
目前还没有API。
https://bugreports.qt.io/browse/QTBUG-181
问题已关闭,修复版本为:某个未来版本bool QFile::moveToTrash()
。我相信在所有支持的平台上都没有一个Qt API来包装这个功能。这意味着不幸的是,您将不得不编写特定于平台的代码。
我不知道Linux发行版存储已删除文件的任何信息,并且我想这可能取决于您使用哪个文件管理器。我相信将文件移动到~/.Trash
文件夹是标准方法,但我不确定这是否可靠。例如,在外部卷中存储的文件的情况下。
在Mac OS X上,情况要容易一些,因为有一个受支持的API可以实现这一点:由Core Services提供的FSMoveObjectToTrashSync
。至少,我记得你应该这样做。 文档声称此方法现在在OS X 10.8中已被弃用。我不知道推荐的替代方案是什么。
作为Windows程序员,我认为该平台要容易得多。 :-) 基本解决方案是调用SHFileOperation
函数:
#include <Windows.h> // general Windows header file
#include <ShellAPI.h> // for shell functions, like SHFileOperation
#include <string> // (or use QString)
void RecycleFileOnWindows()
{
std::wstring path = L"C:\\Users\\Administrator\\Documents\\deleteme.txt";
path.append(1, L'\0'); // path string must be double nul-terminated
SHFILEOPSTRUCT shfos = {};
shfos.hwnd = nullptr; // handle to window that will own generated windows, if applicable
shfos.wFunc = FO_DELETE;
shfos.pFrom = path.c_str();
shfos.pTo = nullptr; // not used for deletion operations
shfos.fFlags = FOF_ALLOWUNDO; // use the recycle bin
const int retVal = SHFileOperation(&shfos);
if (retVal != 0)
{
// The operation failed...
if (shfos.fAnyOperationsAborted)
{
// ...but that's because the user canceled.
MessageBox(nullptr, L"Operation was canceled", nullptr, MB_OK | MB_ICONINFORMATION);
}
else
{
// ...for one of the other reasons given in the documentation.
MessageBox(nullptr, L"Operation failed", nullptr, MB_OK | MB_ICONERROR);
}
}
}
还有一些标志可以设置,以自定义确认、错误报告和其他行为。链接的文档包含了您构建此基本示例所需的所有细节。
在Windows Vista及更高版本中,SHFileOperation
函数已被IFileOperation
接口提供的方法所取代。如果您只针对这些较新的Windows版本进行目标定位,则应优先使用此接口。否则,SHFileOperation
仍将正常工作。
我认为没有跨平台的方法。简单地将文件移动到“垃圾”位置不会有效,因为用户可能关闭此选项。
也许,这个网址可以帮助:http://www.hardcoded.net/articles/send-files-to-trash-on-all-platforms.htm
if(QSysInfo::kernelType()=="linux")
{
QDateTime currentTime(QDateTime::currentDateTime()); // save System time
QString trashFilePath=QDir::homePath()+"/.local/share/Trash/files/"; // trash file path contain delete files
QString trashInfoPath=QDir::homePath()+"/.local/share/Trash/info/"; // trash info path contain delete files information
// create file format for trash info file----- START
QFile infoFile(trashInfoPath+FileName.completeBaseName()+"."+FileName.completeSuffix()+".trashinfo"); //filename+extension+.trashinfo // create file information file in /.local/share/Trash/info/ folder
infoFile.open(QIODevice::ReadWrite);
QTextStream stream(&infoFile); // for write data on open file
stream<<"[Trash Info]"<<endl;
stream<<"Path="+QString(QUrl::toPercentEncoding(FileName.absoluteFilePath(),"~_-./"))<<endl; // convert path string in percentage decoding scheme string
stream<<"DeletionDate="+currentTime.toString("yyyy-MM-dd")+"T"+currentTime.toString("hh:mm:ss")<<endl; // get date and time format YYYY-MM-DDThh:mm:ss
infoFile.close();
// create info file format of trash file----- END
QDir file;
file.rename(FileName.absoluteFilePath(),trashFilePath+FileName.completeBaseName()+"."+FileName.completeSuffix()); // rename(file old path, file trash path)
}
QSysInfo::kernelType()=="linux"
,因为Android的内核也是Linux。 - sashoalm/home/user_name/.local/share/Trash/files/
目录下,但每个垃圾文件还需要一个信息文件,位于/home/user_name/.local/share/Trash/info/
目录下。当我们想要将文件移入回收站时,实际上是将文件移动到/home/user_name/.local/share/Trash/files/
目录,并在/home/user_name/.local/share/Trash/info/
目录中创建信息文件。在.trashinfo格式中,使用百分比解码方案来设置文件所在的路径,信息文件还包含删除的时间和日期。
QFile.moveToTrash
(参见公告)。希望这可以帮到你! - sunyata