在QIODevice::Append模式下打开的QFile意外工作.这是一个Qt错误吗



在我的类StudentTable中,我创建了一个函数appendRecord,如下所示-

qint64 StudentTable::appendRecord(Student student){
QFile file(tableName);
QDataStream stream(&file);
qDebug()<<file.open(QIODevice::Append);
qint64 dumpPosition=file.pos();
qDebug()<<file.openMode();
qDebug()<<dumpPosition;
student.next=-1;
student.print();
stream<<student;
file.close();
return dumpPosition;

}

问题是,当我直接从main()函数调用函数时,它工作得很好。但当我从同一类中的另一个函数调用同一个函数时,它什么也不做;意味着不向文件附加任何内容;

也尝试了QIODevice::Append,QIODevice::Append | QIODevices::ReadWrite,但对我来说什么都不起作用。我尝试了,因为这个问题:打开QFile以进行附加,说要尝试另一种方式;对已接受答案的评论。

我正在为学生们制作一份档案,记录学生们的情况。制作基于记录的平面文件数据库;使用链表。

代码:AddRecord()正在调用函数appendRecord(),在这种情况下什么都没发生。但是当从main()函数调用时,它最后会附加记录。

添加StudentTable类的记录函数。。。

 bool StudentTable::addRecord(Student student)
    {
        if(isEmpty()&&!isHeapAvailable())
        {
            qDebug()<<"case 1";
            student=Student("rajesh","ramesh",4,5,6);
            qint64 dumpPosition= appendRecord(student);
            Header head=header();
            head.used=dumpPosition;
            head.usedLast=dumpPosition;
            setHeader(head); 
                /*If I comment this setHeader() call here then  
                  appending works else not */
            return true;
        }
        if(!isEmpty()&&!isHeapAvailable())
        {
             qDebug()<<"case 2";
             qint64 dumpPosition= appendRecord(student);
             Header head=header();
             head.usedLast=dumpPosition;
             setHeader(head); /*If I comment this setHeader() call here then  
                  appending works else not */
             return true;
        }
        return false;
    }

我使用的是Windows 8,64位。

项目的所有文件:-

页眉.h

#ifndef HEADER_H
#define HEADER_H
#include<QtCore>
class Header
{
public:
    qint32 magicNumber;
    qint32 streamVersion;
    qint64 used;
    qint64 usedLast;
    qint64 freeLast;
    qint64 free;
    Header();
    void debug();
};
QDataStream &operator>>(QDataStream &in, Header &painting);
QDataStream &operator<<(QDataStream &out, Header &painting);
#endif // HEADER_H

Header.cpp

#include "header.h"
#include<QtGui>
#include<QtCore>
Header::Header()
{
}
void Header::debug()
{
    qDebug()<<magicNumber<<streamVersion<<used<<free<<usedLast<<freeLast;
}
QDataStream & operator<<(QDataStream &out, Header &header)
{
    out<<header.magicNumber<<header.streamVersion<<header.used<<header.free<<header.usedLast<<header.freeLast;
    return out;
}
QDataStream & operator>>(QDataStream &in, Header &header)
{
    in>>header.magicNumber>>header.streamVersion>>header.used>>header.free>>header.usedLast>>header.freeLast;
    return in;
}

Student.h

#ifndef STUDENT_H
#define STUDENT_H
#include<QtCore>
#include "record.h"
class Student
{
public:
    bool valid;
    static QString fileName;
    quint64 recordLength;
    QString name,fname;
    quint8 age,weight,clss;
    qint64 next;
    Student();
    Student(QString name,QString fname,quint8 age,quint8 weight, quint8 clss);
    void encrypt();
    void print();
};
QDataStream &operator>>(QDataStream &in, Student &painting);
QDataStream &operator<<(QDataStream &out, Student &painting);

#endif // Student_H

学生.cpp

#include "student.h"
Student::Student(QString name, QString fname, quint8 age, quint8 weight, quint8 clss)
{
    Student::fileName="Student";
    recordLength=291;
    this->name=QString(70,' ');
    this->name.replace(0,name.length(),name);
    this->fname=QString(70,' ');
    this->fname.replace(0,fname.length(),fname);
    this->age=age;
    this->weight=weight;
    this->clss=clss;
    this->next=-1;
}
void Student::encrypt()
{
}
Student::Student()
{
    Student::fileName="Student";
    recordLength=291;
    this->name=QString(70,'0');
    this->fname=QString(70,'0');
    this->age=-1;
    this->weight=-1;
    this->clss=-1;
    valid=true;
    this->next=-1;
}
QDataStream & operator<<(QDataStream &out, Student &f)
{
    out<<f.name<<f.fname<<f.age<<f.weight<<f.clss<<f.next;
    return out;

}
QDataStream & operator>>(QDataStream &in, Student &f)
{
    in>>f.name>>f.fname>>f.age>>f.weight>>f.clss>>f.next;
    return in;
}
void Student::print()
{
    qDebug()<<name<<fname<<age<<weight<<clss<<next;
}
QString Student::fileName;

StudentTable.h

#ifndef STUDENTTABLE_H
#define STUDENTTABLE_H
#include "student.h"
#include "header.h"
#include <QtGui>
#include<QtCore>
class StudentTable
{
public:
    StudentTable();
    QString tableName;

    quint64 next;
    void create();
    Header header();
    void setHeader(Header header);
    bool addRecord(Student student);
    QStandardItemModel * getModel();
    qint64 appendRecord(Student student);
    bool isEmpty();
    bool isHeapAvailable();
    void print();
private:

};

StudentTable.cpp

#include "studenttable.h"
#include<QtGui>
#include "header.h"
StudentTable::StudentTable()
{
    tableName="Student";
}
void StudentTable::create()
{
    QFile file(tableName);
    if(file.exists())
        return;
    else
        file.open(QIODevice::Append);
    QDataStream stream(&file);
    Header header;
    header.magicNumber=2015;
    header.streamVersion=stream.version();
    header.used=-1;
    header.free=-1;
    header.usedLast=-1;
    header.freeLast=-1;
    stream<<header;
    file.close();
}
void StudentTable::setHeader(Header header)
{
    QFile file(tableName);
    if(!file.exists())
    {
        qDebug()<<"File "<<tableName<<" doesn't exists";
        return;
    }
    file.open(QIODevice::WriteOnly);
    QDataStream stream(&file);
    stream<<header;
    file.close();
}
Header StudentTable::header()
{
    QFile file(tableName);

    file.open(QIODevice::ReadOnly);
    QDataStream stream(&file);
    Header header;
    stream>>header;
    file.close();
    return header;
}
bool StudentTable::isEmpty()
{
    Header head=header();
    if(head.used==-1)
        return true;
    else return false;
}
bool StudentTable::isHeapAvailable()
{
    Header head=header();
    if(head.free==-1)
        return false;
    else return true;
}
 qint64 StudentTable::appendRecord(Student student)
{
    QFile file(tableName);
    QDataStream stream(&file);
    qDebug()<<file.open(QIODevice::Append);
    qint64 dumpPosition=file.pos();
    qDebug()<<file.openMode();
    qDebug()<<dumpPosition;
    student.next=-1;
    student.print();
    stream<<student;
    file.close();
    return dumpPosition;
}
 void StudentTable::print()
 {
     if(isEmpty())
         qDebug()<<" Table is empty";
     else
     {
         Header head=header();
     QFile file(tableName);
     file.open(QIODevice::ReadOnly);
     QDataStream stream(&file);
     file.seek(head.used);
     Student current;
     stream>>current;
     current.print();
     while(current.next!=-1)
     {
         file.seek(current.next);
         stream>>current;
         current.print();
     }
     file.close();
     }
 }
bool StudentTable::addRecord(Student student)
{
    if(isEmpty()&&!isHeapAvailable())
    {
        qDebug()<<"case 1";
        student=Student("rajesh","ramesh",4,5,6);
        qint64 dumpPosition= appendRecord(student);
        Header head=header();
        head.used=dumpPosition;
        head.usedLast=dumpPosition;
        setHeader(head); 
            /*If I comment this setHeader() call here then  
              appending works else not */
        return true;
    }
    if(!isEmpty()&&!isHeapAvailable())
    {
         qDebug()<<"case 2";
         qint64 dumpPosition= appendRecord(student);
         Header head=header();
         head.usedLast=dumpPosition;
         setHeader(head); /*If I comment this setHeader() call here then  
              appending works else not */
         return true;
    }
    return false;
}
QStandardItemModel * StudentTable::getModel()
{
    QStandardItemModel *model;
    return model;
}

main.cpp

#include "widget.h"
#include <QApplication>
#include "Student.h"
#include "studenttable.h"
#include<QDebug>
#include<QtGui>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    StudentTable studentTable;
    studentTable.create();
    Header header;
    header=studentTable.header();
    header.debug();
    for(int i=1;i<2;i++)
    {
        Student student = Student("ram","bhairu",i,i,i);
        studentTable.addRecord(student);
    }
header=studentTable.header();
header.debug();
//studentTable.print();
    Widget widget;
   // widget.table->setModel(model);
    widget.show();
    return a.exec();
}

由于文件打开模式的命名,这只是一个混乱。setHeader()函数出现问题。

void StudentTable::setHeader(Header header)
{
    QFile file(tableName);
    if(!file.exists())
    {
        qDebug()<<"File "<<tableName<<" doesn't exists";
        return;
    }
    file.open(QIODevice::WriteOnly);
    QDataStream stream(&file);
    stream<<header;
    file.close();
}

每次我必须写文件头时,我都会以QIODevice::WriteOnly模式打开文件;这听起来很正确,因为我既没有阅读也没有寻找文件位置。但问题是QIODevice::WriteOnly模式;清除文件中的所有数据,然后将数据写入文件;我所期望的只是改写;

所以结论是:

如果您必须打开一个文件并覆盖某些数据;使用ReadWrite模式而不是QIODevice::WriteOnly模式。QIODevice::WriteOnly将在写入之前清除所有以前的数据

我不知道他们为什么这样命名。但是模式命名在qt和C++中都非常令人困惑。同样的事情也适用于C++。

相关内容

最新更新