[Kst] branches/work/kst/portto4/kst/src/datasources/ascii
Peter Kümmel
syntheticpp at gmx.net
Sun Oct 7 15:20:20 UTC 2012
SVN commit 1319572 by kuemmel:
read very big files not at once
M +60 -0 asciisource.cpp
M +9 -1 asciisource.h
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.cpp #1319571:1319572
@@ -30,6 +30,7 @@
#include "measuretime.h"
#include <QFile>
+#include <QMessageBox>
#include <assert.h>
#include <ctype.h>
@@ -484,8 +485,63 @@
//-------------------------------------------------------------------------------------------
+void AsciiSource::clearFileBuffer()
+{
+ _tmpBuffer.clear();
+ _bufferedS = -10;
+ _bufferedN = -10;
+}
+
+//-------------------------------------------------------------------------------------------
int AsciiSource::readField(double *v, const QString& field, int s, int n)
{
+ bool re_alloc;
+ int n_read = readField(v, field, s, n, re_alloc);
+ if (re_alloc) {
+ // file is now buffered in memory
+ return n_read;
+ }
+
+ // reading whole file into memory failed
+
+ // find a smaller allocatable size
+ clearFileBuffer();
+ int realloc_size = n / 2;
+ _tmpBuffer.resize(realloc_size);
+ while (_tmpBuffer.size() != realloc_size && realloc_size > 0) {
+ realloc_size /= 2;
+ _tmpBuffer.resize(realloc_size);
+ }
+ realloc_size /= 2; // while reading available memory could shrink, just be sure
+ if (realloc_size == 0) {
+ QMessageBox::warning(0, "Error while reading ascii file", "File could not be read because not enough memory is available.");
+ return 0;
+ }
+
+ // read in
+ int start = s;
+ n_read = 0;
+ while (n_read < n) {
+ clearFileBuffer();
+ int to_read = n_read + realloc_size < n ? realloc_size : n - n_read;
+ n_read += readField(v + start, field, n_read, to_read, re_alloc);
+ if (!re_alloc) {
+ clearFileBuffer();
+ QMessageBox::warning(0, "Error while reading ascii file", "The file was only read partially not enough memory is available.");
+ return n_read;
+ }
+ start += to_read;
+ }
+ // don't buffer partial files
+ clearFileBuffer();
+ return n_read;
+}
+
+
+//-------------------------------------------------------------------------------------------
+int AsciiSource::readField(double *v, const QString& field, int s, int n, bool& re_alloc)
+{
+ re_alloc = true;
if (n < 0) {
n = 1; /* n < 0 means read one sample, not frame - irrelevent here */
}
@@ -518,6 +574,10 @@
bufread = readFromFile(file, _tmpBuffer, bufstart, bufread);
+ if (bufread == 0) {
+ re_alloc = false;
+ return 0;
+ }
_bufferedS = s;
_bufferedN = n;
}
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.h #1319571:1319572
@@ -50,7 +50,6 @@
int readField(double *v, const QString &field, int s, int n);
-
QString fileType() const;
void save(QXmlStreamWriter &s);
@@ -89,6 +88,7 @@
QVarLengthArray<char, KST_PREALLOC> _tmpBuffer;
int _bufferedS;
int _bufferedN;
+ void clearFileBuffer();
QVarLengthArray<int, KST_PREALLOC> _rowIndex;
friend class ConfigWidgetAscii;
@@ -118,6 +118,9 @@
template<class T>
int readFromFile(QFile&, T& buffer, int start, int numberOfBytes, int maximalBytes = -1);
+ int readField(double *v, const QString &field, int s, int n, bool& re_alloc);
+
+
struct LineEndingType {
bool is_crlf;
char character;
@@ -250,12 +253,17 @@
template<class T>
int AsciiSource::readFromFile(QFile& file, T& buffer, int start, int bytesToRead, int maximalBytes)
{
+ const int oldSize = buffer.size();
if (maximalBytes == -1) {
buffer.resize(bytesToRead + 1);
+ if (buffer.size() == oldSize)
+ return 0;
} else {
bytesToRead = qMin(bytesToRead, maximalBytes);
if (buffer.size() <= bytesToRead) {
buffer.resize(bytesToRead + 1);
+ if (buffer.size() == oldSize)
+ return 0;
}
}
file.seek(start); // expensive?
More information about the Kst
mailing list