【问题标题】:How do you use the Write System Call in C++?如何在 C++ 中使用 Write System Call?
【发布时间】:2016-12-24 21:57:18
【问题描述】:

我正在尝试写入文件并希望使用写入系统调用来使其更快。基本上我有一个 QVector,我想将结果存储在一个文件中。最初我只是在遍历数组,但它太慢了。所以我做了一些研究,发现了一个叫Write System Call的东西,但我不知道如何设置代码。

这是我迄今为止尝试过的:

/*Header File*/

QVector<unsigned short> rawData;

/*Implementation File*/

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

虽然上面的代码不会让我崩溃,但它实际上并没有向输出文件写入任何内容。任何想法我做错了什么?

编辑:

使用 fwrite 我可以写入文件,但文件中的数据是一些奇怪的 Unicode。基本上这不是我想要得到的数字。这是我正在做的事情:

FILE * pFile;

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

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

fclose(pFile);

【问题讨论】:

  • rawData的声明是什么?
  • 如果是std::vector,则需要使用&amp;rawData[0]。见stackoverflow.com/questions/6485496/…
  • 没有理由你应该使用像 write() 这样的非便携式调用来“让事情变得更快”——你可以使用便携式 fwrite() 函数。此外,您需要检查文件是否确实打开了。
  • @Barmar 抱歉,忘记添加了。它现在就在那里。
  • QVector 不是标准的 C++ 类。

标签: c++ qt file qvector


【解决方案1】:

QVector 对象和其中的元素是有区别的。您可能想要编写 QVector 元素,因此为了做到这一点,您需要这样的东西:

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());
}

要获得更好的解决方案,请考虑改用QDataStream

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

这也将确保您可以以一致的方式从文件中读取信息。

【讨论】:

    【解决方案2】:

    您假设您需要使用系统调用直接写入数据。在没有看到您的代码的情况下,我认为可能并非如此。很可能你正在做一些非常低效的事情。

    您可以做得更好:在 Qt 中,最简单的方法是利用 QDataStream。当您稍后读取数据时,它将尽一切必要为您返回相同的向量。它的表现相当不错:

    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;
    }
    

    其他问题:

    1. 该文件不是文本文件,所以不要给它一个.txt 扩展名。

    2. 使用具有明确大小的类型,例如uint16_tquint16,而不是unsigned short

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多