Forums

OverviewFelgo 2 Support (Qt 5) › Issue with fileUtils.copyFile with binary content

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #21505

    Flesh

    I have this short example of using the fileUtils.copyFile function, to copy a text file and an image or binary file, the image file gets converted to a text file, and I really need this function to work for binary files as well, so is there a way to get this to work?

     

    import Felgo 3.0
    import QtQuick 2.0
    import "Common.js" as Js
    
    App {
        // You get free licenseKeys from https://felgo.com/licenseKey
        // With a licenseKey you can:
        //  * Publish your games & apps for the app stores
        //  * Remove the Felgo Splash Screen or set a custom one (available with the Pro Licenses)
        //  * Add plugins to monetize, analyze & improve your apps (available with the Pro Licenses)
        //licenseKey: "<generate one from https://felgo.com/licenseKey>"
        property string assetsBinaryFilePath: ""
        property string assetsTextFilePath: ""
        Component.onCompleted: {
            assetsBinaryFilePath = Qt.resolvedUrl("../assets/felgo-logo.png");
            assetsTextFilePath = Qt.resolvedUrl("../assets/test.txt");
            console.debug("assetsBinaryFilePath=" + assetsBinaryFilePath)
        }
    
        NavigationStack {
    
            Page {
                title: qsTr("Test File Utilities")
    
                Grid {
                    id: grid
                    anchors.bottomMargin: 6
                    anchors.rightMargin: 6
                    anchors.leftMargin: 6
                    anchors.topMargin: 6
                    spacing: 6
                    rows: 3
                    columns: 2
                    anchors.fill: parent
    
                    AppButton {
                        id: appButtonWrite
                        width: 66
                        text: "Write"
                        implicitWidth: 66
                        clip: true
                        onClicked: {
                            Js.writeFile("Test/test.txt", "Test File Write Passed");
                            if (Js.existsFile("Test/test.txt")) {
                                appTextWrite.text = "Write test Passed";
                            } else {
                                appTextWrite.text = "Write test Failed";
                            }
                        }
                    }
    
                    AppText {
                        id: appTextWrite
                        text: qsTr("Write")
                        topPadding: 9
                    }
    
                    AppButton {
                        id: appButtonRead
                        width: 66
                        text: "Read"
                        implicitWidth: 66
                        clip: true
                        onClicked: {
                            appTextRead.text = Js.readFile("Test/test.txt");
                        }
                    }
    
                    AppText {
                        id: appTextRead
                        text: qsTr("Read")
                        topPadding: 9
                    }
    
                    AppButton {
                        id: appButtonCopy
                        width: 66
                        text: "Copy"
                        implicitWidth: 66
                        clip: true
                        onClicked: {
                            Js.copyFile(assetsBinaryFilePath, "Test/felgo-logo.png");
                            if (Js.existsFile("Test/felgo-logo.png")) {
                                appTextCopy.text = "copyFile: Binary test Passed";
                            } else {
                                appTextCopy.text = "copyFile: Binary test Failed";
                            }
                            Js.copyFile(assetsTextFilePath, "Test/test.txt");
                            if (Js.existsFile("Test/test.txt")) {
                                appTextCopy.text = appTextCopy.text + " Text test Passed";
                            } else {
                                appTextCopy.text = appTextCopy.text + " Text test Failed";
                            }
                        }
                    }
    
                    AppText {
                        id: appTextCopy
                        text: qsTr("Copy")
                        topPadding: 9
                    }
                }
            } // end Page
        } // end NavigationStack
    } // end App
    
    /*##^## Designer {
        D{i:0;autoSize:true;height:480;width:640}D{i:18;anchors_height:400;anchors_width:400}
    }
     ##^##*/
    

    and the Common.js

    /* ****************************************************************************
     * DebugMessageType: 0=None, 1=Basic, 2=Detailed
     */
    var myDebugMessageType = 1;
    function getDebugMessageType() {
        return myDebugMessageType;
    }
    function setDebugMessageType(debugMessageType) {
        myDebugMessageType = debugMessageType;
    }
    /* ****************************************************************************
     * https://felgo.com/doc/felgo-fileutils/
     */
    function writeFile(myFileName, fileContentAsString) {
        if (getDebugMessageType() === 1) {
            console.debug("writeFile(" + myFileName + "," + fileContentAsString + ")");
        }
        let fileName = fileUtils.storageLocation(FileUtils.AppLocalDataLocation, myFileName);
        return fileUtils.writeFile(fileName, fileContentAsString);
    }
    /* ****************************************************************************
     * https://felgo.com/doc/felgo-fileutils/
     */
    function readFile(myFileName) {
        if (getDebugMessageType() === 1) {
            console.debug("readFile(" + myFileName + ")");
        }
        let fileName = fileUtils.storageLocation(FileUtils.AppLocalDataLocation, myFileName);
        return fileUtils.readFile(fileName);
    }
    /* ****************************************************************************
     * https://felgo.com/doc/felgo-fileutils/
     * ../assets/felgo-logo.png
     */
    function copyFile(mySource, myDestination) {
        if (getDebugMessageType() === 1) {
            console.debug("copyFile(" + mySource + ", " + myDestination + ")");
        }
        let destinationFileName = fileUtils.storageLocation(FileUtils.AppLocalDataLocation, myDestination);
        if (getDebugMessageType() === 1) {
            console.debug("copyFile(" + mySource + ", " + destinationFileName + ")");
        }
        return fileUtils.copyFile(mySource, destinationFileName);
    }
    /* ****************************************************************************
     * https://felgo.com/doc/felgo-fileutils/
     */
    function existsFile(myFileName) {
        if (getDebugMessageType() === 1) {
            console.debug("existsFile(" + myFileName + ")");
        }
        let fileName = fileUtils.storageLocation(FileUtils.AppLocalDataLocation, myFileName);
        return fileUtils.existsFile(fileName);
    }
    

     

    #21516

    Günther
    Felgo Team

    Hi Jeffrey,

    we can have a look at your request as part of our Felgo Indie or Enterprise support.

    As an alternative, you can also integrate custom file handling with Qt C++ , e.g. using QFile:

    QFile::copy("/path/file", "/path/copy-of-file");

    Please note that available source and destination paths depend on the platform. You can also work with Qt StandardPaths to work on different default directories depending on the platform: https://doc.qt.io/qt-5/qstandardpaths.html

    Best,
    Günther

    #21519

    Flesh

    Let me get this right, are you saying that if I want to be able to read, write or copy graphic files, that I must replace your Library?

    If so, I can, it is not difficult, I can figure it out, even using your C++ Integration Example, which I have working great now, so it is easy to add this functionality, that is not my problem, nor my question, this is not about how to do this other ways, it is about your function, and how it is used, this is about the Felgo way of doing things.

    I read a post where someone said use Felgo if you want to write files in JavaScript, what I know about JavaScript, is that without a Certificate, you can not do much, and that did not pan out so well, so support was dropped for even adding that capability, in Web Browsers it makes no sense to have such a function, due to malware, and viruses, but this is a Qml App, and even in it you have to use C++, so this requires C++, and it would be nice if Felgo took care of all the Things, we Developers require, and reading, writing, and copying Graphic Files is at the top of my list right now.

    I think it would be best to address this issue now, so I at least understand your motives, mine is clear:

    https://github.com/Light-Wizzard/Calculator

    My goal of this project is to be able to get all the Commercial License and Support, and Felgo has been great about Free Support, but they need to understand that with most projects, this is not the case, once I sell my App, then I can pay for all the Licenses, and most people are in the same situation, it is called Life, we start off wanting to make a Living, or we do it as a Hobby, maybe School, who knows, the reason why People chose to use Felgo, is because of Support, without it, well it is not user-friendly for sure, so Free support today, means paid support tomorrow.

    My problem is not how to do this, it is how to do this the Felgo way, and if the Felgo policy is we do not support Graphics, that will make it clear, otherwise we have a Problem, this File Utilities only supports Text mode, and as far as I know, this is not a C++ Limit, what I do not know, is if it is an Android or IoS limit, and you guys know this, so even if I write my own function, I will still have that Limit, so I need to know if this is an OS limitation, or if I can expect to see this example run sometime in the near future, asking for Graphic Supports seems like a Reasonably Request, but this does not warrant paid support to fix an issue that is clearly either an OS Limitation, or the fact no one ever tested it or used it to copy graphic images, I do not know, I just know I need this function to work the way your website states it does, so either state it does not support Binary or Graphic Mode, and is Text only, then I will know to roll my own, and that will be known as the Felgo way, personally I like your Company, the name change is fine, but was not necessary, so please just fix this, so I can move on, since I seem to be the only one with this issue.

     

    My App creates Web Page Files, not using the DOM, but using HTML code, you will see the WebPageMaker.js file on the github site above, the concept is simple, I store the data in a database using LocalStorage, I then use that data, to create the Web Page(s), but I need to be able to manage the Images in LocalStorage, and then I need a way to upload that to my Web Server, so I can view them in a WebView, so I need the Ability to do this, and I might have to include my own C++ library to upload the file to my web server, not sure this can be done from Android or IoS, but if coping images is a Limit, then this becomes a Desktop only App, and that limits its sales, and actually makes it much harder to sale, so I came up with a solution to this case, as long as I can email the web pages, or even use the App to create HTML Emails, so if Felgo really wants to get into Apps, they need to support them, and that comes from knowing how its Customers, Free or Paid, which is really all a question of how successful their App is, thus it becomes your job, to ensure your functions at least work the way the examples show, and if it is showing only Text, then you need to make sure everyone knows why it is limited to Text only.

     

    I am not asking for Custom Functionality, can you image if an OS ships, and you can only read, write and copy Text files, well if it was created by Felgo, you do not want that limitation, trust me, the fact it has it now, makes me wonder why no one has made this an issue before.

     

    I have had issues in the past where I was just not doing something right, mainly due to lack of examples, so maybe this is just one of those cases, but I do not think so, this is acting like you only use Text mode to open the file, and if you have a way to turn on Binary mode, I do not see that option.

     

    Thanks, I hope I made myself clear, this request is about Felgo FileUtils and Text Only Mode, since I can not get them to work with Graphic Files.

     

    #21521

    Flesh

    I wrote this so I can get back to work while I am waiting for status.

    /* ****************************************************************************
     * copyFile uses Source File Name for output, make sure Destination ends in /
     * copyFile("/fullPath/FileName.ext", "FullPath/")
     */
    bool MyGlobalObject::copyFile(const QString &mySource, const QString &myDestination)
    {
        QString theSource = mySource;
        if (!isFile(theSource))
        {
            theSource = ":/" + mySource;
            if (!isFile(theSource))
            {
                qDebug() << "copyFile: source not found: " << theSource;
                return false;
            }
            else
            {
                qDebug() << "copyFile: source found: " << theSource;
            }
        }
        else
        {
            qDebug() << "copyFile: source found: " << theSource;
        }
        QString theFileName (QFileInfo(mySource).fileName());
        if (! QDir(myLocalStoragePath + "/" +  myDestination).exists())
        {
            qDebug() << "copyFile: mkdir: " << myLocalStoragePath + "/" +  myDestination;
            QDir().mkdir(myLocalStoragePath + "/" +  myDestination);
        }
        else
        {
            qDebug() << "copyFile: found theDestination QFileInfo: " << myLocalStoragePath + "/" +  myDestination;
        }
        if(QFile::copy(theSource , myLocalStoragePath + "/" + myDestination + theFileName))
        {
            qDebug() << "copyFile: Success";
            return true;
        }
        else
        {
            qDebug() << "copyFile: Failed: source=" << theSource << " destination=" << myLocalStoragePath + "/" +  myDestination + theFileName;
            return false;
        }
    }
    

     

    #21522

    Günther
    Felgo Team

    Hi Jeffrey,

    the FileUtils support was added with (V-Play) version 2.17.0. However, the copyFile implementation in the Felgo SDK does not support binary copy at the moment. We are working on making the SDK better for everyone in all areas, and of course adding this functionality is on our roadmap as well.

    We care a lot about all feedback, so the list of improvements and new features is thus quite long. We prioritize the tasks and feature requests internally, to improve Felgo as best as we can. For project-specific development support, or to handle requests and fixes as high-prio we offer support packages. The Felgo Pro plans also include some support hours, which you can use this way.

     

    I hope this makes things more clear!

     

    Best,
    Günther from Felgo

    #21525

    Flesh

    Thanks for the status, my function works, so I can move on for now, looking at my code, I understand why yours does not work, if I used a read and a write to copy, it would convert it to text in the process, so have a look at how I did it, it will work for both text and binary, and is much simpler and much faster, it is actually just one line of code, the rest is just checking for file exist, making directories, and I thought about rename, so I will update my code to check for a file name, and if missing, then use source name, so this function is very verbose, and not optimized, and does not rename, because I did not need that feature at the time, and will add a rename function also, but fix this issue as I stated, so for now it takes a source full path with file name, then strips the file name to use for the destination, which is just a relative path to LocalStorage which can be changed at any time, my example uses the C++ Integration example to run it, in main.cpp you need to add this code:

     

            // /home/USERNAME/.local/share/FelgoCpp/QML/OfflineStorage
            myGlobal->setLocalStoragePath(engine.offlineStoragePath());
    

     

    Where FelgoCpp is the name of the App, this will set the LocalStorage Path used in the function, this is not flexible, and in general not a good practice, it locks all writes to LocalStorage, which is what I wanted, and why I wrote it this way, you would have to write it so it is not locked down, but in reality, you can change the path anytime, by using this call, so it is not set in stone, and works better for most cases, since you only have to deal with relative paths, so as long as you change the setLocalStoragePath, you can use it as normal, its just method for setting the base path, so I do not have to work with absolute paths, since this runs on multiple platforms, and normally do not need to change this path once set, I just like this concept better.

     

    Maybe make a Roadmap Page that details all the features, as well as known bugs and work arounds and status, and other changes, such as Qt Versions supports, Android SDK and NDK versions supported, and other useful information, and also update the page(s) where this function is, and point to the Roadmap for what version we might find this fix, and how to do work arounds.

     

    I will update this function at this github repo:

    https://github.com/Light-Wizzard/Calculator/

    The file names are MyGlobalObject and MyQmlType, just like the original files, but camelCased, I will put them in a folder called cpp, I still need to make the changes and post them, I will try to get that done now, the app itself uses this function if you need at example, I will also update this file at:

    https://github.com/Light-Wizzard/FelgoCpp

    But I only maintain the first link.

    #21527

    Flesh

    I update this project: https://github.com/Light-Wizzard/FelgoCpp

     

    It takes the source, which can be a resource file, text or binary, and a destination folder, which can be blank if you want the file in the root of the folder, or it can contain a file name, in which case it does a rename. Note that I use localStoragePath or setLocalStoragePath to set the root path, that is prepended to the destination, this is because I set it to the local storage folder at startup, see above comment, you can set it to “” or empty to override this, but for the most part I do not like working with absolute folders, because of the different OS’s that this can run on, so if you are coping a lot of files to the same folder, it is easier to set the path once, then just use a relative path after that, but it is more flexible this way, also safer to use. The Default location is the same place that the Database will go; which is in the home folder in Linux, under ~/.local/share/FelgoCpp/QML/OfflineStorage

     

    There are 3 buttons to test a copy, rename (do not confuse this with the function rename, which does it in place), and a text file copy. The copy button has the destination folder of Test, with no file name, so the source file name will be used in this case, the copy rename has a file name in the destination, so it will be renamed to that name, and the last button does a text copy, so this function works with both Binary and Text formats.

    Give it a try, if you have any issues file a ticket, you are welcome to use the code, I have no claim to it, no copyright, I wrote it in hope of getting this feature fixed in Felgo, it is on the Roadmap, and I can wait now that I have something that works till then, so I make this available to those that need to copy Binary files now. Note that I only tested Copy so far, I need to write test for the other functions, also these test are not complete, I need to test file size, but that is not as simple as it sounds, since they can vary from one device to another, so it is only guaranteed to work on the same device, so I will have to find or write a file compare function, instead of relying on the function return, it is always better to compare the files for testing only, you would not want to deploy a file compare function, they are very slow, but could be added with another button, or you could just go look to see if the files were actually created, because Felgo’s copyFile returns true, and it does create a text file with the word png in it, a file compare would have determined the fail, the file size would have also given it away.

     

    I will work on a better way to target all the LocalStorage Paths, and enum them, making it easier to use LocalStorage paths, by using the enum, but in truth, I will probably go back to using your version when it comes out, so I hope you put more thought into this then I did.

     

    I have not tested this on Android or IoS, but it is a Qt solution, so it should work on all devices they support.

     

    #21528

    Flesh

    Does anyone know how to get the User, AppName and AppRoot in Felgo?

     

    I need these values to support LocalStoragePath here: https://github.com/Light-Wizzard/FelgoCpp/blob/master/cpp/myGlobalObject.cpp

    See functions for userName, appName and appRoot, these are used to fill the path variables, I got this concept from: https://felgo.com/doc/felgo-fileutils/

     

    AppName I can parse from the config.json, but there must be an easier way to get that, there might also be a way to get $USER, but how do I get AppRoot?

     

    Thanks

    #21531

    Flesh

    I figured out how to get QStandardPaths working, so the example now works similar to how copyFile does.

Viewing 9 posts - 1 through 9 (of 9 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support