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. Recommended way of passing file paths
QtWS25 Last Chance

Recommended way of passing file paths

Scheduled Pinned Locked Moved Solved General and Desktop
qdirqfilefilepathstrongly typedc++ qt
7 Posts 5 Posters 4.6k Views
  • 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.
  • C Offline
    C Offline
    christian_p
    wrote on 12 Jul 2022, 13:38 last edited by
    #1

    Hi!

    in the codebase I am working on, filepaths are passed as QString parameters most of the time. In some cases it is also a combination of QDir and QString.

    Examples:

    void foo(const QString &filename);
    void foo(const QDir pathToFile, const QString &filename);
    

    In order to use stronger types for the interfaces, I was considering the following types:

    • QString
    • QDir
    • QFile
    • QFileInfo
    • QUrl
    • std::filesystem::path

    QString
    This is the simplest, with the disadvantage that the type itself does not even tell that it is a path.

    QDir
    Compared to QString we know that a path is passed. But still, it could be a path to a directory or a path to a file. Also the name QDir seems to be misleading for passing paths to files.

    QFile
    For QFile it is clear that it is about a file, not about a directory. The thing I don't like about this is that it opens up other questions, such as "Should the passed file be opened before passing it? Does it need to exist?"

    QFileInfo
    This seems to fit better than QFile, as it is a more lightweight class which is not used for modifying the file.

    QUrl
    To me, this seems to be a too general-purpose class for passing file paths around.

    std::filesystem::path
    This looks like it is a good equivalent to QDir. What I like, is that the name does not suggest that it is a directory. However I am not sure if mixing Qt and std:: classes here could cause other troubles i.e. native file paths.

    Is there a recommended way for passing filepaths as parameters? Any thoughts are highly appreciated.
    My goal would be to have a guideline saying: When passing a path to a file, use class XYZ.

    J 1 Reply Last reply 12 Jul 2022, 13:40
    0
    • S Offline
      S Offline
      SimonSchroeder
      wrote on 13 Jul 2022, 07:11 last edited by
      #6

      I am not sure I have the perfect answer, but lets try to narrow it down (basically agreeing with you).

      QFile is a file and not a file path. It does inherit from QIODevice. It is meant for input/output and might even be total overkill to just store a file path. Don't use it for this.

      QFileInfo gives you more information about a file. You can split it up into its separate parts (base name, extension, path, etc.). Still, I don't see it as the right way to pass just a file path around. I personally use it only when I need the extra information on a file path provided as string.

      QUrl: Just as you said, it seems like it is overkill. Technically, it would be perfect to represent file paths. But, it does a lot more than just to represent file paths. This might actually confuse people as they might assume that their code needs to support more than just files.

      std::filesystem::path seems to be perfect when you are in STL world. As soon as you want to use it for opening a QFile, though, you have the whole trouble of converting std::string to QString. If you tend to use temporaries, you'll get into trouble sooner or later. If you have the choice, try to not mix std::string and QString. Stay in Qt land. (There is also the huge question if std::string is UTF-8 or in the user's locale. Within Qt this is handled correctly as QString knows the character encoding.)

      This leaves us with QString and QDir. I am not sure which one would be the best. I personally use QString. One thing to consider is that initially you have a QString (from user input or read from a file) which you then use to open a file. Under normal circumstances there is no reason to convert the original QString to a QDir just to pass it around and then convert it back to a QString, as QFile's constructor wants a QString again. QDir only comes in handy when you want to manipulate the path. Also note that Qt's file dialog returns a QString! So, Qt made up their mind to use a QString (though, this decision is quite old and there might be better options now).

      J 1 Reply Last reply 13 Jul 2022, 07:56
      0
      • C christian_p
        12 Jul 2022, 13:38

        Hi!

        in the codebase I am working on, filepaths are passed as QString parameters most of the time. In some cases it is also a combination of QDir and QString.

        Examples:

        void foo(const QString &filename);
        void foo(const QDir pathToFile, const QString &filename);
        

        In order to use stronger types for the interfaces, I was considering the following types:

        • QString
        • QDir
        • QFile
        • QFileInfo
        • QUrl
        • std::filesystem::path

        QString
        This is the simplest, with the disadvantage that the type itself does not even tell that it is a path.

        QDir
        Compared to QString we know that a path is passed. But still, it could be a path to a directory or a path to a file. Also the name QDir seems to be misleading for passing paths to files.

        QFile
        For QFile it is clear that it is about a file, not about a directory. The thing I don't like about this is that it opens up other questions, such as "Should the passed file be opened before passing it? Does it need to exist?"

        QFileInfo
        This seems to fit better than QFile, as it is a more lightweight class which is not used for modifying the file.

        QUrl
        To me, this seems to be a too general-purpose class for passing file paths around.

        std::filesystem::path
        This looks like it is a good equivalent to QDir. What I like, is that the name does not suggest that it is a directory. However I am not sure if mixing Qt and std:: classes here could cause other troubles i.e. native file paths.

        Is there a recommended way for passing filepaths as parameters? Any thoughts are highly appreciated.
        My goal would be to have a guideline saying: When passing a path to a file, use class XYZ.

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 12 Jul 2022, 13:40 last edited by
        #2

        @christian_p said in Recommended way of passing file paths:

        with the disadvantage that the type itself does not even tell that it is a path

        Doesn't the parameter name tell you that it should be a path/filename?
        Most of the time paths are handled as strings as there is no benefit in using anything else.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        C 1 Reply Last reply 12 Jul 2022, 14:05
        3
        • J jsulm
          12 Jul 2022, 13:40

          @christian_p said in Recommended way of passing file paths:

          with the disadvantage that the type itself does not even tell that it is a path

          Doesn't the parameter name tell you that it should be a path/filename?
          Most of the time paths are handled as strings as there is no benefit in using anything else.

          C Offline
          C Offline
          christian_p
          wrote on 12 Jul 2022, 14:05 last edited by
          #3

          @jsulm Yes, the filename tells you that. But I thought there might be a fitting type, so that I could rely on a strong type rather than on parameter names.
          In my experience by using QString it is hard to disambiguate, whether the parameter is just the base filename, or a file path (directory + filename).

          The things that got me thinking was methods that were passing a QDir and a QString for it's filename, or in some places there were structs holding a QDir and a QString.

          J G 2 Replies Last reply 12 Jul 2022, 14:09
          0
          • C christian_p
            12 Jul 2022, 14:05

            @jsulm Yes, the filename tells you that. But I thought there might be a fitting type, so that I could rely on a strong type rather than on parameter names.
            In my experience by using QString it is hard to disambiguate, whether the parameter is just the base filename, or a file path (directory + filename).

            The things that got me thinking was methods that were passing a QDir and a QString for it's filename, or in some places there were structs holding a QDir and a QString.

            J Offline
            J Offline
            JonB
            wrote on 12 Jul 2022, 14:09 last edited by JonB 7 Dec 2022, 14:10
            #4

            @christian_p
            You can do all this typing if you want, but my experience is like @jsulm says, it's not worth the effort over just using a QString, and getting your code right.

            I might store, say, a temperature. I'll just use a double (or float/int). You could then say "but the type doesn't tell me it's a temperature". And so on.

            1 Reply Last reply
            3
            • C christian_p
              12 Jul 2022, 14:05

              @jsulm Yes, the filename tells you that. But I thought there might be a fitting type, so that I could rely on a strong type rather than on parameter names.
              In my experience by using QString it is hard to disambiguate, whether the parameter is just the base filename, or a file path (directory + filename).

              The things that got me thinking was methods that were passing a QDir and a QString for it's filename, or in some places there were structs holding a QDir and a QString.

              G Offline
              G Offline
              Gojir4
              wrote on 12 Jul 2022, 15:23 last edited by
              #5

              @christian_p If you need to disambiguate you can still use QFileInfo at the time you use the path.

              QFileInfo fi(filepath);
              if ( fi.isFile() ) { 
                 ... 
              }
              
              1 Reply Last reply
              0
              • S Offline
                S Offline
                SimonSchroeder
                wrote on 13 Jul 2022, 07:11 last edited by
                #6

                I am not sure I have the perfect answer, but lets try to narrow it down (basically agreeing with you).

                QFile is a file and not a file path. It does inherit from QIODevice. It is meant for input/output and might even be total overkill to just store a file path. Don't use it for this.

                QFileInfo gives you more information about a file. You can split it up into its separate parts (base name, extension, path, etc.). Still, I don't see it as the right way to pass just a file path around. I personally use it only when I need the extra information on a file path provided as string.

                QUrl: Just as you said, it seems like it is overkill. Technically, it would be perfect to represent file paths. But, it does a lot more than just to represent file paths. This might actually confuse people as they might assume that their code needs to support more than just files.

                std::filesystem::path seems to be perfect when you are in STL world. As soon as you want to use it for opening a QFile, though, you have the whole trouble of converting std::string to QString. If you tend to use temporaries, you'll get into trouble sooner or later. If you have the choice, try to not mix std::string and QString. Stay in Qt land. (There is also the huge question if std::string is UTF-8 or in the user's locale. Within Qt this is handled correctly as QString knows the character encoding.)

                This leaves us with QString and QDir. I am not sure which one would be the best. I personally use QString. One thing to consider is that initially you have a QString (from user input or read from a file) which you then use to open a file. Under normal circumstances there is no reason to convert the original QString to a QDir just to pass it around and then convert it back to a QString, as QFile's constructor wants a QString again. QDir only comes in handy when you want to manipulate the path. Also note that Qt's file dialog returns a QString! So, Qt made up their mind to use a QString (though, this decision is quite old and there might be better options now).

                J 1 Reply Last reply 13 Jul 2022, 07:56
                0
                • S SimonSchroeder
                  13 Jul 2022, 07:11

                  I am not sure I have the perfect answer, but lets try to narrow it down (basically agreeing with you).

                  QFile is a file and not a file path. It does inherit from QIODevice. It is meant for input/output and might even be total overkill to just store a file path. Don't use it for this.

                  QFileInfo gives you more information about a file. You can split it up into its separate parts (base name, extension, path, etc.). Still, I don't see it as the right way to pass just a file path around. I personally use it only when I need the extra information on a file path provided as string.

                  QUrl: Just as you said, it seems like it is overkill. Technically, it would be perfect to represent file paths. But, it does a lot more than just to represent file paths. This might actually confuse people as they might assume that their code needs to support more than just files.

                  std::filesystem::path seems to be perfect when you are in STL world. As soon as you want to use it for opening a QFile, though, you have the whole trouble of converting std::string to QString. If you tend to use temporaries, you'll get into trouble sooner or later. If you have the choice, try to not mix std::string and QString. Stay in Qt land. (There is also the huge question if std::string is UTF-8 or in the user's locale. Within Qt this is handled correctly as QString knows the character encoding.)

                  This leaves us with QString and QDir. I am not sure which one would be the best. I personally use QString. One thing to consider is that initially you have a QString (from user input or read from a file) which you then use to open a file. Under normal circumstances there is no reason to convert the original QString to a QDir just to pass it around and then convert it back to a QString, as QFile's constructor wants a QString again. QDir only comes in handy when you want to manipulate the path. Also note that Qt's file dialog returns a QString! So, Qt made up their mind to use a QString (though, this decision is quite old and there might be better options now).

                  J Offline
                  J Offline
                  JonB
                  wrote on 13 Jul 2022, 07:56 last edited by JonB
                  #7

                  @SimonSchroeder
                  QDir is only for directories, not for files. So it is not a (suitable) candidate for general "file paths".

                  1 Reply Last reply
                  0

                  1/7

                  12 Jul 2022, 13:38

                  • Login

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