Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why can't QSettings be written to QTemporaryFile
Forum Updated to NodeBB v4.3 + New Features

Why can't QSettings be written to QTemporaryFile

Scheduled Pinned Locked Moved Solved General and Desktop
36 Posts 6 Posters 3.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • tovaxT tovax

    @Pl45m4 I tested QFile, the write failure should not be caused by the extension.

    Debug output:
    JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.TBjIps"
    JCDemoAES::test 2 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.TBjIps"
    JCDemoAES::test 3 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.TBjIps"
    JCDemoAES::test 4 "[GroupTest]\nUserCode=0000, 1111, 2222, 3333\nUserCodeDefault=1234\n"

    void JCDemoAES::test()
    {
        // Init temp file
        // tmpFile = new QTemporaryFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath()).arg(QApplication::applicationName()), this);
        tmpFile = new QFile(QStringLiteral("%1/%2.TBjIps").arg(QApplication::applicationDirPath()).arg(QApplication::applicationName()), this);
        tmpFile->open(QIODevice::ReadWrite | QIODevice::Text);
        qDebug() << __FUNCTION__ << 1 << tmpFile->fileName();
        tmpFile->close();
    
        // Settings
        QSettings settings(tmpFile->fileName(), QSettings::IniFormat);
        qDebug() << __FUNCTION__ << 2 << settings.fileName();
        settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
        settings.beginGroup("GroupTest");
    
        QStringList list;
        list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
        settings.setValue("UserCode", list);
        settings.setValue("UserCodeDefault", QStringLiteral("1234"));
    
        settings.endGroup();
        settings.sync();
    
        // Read temp file
        tmpFile->open(QIODevice::ReadWrite | QIODevice::Text);
        qDebug() << __FUNCTION__ << 3 << tmpFile->fileName();
        qDebug() << __FUNCTION__ << 4 << tmpFile->readAll();
        tmpFile->close();
    }
    
    Pl45m4P Offline
    Pl45m4P Offline
    Pl45m4
    wrote on last edited by Pl45m4
    #11

    @tovax

    Got (actually not me) the solution...

    Try to open the tempFile one time BEFORE you create the QSettings object.
    Then it should work :)

    Here's the MVP :)
    https://stackoverflow.com/a/57471942

    fileName returns an empty string when the file is not open. Which you did in your first try (but wrong sync). In your latest approach, the file is closed when creating the settings.
    It's a QTemporaryFile thing, this is why it worked with QFile even when the file is closed.

    So open before settings and sync after endGroup :)


    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

    ~E. W. Dijkstra

    tovaxT 1 Reply Last reply
    1
    • jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by
      #12

      This works for me:

      #include <QCoreApplication>
      #include <QSettings>
      #include <QTemporaryFile>
      #include <QTextCodec>
      #include <QDebug>
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          QTemporaryFile tmpFile("/tmp/tmpfile.XXXXXXX");
          tmpFile.open();
          tmpFile.close();
      
          QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
          settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
          settings.setValue("UserCode", "test value");
          settings.sync();
          
          QFile reader(tmpFile.fileName());
          reader.open(QIODevice::ReadOnly);
          qDebug() << "file" << tmpFile.fileName();
          qDebug() << "content" << reader.readAll();
      }
      

      Output:

      21:19:24: Starting /tmp/build-settingsfile-Desktop_Qt_5_15_5_clang_64bit-Debug/settingsfile ...
      file "/tmp/tmpfile.ZlFULTY"
      content "[General]\nUserCode=test value\n"
      

      Asking a question about code? http://eel.is/iso-c++/testcase/

      tovaxT 1 Reply Last reply
      4
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by jeremy_k
        #13

        The issue seems to be caching in the QIODevice, at least on macOS with Qt 5.15.5.

        #include <QCoreApplication>
        #include <QSettings>
        #include <QTemporaryFile>
        #include <QTextCodec>
        #include <QDebug>
        int main(int argc, char *argv[])
        {
            QCoreApplication a(argc, argv);
        
            QTemporaryFile tmpFile("/tmp/tmpfile.XXXXXXX");
            tmpFile.open();
            tmpFile.write("some text");
            tmpFile.seek(0);
            qDebug() << "tmpfile" << tmpFile.readAll();
            tmpFile.close();
        
            QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
            settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
            settings.setValue("UserCode", "test value");
            settings.sync();
        
            QFile reader(tmpFile.fileName());
            reader.open(QIODevice::ReadOnly);
            qDebug() << "file" << tmpFile.fileName() << reader.fileName();
            qDebug() << "content" << reader.readAll();
            tmpFile.open();
            qDebug() << "tmpfile" << tmpFile.readAll();
        }
        

        Output:

        tmpfile "some text"
        file "/tmp/tmpfile.NmlyxbW" "/tmp/tmpfile.NmlyxbW"
        content "[General]\nUserCode=test value\n"
        tmpfile "some text"
        

        Asking a question about code? http://eel.is/iso-c++/testcase/

        jeremy_kJ tovaxT 2 Replies Last reply
        1
        • jeremy_kJ jeremy_k

          The issue seems to be caching in the QIODevice, at least on macOS with Qt 5.15.5.

          #include <QCoreApplication>
          #include <QSettings>
          #include <QTemporaryFile>
          #include <QTextCodec>
          #include <QDebug>
          int main(int argc, char *argv[])
          {
              QCoreApplication a(argc, argv);
          
              QTemporaryFile tmpFile("/tmp/tmpfile.XXXXXXX");
              tmpFile.open();
              tmpFile.write("some text");
              tmpFile.seek(0);
              qDebug() << "tmpfile" << tmpFile.readAll();
              tmpFile.close();
          
              QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
              settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
              settings.setValue("UserCode", "test value");
              settings.sync();
          
              QFile reader(tmpFile.fileName());
              reader.open(QIODevice::ReadOnly);
              qDebug() << "file" << tmpFile.fileName() << reader.fileName();
              qDebug() << "content" << reader.readAll();
              tmpFile.open();
              qDebug() << "tmpfile" << tmpFile.readAll();
          }
          

          Output:

          tmpfile "some text"
          file "/tmp/tmpfile.NmlyxbW" "/tmp/tmpfile.NmlyxbW"
          content "[General]\nUserCode=test value\n"
          tmpfile "some text"
          
          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #14

          https://doc.qt.io/qt-6/qiodevice.html says:
          Some subclasses, such as QFile and QTcpSocket, are implemented using a memory buffer for intermediate storing of data.

          My guess is that closing and reopening the QTemporaryFile doesn't discard its buffer and fails to notice the underlying file change.

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          0
          • Pl45m4P Pl45m4

            @tovax

            Got (actually not me) the solution...

            Try to open the tempFile one time BEFORE you create the QSettings object.
            Then it should work :)

            Here's the MVP :)
            https://stackoverflow.com/a/57471942

            fileName returns an empty string when the file is not open. Which you did in your first try (but wrong sync). In your latest approach, the file is closed when creating the settings.
            It's a QTemporaryFile thing, this is why it worked with QFile even when the file is closed.

            So open before settings and sync after endGroup :)

            tovaxT Offline
            tovaxT Offline
            tovax
            wrote on last edited by
            #15

            @Pl45m4
            Output:
            JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.NYWrOp"
            JCDemoAES::test 2 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.NYWrOp"
            JCDemoAES::test 3 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.NYWrOp"
            JCDemoAES::test 4 ""

            void JCDemoAES::test()
            {
                // Init temp file
                tmpFile = new QTemporaryFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath()).arg(QApplication::applicationName()), this);
                tmpFile->open();
                qDebug() << __FUNCTION__ << 1 << tmpFile->fileName();
            
                // Settings
                QSettings settings(tmpFile->fileName(), QSettings::IniFormat);
                qDebug() << __FUNCTION__ << 2 << settings.fileName();
                settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                settings.beginGroup("GroupTest");
            
                QStringList list;
                list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
                settings.setValue("UserCode", list);
                settings.setValue("UserCodeDefault", QStringLiteral("1234"));
            
                settings.endGroup();
                settings.sync();
            
                // Read temp file
                qDebug() << __FUNCTION__ << 3 << tmpFile->fileName();
                qDebug() << __FUNCTION__ << 4 << tmpFile->readAll();
                tmpFile->close();
            }
            
            1 Reply Last reply
            0
            • jeremy_kJ jeremy_k

              This works for me:

              #include <QCoreApplication>
              #include <QSettings>
              #include <QTemporaryFile>
              #include <QTextCodec>
              #include <QDebug>
              int main(int argc, char *argv[])
              {
                  QCoreApplication a(argc, argv);
              
                  QTemporaryFile tmpFile("/tmp/tmpfile.XXXXXXX");
                  tmpFile.open();
                  tmpFile.close();
              
                  QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
                  settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                  settings.setValue("UserCode", "test value");
                  settings.sync();
                  
                  QFile reader(tmpFile.fileName());
                  reader.open(QIODevice::ReadOnly);
                  qDebug() << "file" << tmpFile.fileName();
                  qDebug() << "content" << reader.readAll();
              }
              

              Output:

              21:19:24: Starting /tmp/build-settingsfile-Desktop_Qt_5_15_5_clang_64bit-Debug/settingsfile ...
              file "/tmp/tmpfile.ZlFULTY"
              content "[General]\nUserCode=test value\n"
              
              tovaxT Offline
              tovaxT Offline
              tovax
              wrote on last edited by
              #16

              @jeremy_k
              PC:
              Win10 64bit
              Qt 5.14.2

                  QTemporaryFile tmpFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath()).arg(QApplication::applicationName()));
                  tmpFile.open();
                  tmpFile.close();
              
                  QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
                  settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                  settings.setValue("UserCode", "test value");
                  settings.sync();
              
                  QFile reader(tmpFile.fileName());
                  reader.open(QIODevice::ReadOnly);
                  qDebug() << "file" << tmpFile.fileName();
                  qDebug() << "content" << reader.readAll();
              

              Output:
              file "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.IwayTr"
              content ""

              1 Reply Last reply
              0
              • jeremy_kJ jeremy_k

                The issue seems to be caching in the QIODevice, at least on macOS with Qt 5.15.5.

                #include <QCoreApplication>
                #include <QSettings>
                #include <QTemporaryFile>
                #include <QTextCodec>
                #include <QDebug>
                int main(int argc, char *argv[])
                {
                    QCoreApplication a(argc, argv);
                
                    QTemporaryFile tmpFile("/tmp/tmpfile.XXXXXXX");
                    tmpFile.open();
                    tmpFile.write("some text");
                    tmpFile.seek(0);
                    qDebug() << "tmpfile" << tmpFile.readAll();
                    tmpFile.close();
                
                    QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
                    settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                    settings.setValue("UserCode", "test value");
                    settings.sync();
                
                    QFile reader(tmpFile.fileName());
                    reader.open(QIODevice::ReadOnly);
                    qDebug() << "file" << tmpFile.fileName() << reader.fileName();
                    qDebug() << "content" << reader.readAll();
                    tmpFile.open();
                    qDebug() << "tmpfile" << tmpFile.readAll();
                }
                

                Output:

                tmpfile "some text"
                file "/tmp/tmpfile.NmlyxbW" "/tmp/tmpfile.NmlyxbW"
                content "[General]\nUserCode=test value\n"
                tmpfile "some text"
                
                tovaxT Offline
                tovaxT Offline
                tovax
                wrote on last edited by
                #17

                @jeremy_k said in Why can't QSettings be written to QTemporaryFile:

                e seems to be caching in the QIODev

                    QTemporaryFile tmpFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath()).arg(QApplication::applicationName()));
                    tmpFile.open();
                    tmpFile.write("some text");
                    tmpFile.seek(0);
                    qDebug() << "tmpfile" << tmpFile.readAll();
                    tmpFile.close();
                
                    QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
                    settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                    settings.setValue("UserCode", "test value");
                    settings.sync();
                
                    QFile reader(tmpFile.fileName());
                    reader.open(QIODevice::ReadOnly);
                    qDebug() << "file" << tmpFile.fileName() << reader.fileName();
                    qDebug() << "content" << reader.readAll();
                    tmpFile.open();
                    qDebug() << "tmpfile" << tmpFile.readAll();
                

                Output:
                tmpfile "some text"
                file "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.bveDgi" "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug/debug/JCDemoAES.bveDgi"
                content "some text"
                tmpfile "some text"

                1 Reply Last reply
                0
                • tovaxT Offline
                  tovaxT Offline
                  tovax
                  wrote on last edited by
                  #18

                  I tested qt5.15.2 and couldn't work.
                  PC: Win10 64-bit
                  Compiler: MSVC2019

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by Christian Ehrlicher
                    #19

                    You should check QSettings::status() and will notice that you get a QSettings::FormatError since you try to load an invalid ini file.

                    qDebug() << "Settings status: " <<  settings.status();
                    

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    tovaxT 2 Replies Last reply
                    4
                    • Christian EhrlicherC Christian Ehrlicher

                      You should check QSettings::status() and will notice that you get a QSettings::FormatError since you try to load an invalid ini file.

                      qDebug() << "Settings status: " <<  settings.status();
                      
                      tovaxT Offline
                      tovaxT Offline
                      tovax
                      wrote on last edited by tovax
                      #20

                      @Christian-Ehrlicher Hi, thanks.
                      It's "QSettings::NoError".
                      Output:
                      JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.tSHxeC"
                      JCDemoAES::test 2 QSettings::NoError
                      JCDemoAES::test file: "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.tSHxeC"
                      JCDemoAES::test content: ""

                          // Init temp file
                          QTemporaryFile tmpFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                          tmpFile.open();
                          tmpFile.close();
                          qDebug() << __FUNCTION__ << 1 << tmpFile.fileName();
                      
                          // Settings
                          QSettings settings(tmpFile.fileName(), QSettings::IniFormat);
                          qDebug() << __FUNCTION__ << 2 << settings.status();
                          settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                          settings.beginGroup("GroupTest");
                      
                          QStringList list;
                          list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
                          settings.setValue("UserCode", list);
                          settings.setValue("UserCodeDefault", QStringLiteral("1234"));
                      
                          settings.endGroup();
                          settings.sync();
                      
                          // Read temp file
                          QFile reader(tmpFile.fileName());
                          reader.open(QIODevice::ReadOnly);
                          qDebug() << __FUNCTION__ << "file:" << tmpFile.fileName();
                          qDebug() << __FUNCTION__ << "content:" << reader.readAll();
                      
                      1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        You should check QSettings::status() and will notice that you get a QSettings::FormatError since you try to load an invalid ini file.

                        qDebug() << "Settings status: " <<  settings.status();
                        
                        tovaxT Offline
                        tovaxT Offline
                        tovax
                        wrote on last edited by
                        #21

                        @Christian-Ehrlicher
                        QSettings::status() is "AccessError" after settings.sync();
                        Output:
                        JCDemoAES::test 3 QSettings::AccessError

                            settings.endGroup();
                            settings.sync();
                            qDebug() << __FUNCTION__ << 3 << settings.status();
                        
                        1 Reply Last reply
                        0
                        • tovaxT Offline
                          tovaxT Offline
                          tovax
                          wrote on last edited by tovax
                          #22

                          I don't know why access error occurred.

                          AccessError
                          public static final QSettings.Status AccessError

                          An access error occurred (e.g. trying to write to a read-only file). 
                          

                          A QTemporaryFile will always be opened in QIODevice::ReadWrite mode, this allows easy access to the data in the file. This function will return true upon success and will set the fileName() to the unique filename used.

                          1 Reply Last reply
                          0
                          • tovaxT Offline
                            tovaxT Offline
                            tovax
                            wrote on last edited by
                            #23

                            Output:
                            JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                            JCDemoAES::test 2 QSettings::NoError
                            JCDemoAES::test 3 QSettings::AccessError
                            JCDemoAES::test file: "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                            JCDemoAES::test content: ""

                                // Init temp file
                                tmpFile = new QTemporaryFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                                tmpFile->open();
                                qDebug() << __FUNCTION__ << 1 << tmpFile->fileName();
                            
                                // Settings
                                QSettings settings(tmpFile->fileName(), QSettings::IniFormat);
                                qDebug() << __FUNCTION__ << 2 << settings.status();
                                settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                                settings.beginGroup("GroupTest");
                            
                                QStringList list;
                                list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
                                settings.setValue("UserCode", list);
                                settings.setValue("UserCodeDefault", QStringLiteral("1234"));
                            
                                settings.endGroup();
                                settings.sync();
                                qDebug() << __FUNCTION__ << 3 << settings.status();
                            
                                // Read temp file
                                QFile reader(tmpFile->fileName());
                                reader.open(QIODevice::ReadOnly);
                                qDebug() << __FUNCTION__ << "file:" << tmpFile->fileName();
                                qDebug() << __FUNCTION__ << "content:" << reader.readAll();
                            
                                // Close temp file
                                tmpFile->close();
                            
                            JonBJ 2 Replies Last reply
                            0
                            • tovaxT tovax

                              Output:
                              JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                              JCDemoAES::test 2 QSettings::NoError
                              JCDemoAES::test 3 QSettings::AccessError
                              JCDemoAES::test file: "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                              JCDemoAES::test content: ""

                                  // Init temp file
                                  tmpFile = new QTemporaryFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                                  tmpFile->open();
                                  qDebug() << __FUNCTION__ << 1 << tmpFile->fileName();
                              
                                  // Settings
                                  QSettings settings(tmpFile->fileName(), QSettings::IniFormat);
                                  qDebug() << __FUNCTION__ << 2 << settings.status();
                                  settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                                  settings.beginGroup("GroupTest");
                              
                                  QStringList list;
                                  list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
                                  settings.setValue("UserCode", list);
                                  settings.setValue("UserCodeDefault", QStringLiteral("1234"));
                              
                                  settings.endGroup();
                                  settings.sync();
                                  qDebug() << __FUNCTION__ << 3 << settings.status();
                              
                                  // Read temp file
                                  QFile reader(tmpFile->fileName());
                                  reader.open(QIODevice::ReadOnly);
                                  qDebug() << __FUNCTION__ << "file:" << tmpFile->fileName();
                                  qDebug() << __FUNCTION__ << "content:" << reader.readAll();
                              
                                  // Close temp file
                                  tmpFile->close();
                              
                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by
                              #24

                              @tovax
                              https://doc.qt.io/qt-5/qtemporaryfile.html#details

                              Reopening a QTemporaryFile after calling close() is safe. For as long as the QTemporaryFile object itself is not destroyed, the unique temporary file will exist and be kept open internally by QTemporaryFile.

                              It is possible that the fact the file is kept open internally interferes with QSettings ability to write to the file. Create or hand QSettings your own filename in the same directory as QTemporaryFile would (QDir::tempPath()) and verify that succeeds.

                              Reduce your code to minimum. Remove the setIniCodec(), and get rid of the beginGroup() stuff and the QStringList, just write a single simple value while you test.

                              1 Reply Last reply
                              2
                              • Christian EhrlicherC Offline
                                Christian EhrlicherC Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on last edited by Christian Ehrlicher
                                #25

                                You can't open a file twice for read/write as @JonB correctly told you.

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                1 Reply Last reply
                                0
                                • tovaxT tovax

                                  Output:
                                  JCDemoAES::test 1 "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                                  JCDemoAES::test 2 QSettings::NoError
                                  JCDemoAES::test 3 QSettings::AccessError
                                  JCDemoAES::test file: "E:/JCShared/Projects/JCDemo/JCDemoAES/build-JCDemoAES-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/JCDemoAES.lwKvTB"
                                  JCDemoAES::test content: ""

                                      // Init temp file
                                      tmpFile = new QTemporaryFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                                      tmpFile->open();
                                      qDebug() << __FUNCTION__ << 1 << tmpFile->fileName();
                                  
                                      // Settings
                                      QSettings settings(tmpFile->fileName(), QSettings::IniFormat);
                                      qDebug() << __FUNCTION__ << 2 << settings.status();
                                      settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
                                      settings.beginGroup("GroupTest");
                                  
                                      QStringList list;
                                      list << QStringLiteral("0000") << QStringLiteral("1111") << QStringLiteral("2222") << QStringLiteral("3333");
                                      settings.setValue("UserCode", list);
                                      settings.setValue("UserCodeDefault", QStringLiteral("1234"));
                                  
                                      settings.endGroup();
                                      settings.sync();
                                      qDebug() << __FUNCTION__ << 3 << settings.status();
                                  
                                      // Read temp file
                                      QFile reader(tmpFile->fileName());
                                      reader.open(QIODevice::ReadOnly);
                                      qDebug() << __FUNCTION__ << "file:" << tmpFile->fileName();
                                      qDebug() << __FUNCTION__ << "content:" << reader.readAll();
                                  
                                      // Close temp file
                                      tmpFile->close();
                                  
                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by JonB
                                  #26

                                  @tovax
                                  I suspect you will find there is indeed a problem trying to use a QTemporaryFile for QSettings, for whatever reason. I refer you to https://www.mail-archive.com/interest@qt-project.org/msg32865.html

                                  I decided to look at writing the settings out to a QTemporaryFile,

                                  then just reading that data back in as a string, and then let the

                                  QTemporaryFile go out of scope and clean itself up. But according to the

                                  following test code, QSettings does not seem to play nicely with QTemporaryFile:

                                  I suggest you read that thread and look at his code. Read through all the responses (I did not.) I think you will find the final advice is to use your own temporary file instead.

                                  Christian EhrlicherC 1 Reply Last reply
                                  2
                                  • JonBJ JonB

                                    @tovax
                                    I suspect you will find there is indeed a problem trying to use a QTemporaryFile for QSettings, for whatever reason. I refer you to https://www.mail-archive.com/interest@qt-project.org/msg32865.html

                                    I decided to look at writing the settings out to a QTemporaryFile,

                                    then just reading that data back in as a string, and then let the

                                    QTemporaryFile go out of scope and clean itself up. But according to the

                                    following test code, QSettings does not seem to play nicely with QTemporaryFile:

                                    I suggest you read that thread and look at his code. Read through all the responses (I did not.) I think you will find the final advice is to use your own temporary file instead.

                                    Christian EhrlicherC Offline
                                    Christian EhrlicherC Offline
                                    Christian Ehrlicher
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #27

                                    @JonB I don't see why it's needed - all what is needs to be done is written here. Create a QTemporaryFile, open it, close it again, pass filename to QSettings and go ahead.

                                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                    Visit the Qt Academy at https://academy.qt.io/catalog

                                    JonBJ 1 Reply Last reply
                                    0
                                    • Christian EhrlicherC Christian Ehrlicher

                                      @JonB I don't see why it's needed - all what is needs to be done is written here. Create a QTemporaryFile, open it, close it again, pass filename to QSettings and go ahead.

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by JonB
                                      #28

                                      @Christian-Ehrlicher said in Why can't QSettings be written to QTemporaryFile:

                                      Create a QTemporaryFile, open it, close it again, pass filename to QSettings and go ahead.

                                      I believe the OP here tried that earlier (his post before last above) but got the same "access error", did he not? See his earlier code above:

                                          QTemporaryFile tmpFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                                          tmpFile.open();
                                          tmpFile.close();
                                      

                                      And probably that reference tried to. QTemporaryFile::close() does not close the file, reference the docs I quoted earlier, and I looked at the source and all it does it seek(0). Doubtless to do with keeping a handle into it until the QTemporaryFile goes out of scope, whereupon it will be closed and deleted. Hence if the fact that it is kept open (for all I know with exclusive access) is what stops QSettings working cannot be avoided.

                                      Christian EhrlicherC 1 Reply Last reply
                                      2
                                      • JonBJ JonB

                                        @Christian-Ehrlicher said in Why can't QSettings be written to QTemporaryFile:

                                        Create a QTemporaryFile, open it, close it again, pass filename to QSettings and go ahead.

                                        I believe the OP here tried that earlier (his post before last above) but got the same "access error", did he not? See his earlier code above:

                                            QTemporaryFile tmpFile(QStringLiteral("%1/%2").arg(QApplication::applicationDirPath(), QApplication::applicationName()), this);
                                            tmpFile.open();
                                            tmpFile.close();
                                        

                                        And probably that reference tried to. QTemporaryFile::close() does not close the file, reference the docs I quoted earlier, and I looked at the source and all it does it seek(0). Doubtless to do with keeping a handle into it until the QTemporaryFile goes out of scope, whereupon it will be closed and deleted. Hence if the fact that it is kept open (for all I know with exclusive access) is what stops QSettings working cannot be avoided.

                                        Christian EhrlicherC Offline
                                        Christian EhrlicherC Offline
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #29

                                        @JonB You're right. It can't work since completely closing a QTemporaryFile will delete it (as this is the usecase for this class).
                                        I also don't see a reason to use a QTemporaryFile here at all.

                                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                        Visit the Qt Academy at https://academy.qt.io/catalog

                                        jeremy_kJ 1 Reply Last reply
                                        1
                                        • Christian EhrlicherC Christian Ehrlicher

                                          @JonB You're right. It can't work since completely closing a QTemporaryFile will delete it (as this is the usecase for this class).
                                          I also don't see a reason to use a QTemporaryFile here at all.

                                          jeremy_kJ Offline
                                          jeremy_kJ Offline
                                          jeremy_k
                                          wrote on last edited by
                                          #30

                                          @tovax might have better luck using QTemporaryDir, and then creating a QFile with a known name within.

                                          Asking a question about code? http://eel.is/iso-c++/testcase/

                                          1 Reply Last reply
                                          1

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved