Deleting orphaned files

How do I delete a file in QML + JS?

A snippet of my javascript code, that makes a screenshot and saves it:

    function commitSave(slot) {
        if ((slot === null ) || (slot < 0 )) {
            _saving = false
            return false
        }
        gameRoot.grabToImage(function(result) {
            if (result) {
                var filename    = "save_" + slot + ".jpg"
                var dir         = StandardPaths.data
                result.saveToFile(dir + "/" + filename)
                Components.SaveManager.commitSave(filename)
            }
            _saving = false
        }, Qt.size(thumbWidth, thumbHeight))
    }

There seems to be no way to delete these screenshots. When I delete a slot, the image file is orphaned.
To me, it seems strange to be able to be able to write a file in javascript, but not to be able to delete the file.

    function deleteSave(slot) {
        if (!_db) initialize()

        _db.transaction(function(tx) {
            tx.executeSql("DELETE FROM saves WHERE slot = ?", [slot])
        })

        //var filename    = StandardPaths.data + "/save_" + slot + ".jpg"
        //if (Qt.fileExists(filename)) Qt.removeFile(filename)

        // Yeah, it seems to be impossible to delete files
        // So we can create screenshots, but when we delete a save
        // the images are orphaned.
        // This sucks
        return
    }

If I am missing something, please let me know.

Yes, apart from the few builtins like grabToImage/saveToFile, managing files is a bit cumbersome in QML only. You might even say not really supported.

The usual ways to deal with file handling is:

  • do it from Qt/C++
  • use pyotherside and do it in Python
  • use XmlHttpRequest with GET or PUT methods to read and write. It may be possible to DELETE as well but I never tried it.
  • use a QML plugin/import like Nemo.FileManager or Sailfish.FileManager

If you really want to stay only QML, try

import Nemo.FileManager 1.0

function remove(file) {
  FileEngine.deleteFiles([ file ]) // takes a list
}

FileEngine can do other useful things, like cut+paste, create dirs etc.

XmlHttpRequest is really handy if you need to read / write text content like JSON. Binary files are really painful though.

3 Likes

I’ll import the filemanager plugin. Thanks!

EDIT:

I don’t think I can import FileManager, because of Harbour compliance.

For now, I do accept the orphaned files. I use a reduced size for the screenshots, for use as little thumbnails, so they are tens of kilobytes each. I really don’t like it, but even the worst realistic use case will result in about 1 MB of orphaned files maximum, where 0.1 or 0.2 MB is more typical.

Maybe I will rewrite the whole project into C++ some time, and I will fix it then. And maybe I will not.

What you could do, as you seem to be using locastorage, convert the snapped image into a data: URL and put that in the database.

For smallish images that should work fine.

1 Like