Avoid holding entire file in memory

Previously we need a file buffer that is as large as the file size and
this could be a problem when user has less free memory available or
having very large data. Now with the help of `FileOutputIterator`,
we can have a much smaller, fixed size immediate file buffer and also
the code looks nice with `lt::bencode()`.
This commit is contained in:
Chocobo1
2020-04-01 14:25:00 +08:00
parent 96c5af7ae9
commit 9f281c2d25
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);