Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QFile in AppDataLocation not readable/writeable
Forum Updated to NodeBB v4.3 + New Features

QFile in AppDataLocation not readable/writeable

Scheduled Pinned Locked Moved Solved Mobile and Embedded
9 Posts 3 Posters 1.1k Views 2 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.
  • SeDiS Offline
    SeDiS Offline
    SeDi
    wrote on last edited by SeDi
    #1

    I am unable to read from or write to a file in QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) under Android - and I don't have a clue, why.
    Isn't AppDataLocation supposed to be inside the sandbox, allowing me to access my files?

    Am I mistaken? Is there any better location to use?
    Or am I doing anything very stupid here?

    This is my code:

        auto appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        auto fileName = appDataPath + QStringLiteral("/products.json");
    
        QFile saveFile(fileName);
        saveFile.setPermissions(QFileDevice::ReadOther|QFileDevice::WriteOther);
        qDebug()<<"fileName: "<<fileName;
        qDebug()<<"saveFile.exists(): "<<saveFile.exists();
        qDebug()<<"saveFile.isOpen(): "<<saveFile.isOpen();
        qDebug()<<"saveFile.isReadable(): "<<saveFile.isReadable();
        qDebug()<<"saveFile.isWritable(): "<<saveFile.isWritable();
        qDebug()<<"saveFile.errorString() before: "<<saveFile.errorString();
    
        if (!saveFile.open(QIODevice::ReadWrite)) {
            qWarning("Couldn't open products file.");
            qDebug()<<"saveFile.errorString() after: "<<saveFile.errorString();
            return false;
        }
        saveFile.write(QJsonDocument(saveProductsObj).toJson(QJsonDocument::Indented));
        saveFile.close();
        return true;
    

    This is my output:

    fileName:  "/data/user/0/de.herrdiel.punktlandung/files/products.json"
    saveFile.exists():  true
    saveFile.isOpen():  false
    saveFile.isReadable():  false
    saveFile.isWritable():  false
    saveFile.errorString() before:  "Unknown error"
    Couldn't open products file.
    saveFile.errorString() after:  "Permission denied"
    
    
    J.HilkJ 1 Reply Last reply
    0
    • SeDiS SeDi

      I am unable to read from or write to a file in QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) under Android - and I don't have a clue, why.
      Isn't AppDataLocation supposed to be inside the sandbox, allowing me to access my files?

      Am I mistaken? Is there any better location to use?
      Or am I doing anything very stupid here?

      This is my code:

          auto appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
          auto fileName = appDataPath + QStringLiteral("/products.json");
      
          QFile saveFile(fileName);
          saveFile.setPermissions(QFileDevice::ReadOther|QFileDevice::WriteOther);
          qDebug()<<"fileName: "<<fileName;
          qDebug()<<"saveFile.exists(): "<<saveFile.exists();
          qDebug()<<"saveFile.isOpen(): "<<saveFile.isOpen();
          qDebug()<<"saveFile.isReadable(): "<<saveFile.isReadable();
          qDebug()<<"saveFile.isWritable(): "<<saveFile.isWritable();
          qDebug()<<"saveFile.errorString() before: "<<saveFile.errorString();
      
          if (!saveFile.open(QIODevice::ReadWrite)) {
              qWarning("Couldn't open products file.");
              qDebug()<<"saveFile.errorString() after: "<<saveFile.errorString();
              return false;
          }
          saveFile.write(QJsonDocument(saveProductsObj).toJson(QJsonDocument::Indented));
          saveFile.close();
          return true;
      

      This is my output:

      fileName:  "/data/user/0/de.herrdiel.punktlandung/files/products.json"
      saveFile.exists():  true
      saveFile.isOpen():  false
      saveFile.isReadable():  false
      saveFile.isWritable():  false
      saveFile.errorString() before:  "Unknown error"
      Couldn't open products file.
      saveFile.errorString() after:  "Permission denied"
      
      
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      Hi @SeDi

      IIRC QStandardpaths gives you the correct path, that you're supposed to use, but on mobile you'll have to mkDir the path first, because the directory doesn't exist yet


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      3
      • SeDiS Offline
        SeDiS Offline
        SeDi
        wrote on last edited by SeDi
        #3

        Hi @J-Hilk, thanks for your input!
        You've said in QFile in AppDataLocation not readable/writeable:

        on mobile you'll have to mkDir the path first, because the directory doesn't exist yet

        The directory does exist for sure, though, because the file does exist there already:

        saveFile.exists():  true
        

        Interesting catch from just now: removing the file does work, afterwards writing (to non-existing file) works, thus re-creating the removed file.

        This workaround actually removes my problem, but not my questions. Partly dumb questions, perhaps:
        - Do I have to remove a file before just overwriting it?
        - Why isn't the existing file marked as readable?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          Did you check the permissions right after finishing the write to the file and having closed it ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • SeDiS Offline
            SeDiS Offline
            SeDi
            wrote on last edited by
            #5

            Thank you for yor time @SGaist! You've said in QFile in AppDataLocation not readable/writeable:

            Did you check the permissions right after finishing the write to the file and having closed it ?

            Now this is interesting. "Normally", after writing it, the file has these permissions:

            • QFileDevice::WriteUser 0x0200: The file is writable by the user.
            • QFileDevice::ReadUser 0x0400: The file is readable by the user.
            • QFileDevice::WriteOwner 0x2000: The file is writable by the owner of the file.
            • QFileDevice::ReadOwner 0x4000: The file is readable by the owner of the file.

            I've just realized, that the problem only seems to occur after importing the file from outside the application. After import, it has the permissions:

            • QFileDevice::ReadOther 0x0004 The file is readable by anyone.
            • QFileDevice::ReadGroup 0x0040 The file is readable by the group.
            • QFileDevice::ReadUser 0x0400 The file is readable by the user.
            • QFileDevice::ReadOwner 0x4000 The file is readable by the owner of the file.

            In spite of that, I can still remove it!

            I now set more specific permissions to the file:

            saveFile.setPermissions(QFlags<QFileDevice::Permission>(
                       QFileDevice::WriteUser
                     | QFileDevice::ReadUser
                     | QFileDevice::WriteOwner
                     | QFileDevice::ReadOwner));
            

            Additionally I still remove and re-write as explained above.
            I've yet to see the problem again. Seems to work.

            Would you regard first removing and then re-writing the file as a somewhat clean or recommendable solution?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              How are you importing it ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • SeDiS Offline
                SeDiS Offline
                SeDi
                wrote on last edited by
                #7

                I get the location with QML FileDialog (importing QtQuick.Dialogs 1.3)

                FileDialog {
                                            id: importProductFileDialog
                                            title: "Choose new product file"
                                            folder: shortcuts.home
                                            onAccepted: {
                                                var result = controller.importGenericList(importProductFileDialog.fileUrl)
                                            }
                                        }
                

                My import is done then from c++ controller class, specifically with this line:

                newFile.copy(QStringLiteral("products.json")
                

                The full method:

                bool Controller::importGenericList(QString fileUrl) {
                
                    #ifndef Q_OS_ANDROID
                        fileUrl = QUrl(fileUrl).toLocalFile();
                    #endif
                    QFile newFile(fileUrl);
                    QFile oldFile(QStringLiteral("products.json"));
                    QFile backupFile(QStringLiteral("productsOLD.json"));
                
                    // first we check if the new file is parseable
                    ProductTableModel* testModel = new ProductTableModel();
                    bool isValidFile = testModel->readDataFromFile(newFile.fileName());
                    testModel->deleteLater();
                    if (!isValidFile) {
                        qDebug()<<"not valid!";
                        return false;
                    }
                
                    // remove an old backup (if applicable)
                    backupFile.remove();
                    // make a backup of our product list
                    oldFile.copy(backupFile.fileName());
                    // NO check for backup success, as there may have been no products file in the first place.
                    // delete our product list.
                    oldFile.remove();
                
                    // try copying
                    if (!newFile.copy(QStringLiteral("products.json"))) {
                        // not successful? try to repair:
                        QFile rescueFile("productsOLD.json");
                        rescueFile.copy(QStringLiteral("products.json"));
                        return false;
                    }
                
                    auto model = qobject_cast<ProductTableModel*>(m_productModel->sourceModel());
                    if (!model) {
                        qWarning()<<"product model could not be found!";
                        Q_ASSERT(model);
                        return false;
                    }
                
                    // read the new file into the our actual model
                    model->readDataFromFile();
                    m_productModel->setSortRole(Qt::UserRole +3);
                    m_productModel->invalidate();
                    return true;
                }
                
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Ok, then what about the permissions of the source file ? Here may be the issue.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  SeDiS 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    Ok, then what about the permissions of the source file ? Here may be the issue.

                    SeDiS Offline
                    SeDiS Offline
                    SeDi
                    wrote on last edited by
                    #9

                    @SGaist said in QFile in AppDataLocation not readable/writeable:

                    Here may be the issue.

                    And there, indeed, it was.
                    After import, setting

                    file.setPermissions(QFileDevice::WriteUser|QFileDevice::ReadUser|QFileDevice::WriteOwner|QFileDevice::ReadOwner);
                    

                    does the trick.
                    Thank you very much, @J-Hilk and @SGaist!

                    1 Reply Last reply
                    2

                    • Login

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