Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何在QFutureWatcher中清除QFuture结果_Qt_C++14_Shared Ptr_Future_Qtconcurrent - Fatal编程技术网

Qt 如何在QFutureWatcher中清除QFuture结果

Qt 如何在QFutureWatcher中清除QFuture结果,qt,c++14,shared-ptr,future,qtconcurrent,Qt,C++14,Shared Ptr,Future,Qtconcurrent,我试图一次阻止多个文件,然后将它们复制到另一个位置 应同时阻止源文件和目标文件。因此,我不能使用静态QFile::copy()函数 为了保存和移动文件,我使用QSharedPointer,因为QFile既不可复制也不可移动 为了完全执行整个操作,我使用QtConcurrent框架。即:QtConcurrent::mappedReduced和QFutureWatcher 要打开所有文件对,我使用“贴图函子”,然后要按顺序复制它们,我使用“减少函子” 使用PFile=QSharedPointer;

我试图一次阻止多个文件,然后将它们复制到另一个位置

应同时阻止源文件和目标文件。因此,我不能使用
静态QFile::copy()
函数

为了保存和移动文件,我使用
QSharedPointer
,因为
QFile
既不可复制也不可移动

为了完全执行整个操作,我使用
QtConcurrent
框架。即:
QtConcurrent::mappedReduced
QFutureWatcher

要打开所有文件对,我使用“贴图函子”,然后要按顺序复制它们,我使用“减少函子”

使用PFile=QSharedPointer;
使用PFileList=QList;
模板
结构函数WithResultType
:std::衰变\u t<函子>
{
使用结果类型=结果;
FunctorWithResultType(Functor和Functor)
:std::decation\u t{std::forward(Functor)}
{ ; }
};
模板
FunctorWithResultType
addResultType(Functor&&Functor)
{
返回{函子};
}
课堂测试
{
公众:
QDir目录;
QFutureWatcherfileCopyFutureWatcher;
// ...
};
// ...
Test::Test()
{
自动onfilescomped=[&]
{
PFileList copiedFiles=fileCopyFutureWatcher.result();

qCInfo(usbDevice)我的解决方案如下所示:

using PFile = QSharedPointer< QFile >;

using PFileList = QList< PFile >;

template< typename Result, typename Functor >
struct FunctorWithResultType
        : std::decay_t< Functor >
{

    using result_type = Result;

    FunctorWithResultType(Functor & functor)
        : std::decay_t< Functor >{std::forward< Functor >(functor)}
    { ; }

};

template< typename Result, typename Functor >
FunctorWithResultType< Result, Functor >
addResultType(Functor && functor)
{
    return {functor};
}

class Test
{
public :

    QDir currentDirectory;
    // ...
};

// ...

void Test::onDeviceAdded(QString deviceName)
{
    qCInfo(usbDevice) << "USB device" << deviceName << "is added.";
    QDir sourceDirectory{deviceName};
    if (!sourceDirectory.cd("dir")) {
        qCInfo(usbDevice) << "Drive" << deviceName << "does not contain dir subdirectory.";
        return;
    }
    auto destinationDirectory = currentDirectory;
    if (!destinationDirectory.mkpath("fileCache")) {
        qCCritical(usbDevice) << "Can't create fileCache subdirectory in"
                                     << destinationDirectory.absolutePath()
                                     << "directory";
        return;
    }
    if (!destinationDirectory.cd("fileCache")) {
        qCCritical(usbDevice) << "Can't change directory to fileCache subdirectory in"
                                     << destinationDirectory.absolutePath()
                                     << "directory";
        return;
    }
    struct PFilePair
    {
        PFile source, destination;
    };
    auto openSourceAndDestinationFiles = [&, destinationDirectory] (QFileInfo const & fileInfo) -> PFilePair
    {
        auto source = PFile::create(fileInfo.absoluteFilePath());
        QFile & sourceFile = *source;
        if (!sourceFile.open(QFile::ReadOnly)) {
            qCCritical(usbDevice) << "Can't open file" << sourceFile.fileName()
                                         << "to read:" << sourceFile.errorString();
            return {};
        }
        auto destination = PFile::create(destinationDirectory.absoluteFilePath(fileInfo.fileName()));
        QFile & destinationFile = *destination;;
        if (!destinationFile.open(QFile::ReadWrite | QFile::Truncate)) {
            qCCritical(usbDevice) << "Can't open file" << destinationFile.fileName()
                                         << "to write:" << destinationFile.errorString();
            return {};
        }
        return {qMove(source), qMove(destination)};
    };
    auto copyFiles = [&] (PFileList & files, PFilePair const & filePair)
    {
        if (filePair.source.isNull() || filePair.destination.isNull()) {
            return;
        }
        QFile & sourceFile = *filePair.source;
        QFile & destinationFile = *filePair.destination;
        qCInfo(usbDevice) << sourceFile.fileName() << "->" << destinationFile.fileName();
        constexpr int size = (1 << 20); // 1MiB
        QByteArray buffer{size, 0};
        char * const data = buffer.data();
        while (!sourceFile.atEnd()) {
            auto bytesRead = sourceFile.read(data, size);
            if (bytesRead < 0) {
                qCCritical(usbDevice) << "Can't read file" << sourceFile.fileName()
                                             << ":" << sourceFile.errorString();
                return;
            }
            auto bytesWritten = destinationFile.write(data, bytesRead);
            while (bytesWritten < bytesRead) {
                auto sizeWritten = destinationFile.write(data + bytesWritten, bytesRead - bytesWritten);
                if (sizeWritten < 0) {
                    qCCritical(usbDevice) << "Can't write file" << destinationFile.fileName()
                                                 << ":" << destinationFile.errorString();
                    return;
                }
                bytesWritten += sizeWritten;
            }
            Q_ASSERT(bytesWritten == bytesRead);
        }
        Q_ASSERT(sourceFile.size() == destinationFile.size());
        destinationFile.flush();
        files.append(filePair.destination);
    };

    auto & fileCopyFutureWatcher = *new QFutureWatcher< PFileList >{this};

    auto onFilesCopied = [&]
    {
        fileCopyFutureWatcher.deleteLater();
        PFileList copiedFiles = fileCopyFutureWatcher.result();
        qCInfo(usbDevice) << "Files copy operation from drive finished.";
        qCInfo(usbDevice) << copiedFiles.size();
        for (PFile const & file : copiedFiles) {
            // ...
        }
    };
    connect(&fileCopyFutureWatcher, &fileCopyFutureWatcher.finished, onFilesCopied);

    QStringList nameFilters;
    nameFilters << "*.dat";
    auto entryInfoList = sourceDirectory.entryInfoList(nameFilters, (QDir::Readable | QDir::Files));
    fileCopyFutureWatcher.setFuture(QtConcurrent::mappedReduced< PFileList >(qMove(entryInfoList), addResultType< PFilePair >(openSourceAndDestinationFiles), copyFiles));
}

// ...
使用PFile=QSharedPointer;
使用PFileList=QList;
模板
结构函数WithResultType
:std::衰变\u t<函子>
{
使用结果类型=结果;
FunctorWithResultType(Functor和Functor)
:std::decation\u t{std::forward(Functor)}
{ ; }
};
模板
FunctorWithResultType
addResultType(Functor&&Functor)
{
返回{函子};
}
课堂测试
{
公众:
QDir目录;
// ...
};
// ...
无效测试::onDeviceAdded(QString deviceName)
{
qCInfo(usbDevice)
using PFile = QSharedPointer< QFile >;

using PFileList = QList< PFile >;

template< typename Result, typename Functor >
struct FunctorWithResultType
        : std::decay_t< Functor >
{

    using result_type = Result;

    FunctorWithResultType(Functor & functor)
        : std::decay_t< Functor >{std::forward< Functor >(functor)}
    { ; }

};

template< typename Result, typename Functor >
FunctorWithResultType< Result, Functor >
addResultType(Functor && functor)
{
    return {functor};
}

class Test
{
public :

    QDir currentDirectory;
    // ...
};

// ...

void Test::onDeviceAdded(QString deviceName)
{
    qCInfo(usbDevice) << "USB device" << deviceName << "is added.";
    QDir sourceDirectory{deviceName};
    if (!sourceDirectory.cd("dir")) {
        qCInfo(usbDevice) << "Drive" << deviceName << "does not contain dir subdirectory.";
        return;
    }
    auto destinationDirectory = currentDirectory;
    if (!destinationDirectory.mkpath("fileCache")) {
        qCCritical(usbDevice) << "Can't create fileCache subdirectory in"
                                     << destinationDirectory.absolutePath()
                                     << "directory";
        return;
    }
    if (!destinationDirectory.cd("fileCache")) {
        qCCritical(usbDevice) << "Can't change directory to fileCache subdirectory in"
                                     << destinationDirectory.absolutePath()
                                     << "directory";
        return;
    }
    struct PFilePair
    {
        PFile source, destination;
    };
    auto openSourceAndDestinationFiles = [&, destinationDirectory] (QFileInfo const & fileInfo) -> PFilePair
    {
        auto source = PFile::create(fileInfo.absoluteFilePath());
        QFile & sourceFile = *source;
        if (!sourceFile.open(QFile::ReadOnly)) {
            qCCritical(usbDevice) << "Can't open file" << sourceFile.fileName()
                                         << "to read:" << sourceFile.errorString();
            return {};
        }
        auto destination = PFile::create(destinationDirectory.absoluteFilePath(fileInfo.fileName()));
        QFile & destinationFile = *destination;;
        if (!destinationFile.open(QFile::ReadWrite | QFile::Truncate)) {
            qCCritical(usbDevice) << "Can't open file" << destinationFile.fileName()
                                         << "to write:" << destinationFile.errorString();
            return {};
        }
        return {qMove(source), qMove(destination)};
    };
    auto copyFiles = [&] (PFileList & files, PFilePair const & filePair)
    {
        if (filePair.source.isNull() || filePair.destination.isNull()) {
            return;
        }
        QFile & sourceFile = *filePair.source;
        QFile & destinationFile = *filePair.destination;
        qCInfo(usbDevice) << sourceFile.fileName() << "->" << destinationFile.fileName();
        constexpr int size = (1 << 20); // 1MiB
        QByteArray buffer{size, 0};
        char * const data = buffer.data();
        while (!sourceFile.atEnd()) {
            auto bytesRead = sourceFile.read(data, size);
            if (bytesRead < 0) {
                qCCritical(usbDevice) << "Can't read file" << sourceFile.fileName()
                                             << ":" << sourceFile.errorString();
                return;
            }
            auto bytesWritten = destinationFile.write(data, bytesRead);
            while (bytesWritten < bytesRead) {
                auto sizeWritten = destinationFile.write(data + bytesWritten, bytesRead - bytesWritten);
                if (sizeWritten < 0) {
                    qCCritical(usbDevice) << "Can't write file" << destinationFile.fileName()
                                                 << ":" << destinationFile.errorString();
                    return;
                }
                bytesWritten += sizeWritten;
            }
            Q_ASSERT(bytesWritten == bytesRead);
        }
        Q_ASSERT(sourceFile.size() == destinationFile.size());
        destinationFile.flush();
        files.append(filePair.destination);
    };

    auto & fileCopyFutureWatcher = *new QFutureWatcher< PFileList >{this};

    auto onFilesCopied = [&]
    {
        fileCopyFutureWatcher.deleteLater();
        PFileList copiedFiles = fileCopyFutureWatcher.result();
        qCInfo(usbDevice) << "Files copy operation from drive finished.";
        qCInfo(usbDevice) << copiedFiles.size();
        for (PFile const & file : copiedFiles) {
            // ...
        }
    };
    connect(&fileCopyFutureWatcher, &fileCopyFutureWatcher.finished, onFilesCopied);

    QStringList nameFilters;
    nameFilters << "*.dat";
    auto entryInfoList = sourceDirectory.entryInfoList(nameFilters, (QDir::Readable | QDir::Files));
    fileCopyFutureWatcher.setFuture(QtConcurrent::mappedReduced< PFileList >(qMove(entryInfoList), addResultType< PFilePair >(openSourceAndDestinationFiles), copyFiles));
}

// ...