QFile은 프로그램 종료 시 파일을 저장하지만 ~500MB 파일은 전혀 저장하지 않습니다.

StackOverflow https://stackoverflow.com//questions/22002095

문제

응, 얘들아, 또 나야다음 코드가 있습니다.

void MainWindow::on_startButton_clicked()
{
  QNetworkAccessManager *nam = new QNetworkAccessManager(this);
  QNetworkReply *re = nam->get(QNetworkRequest(QUrl("http://somesite/ai/iai.jpg")));
  QEventLoop loop;
  QObject::connect(reply, SIGNAL(readyRead()), &loop, SLOT(quit()));
  loop.exec();
  ui->dbgOut->insertHtml("<font color='green'>OK</font><br>");
  ui->dbgOut->insertHtml("##################################");
  //save
  QFile file("C:\\a.bin");
  file.open(QIODevice::WriteOnly);
  file.write(re->readAll());
  file.close();
}

그리고 두 가지 문제가 있습니다.

  1. 버튼을 클릭하면 파일이 다운로드되지만 HDD에 쓰지는 않습니다.5분, 10분 정도는 기다릴 수 있는데 아무것도 없어요.이때 전체 파일은 프로그램 메모리 내부에 저장됩니다.프로그램을 닫으면 디스크에 저장됩니다.

  2. 대용량 파일(~500MB)은 전혀 저장되지 않습니다.프로그램을 닫으면 즉시 충돌이 발생합니다.

내 프로그램이 다운로드한 파일을 "실시간"으로 저장하도록 편집하려면 어떻게 해야 합니까?

도움이 되었습니까?

해결책

비 상호 작용은 다음과 같습니다. re->readAll() 크기를 알 수 없는 장치에서 호출이 차단되고 있습니다.요청이 완료될 때까지 계속 읽혀집니다.

대용량 파일의 문제는 파일을 보유하는 바이트 배열의 증가와 관련이 있습니다.어떤 시점이 되면 바이트 배열은 400MB가 되고 그 크기의 2배로 커져야 하므로 한 번에 최대 1GB를 두 개의 큰 청크로 나누어 보관해야 하며 주소 공간 조각화로 인해 할당 요청이 실패하고 프로그램이 충돌합니다.

코드를 조금만 변경하면 원하는 동작이 생성됩니다.한 번에 읽고 쓰기 시작하고 두 가지를 연결하기만 하면 됩니다.

class MainWindow {
  ...
  // You shouldn't be creating a new network access manager for each request.
  QScopedPointer<QNetworkAccessManager> m_nam;
  ...
};

void MainWindow::handleError(const QNetworkReply *) { ... }
void MainWindow::handleError(const QFile *) { ... }
void MainWindow::on_startButton_clicked()
{
  // Lazily create the network access manager once.
  if (!m_nam) m_nam.reset(new QNetworkAccessManager);
  // The file is destructed, and thus flushed and closed, when the
  // last shared pointer to this file is destructed.
  QSharedPointer<QFile> output(new QFile("C:\\a.bin"));
  if (!output->open(QIODevice::WriteOnly)) return;
  QNetworkReply *reply = m_nam->get(QNetworkRequest(QUrl("http://somesite/ai/iai.jpg")));
  // The lambda syntax creates a functor object that holds a copy
  // of the reply pointer and the output file pointer.
  // This functor will be destructed when the reply is destructed.
  QObject::connect(reply, &QIODevice::readyRead, [this, output, reply]{
    QByteArray data(reply->bytesAvailable(), Qt::Uninitialized);
    qint64 in = reply->read(data.data(), data.size());
    qint64 out = output->write(in);
    if (in < 0) {
      handleError(reply); 
      reply->deleteLater();
    }
    else if (out != in) {
      handleError(output.data());
      reply->deleteLater();
    }
  });
  // The reply will self-destruct when finished, thus deleting the file
  // instance.
  QObject::connect(reply, &QNetworkReply::finished, reply, &QObject::deleteLater);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top