QTextStream将错误的数据写入文件

时间:2014-12-22 19:01:54

标签: c++ qt qtextedit qfile qtextstream

我尝试从同一个文件读取和写入,但得到奇怪的行为。以下是示例代码:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextStream>
#include <QFile>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_textEdit_textChanged();

private:
    QFile *File;
    QTextStream *FileStream;
    QString TextFromFile;
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    File = new QFile;
    File->setFileName("test.txt");
    File->open(QIODevice::ReadWrite | QIODevice::Text);
    FileStream = new QTextStream(File);

    TextFromFile = FileStream->readAll();
    ui->textEdit->setText(TextFromFile);

    File->close();
    File->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_textEdit_textChanged()
{
    *FileStream << ui->textEdit->toPlainText();
    FileStream->flush();
}

所以当我输入例如: enter image description here
文件将更改为:
enter image description here
但我需要这个:
enter image description here
我的目的是每次输入短信到textedit时覆盖文件。

1 个答案:

答案 0 :(得分:3)

如果您每次都需要重写文件,那么尝试在没有指针的情况下执行此操作。类似的东西:

void MainWindow::on_textEdit_textChanged()
{    
    QElapsedTimer timer;
    timer.start();  
    QFile file("test.txt");
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
        qDebug() << "failed open";
    else
    {
        QTextStream out(&file);
        out << ui->textEdit->toPlainText();
    }
    qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds";
}

QFile析构函数将在插槽末尾关闭文件。

我的案例输出:

The slow operation took 0 milliseconds 
The slow operation took 0 milliseconds 

当然,对于大数据,它会更慢,但我认为这是正常的做法。

可能你认为QIODevice::Truncate可以做到这一点,但这是错误的。来自doc:

  

如果可能,设备在打开之前会被截断。都早点   设备内容丢失。

但是在你的代码中它不起作用,因为你使用相同的流,你不会每次都打开你的文件,你只是每次都附加新的单词。并且flush()只刷新等待写入设备的任何缓冲数据。