Merge pull request #12364 from Chocobo1/fileOutIter

Avoid holding entire file in memory
This commit is contained in:
Mike Tzou
2020-04-04 11:07:59 +08:00
committed by GitHub
6 changed files with 158 additions and 15 deletions

View File

@@ -41,8 +41,10 @@
#include <QFileInfo>
#include <QHash>
#include "base/exceptions.h"
#include "base/global.h"
#include "base/utils/fs.h"
#include "base/utils/io.h"
#include "base/utils/string.h"
#include "private/ltunderlyingtype.h"
@@ -182,19 +184,19 @@ void TorrentCreatorThread::run()
if (isInterruptionRequested()) return;
// create the torrent
std::ofstream outfile(
#ifdef _MSC_VER
Utils::Fs::toNativePath(m_params.savePath).toStdWString().c_str()
#else
Utils::Fs::toNativePath(m_params.savePath).toUtf8().constData()
#endif
, (std::ios_base::out | std::ios_base::binary | std::ios_base::trunc));
if (outfile.fail())
throw std::runtime_error(tr("create new torrent file failed").toStdString());
QFile outfile {m_params.savePath};
if (!outfile.open(QIODevice::WriteOnly)) {
throw RuntimeError {tr("Create new torrent file failed. Reason: %1")
.arg(outfile.errorString())};
}
if (isInterruptionRequested()) return;
lt::bencode(std::ostream_iterator<char>(outfile), entry);
lt::bencode(Utils::IO::FileDeviceOutputIterator {outfile}, entry);
if (outfile.error() != QFileDevice::NoError) {
throw RuntimeError {tr("Create new torrent file failed. Reason: %1")
.arg(outfile.errorString())};
}
outfile.close();
emit updateProgress(100);

View File

@@ -47,6 +47,7 @@
#include "base/exceptions.h"
#include "base/global.h"
#include "base/utils/fs.h"
#include "base/utils/io.h"
#include "base/utils/misc.h"
#include "infohash.h"
#include "trackerentry.h"
@@ -166,12 +167,12 @@ void TorrentInfo::saveToFile(const QString &path) const
#endif
const lt::entry torrentEntry = torrentCreator.generate();
QByteArray out;
out.reserve(1024 * 1024); // most torrent file sizes are under 1 MB
lt::bencode(std::back_inserter(out), torrentEntry);
QFile torrentFile {path};
if (!torrentFile.open(QIODevice::WriteOnly))
throw RuntimeError {torrentFile.errorString()};
QFile torrentFile{path};
if (!torrentFile.open(QIODevice::WriteOnly) || (torrentFile.write(out) != out.size()))
lt::bencode(Utils::IO::FileDeviceOutputIterator {torrentFile}, torrentEntry);
if (torrentFile.error() != QFileDevice::NoError)
throw RuntimeError {torrentFile.errorString()};
}