How do you use the Write System Call in C++?

590 views Asked by At

I'm trying to write to a file and want to use Write System Call to make it faster. Basically I have a QVector and I want to store the results in a file. Originally I was just iterating through the array but it's too slow. So I did some research and found something called Write System Call, but I can't figure out how to set up the code.

This is what I have tried so far:

/*Header File*/

QVector<unsigned short> rawData;

/*Implementation File*/

int fd = open("output.txt", O_WRONLY)L
write(fd, &rawData, rawData.size());
close(fd);

While the above code does not crash on me it doesn't actually write anything to the output file. Any ideas what I'm doing wrong?

EDIT:

Using fwrite I am able to write to the file but the data in the file is some strange Unicode. Basically it's not number which is what I'm trying to get. Here is what I'm doing:

FILE * pFile;

pfile = fopen("pixelValues.txt", "wb");

fwrite(&rawData, sizeof(unsigned short), sizeof(rawData), pFile);

fclose(pFile);
2

There are 2 answers

0
Kuba hasn't forgotten Monica On BEST ANSWER

You're assuming that you need to write your data directly using system calls. Without seeing your code I'd argue that it probably is not the case. Most likely you were doing something very obnoxiously inefficient.

You can do better: In Qt, the simplest way would be to leverage QDataStream. It will do everything necessary to give you the same vector back when you read the data later. It perfoms quite adequately:

bool write(const QString &filename, const QVector<uint16_t> &data)
{
   QSaveFile f(filename);
   if (!f.open(QIODevice::WriteOnly))
      return false;
   QDataStream s(&f);
   s.setVersion(QDataStream::Qt_5_6);
   s << data;
   return f.commit();
}

QVector<uint16_t> read(const QString &filename)
{
   QVector<uint16_t> data;
   QFile f(filename);
   if (!f.open(QIODevice::ReadOnly))
      return data;
   QDataStream s(&f);
   s.setVersion(QDataStream::Qt_5_6);
   s >> data;
   if (s.status() != QDataStream::Ok)
      data.clear();
   return data;
}

Other issues:

  1. The file is not a text file, so don't give it a .txt extension.

  2. Use types with explicit sizes, such as uint16_t or quint16 instead of unsigned short.

0
user268396 On

There is a difference between QVector the object and the elements inside it. You probably want to write the QVector elements, so in order to do that you need something like this:

template<typename T>
int writeVector(const QVector<T>& vec, int fd)
{
    // note: the size argument to write() is about the number of bytes
    // which is: (size of each element) * (number of elements to write) 
    return write(fd, vec.constData(), (sizeof(T)) * vec.size());
}

For a better solution, consider using a QDataStream instead:

template<typename T>
void writeVectorBetter(QDataStream& stream, const QVector<T>& vec)
{
    stream << vec;
}

This will also ensure you can read the information back from the file in a consistent manner.