Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Does Ti.Filesystem.File.exists() always return true?

I'm using the following setup:

  • Titanium Mobile 1.7.1 stable
  • Titanium Studio 1.0.1.201106171427
  • Mac OS 10.6.7 x86 with all updates
  • JRE 1.6.0_26-b03-384-10M3425

Here is some code to reproduce the problem. Note that in my app, 'app.js' does exist while the second two files do not exist.

var file1 = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'app.js');
    file2 = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'asdfkjfsad.js');
    file3 = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'fakedir/fakefile.js');

Ti.API.debug(file1.exists());
Ti.API.debug(file2.exists());
Ti.API.debug(file3.exists());

And the output:

[INFO] true
[INFO] true
[INFO] true

Is there some way I can correct this? I read somewhere that Titanium Mobile 1.6 returned true for Ti.Filesystem.File.exists() only if a file was readable. Is it something to do with the permissions on the Resources directory?

I actually can't continue working on my app until I get an answer about this, so I'd really appreciate some help.

— asked July 15th 2011 by Stephen Tellis
  • bug
  • file
  • filesystem
  • mobile
2 Comments
  • While I'm at it, I should also mention that the documentation on the File object is very incomplete, and, in some cases, incorrect. I tried and failed to find the source for TiFileProxy class on Github.

    — commented July 15th 2011 by Stephen Tellis
  • It occurred to me to redo the tests with some changes. First I called getFile() with a single argument (the same path, just with concatenation instead of a comma). I got all trues again.

    But then I tried this:

    var file1 = Ti.Filesystem.getFile('app.js');
        file2 = Ti.Filesystem.getFile('/asdfkjfsad.js');
        file3 = Ti.Filesystem.getFile('fakefile.js');
    
    Ti.API.debug(file1.exists());
    Ti.API.debug(file2.exists());
    Ti.API.debug(file3.exists());
    

    And this time I got odd results:

    [INFO] true
    [INFO] false
    [INFO] true
    
    — commented July 15th 2011 by Stephen Tellis

5 Answers

  • Tried this on my own system and…

    var drawing2 = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'drawing.jpg');
    var drawing3 = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'drawing3.jpg');
    var drawing4 = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'drawing.jpg');
    
    Ti.API.debug(drawing2.exists());
    Ti.API.debug(drawing3.exists());
    Ti.API.debug(drawing4.exists());
    

    Gave an output of

    [DEBUG] 1
    
    [DEBUG] 0
    
    [DEBUG] 1
    

    Which is correct, i tried playing with other real and fake files and if works every time.
    Maybe you need to define Ti as Titanium in the path?
    or maybe you have missed out the applicationDataDirectory to get the resources url?

    Hope this helps!

    — answered July 15th 2011 by adam kearsley
    permalink
    2 Comments
    • Ti by default seems to be a valid reference to Titanium in my app and has always worked.

      After further investigation, it seems like the problem only occurs when finding out if files exist in the Resources directory. I'm using the code in a wrapper for Titanium.include that helps me debug.

      PS: It's odd that your copy of Titanium uses the correct logging level (DEBUG in this case) when mine does not, and it never has. It just outputs [INFO] for everything. What OS and Titanium SDK are you using?

      — commented July 15th 2011 by Stephen Tellis
    • Im running Titanium Studio, build: 1.0.1.201106171427
      SDK 1.7.1
      OS: OSX Snow Leopard.

      — commented July 15th 2011 by adam kearsley
  • I also got the problem. And i need it to include JS files when they exist.

    On my side it looks like this:

    var file1 = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, 'js/'+filename1);
    var file2 = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, 'js/'+filename2);
    
    if (file1.exists()) {
      Titanium.include('js/'+filename1);
    } else if (file2.exists()) {
      Titanium.include('js/'+filename2);
    }
    

    On iPhone OS it runs fine, but on android it does not run and file1 always exists even if it is not there…

    Does someone have an idea for a solution?

    — answered July 18th 2011 by Torsten Stelling
    permalink
    1 Comment
    • Titanium SDK version: 1.7.1 (06/21/11 14:28 1293a6d)

      — commented July 18th 2011 by Torsten Stelling
  • For other people having trouble with this, I wrote a quick function to replicate .exists() functionality. I haven't tested it extensively and can't guarantee that it works in every situation, so if you're going to use it, you should be comfortable modifying it and/or fixing bugs that you find.

    Make sure to configure the rootDir variable at the top if you don't want it to default to the resources directory!

    // Obviously this shouldn't be global when you actually use it.
    var fileExists = function(path)
    {
        /**
         * Configure this variable according to your own needs. Keep in mind that
         * if a protocol is provided, this value will be overridden. A path
         * separator
         */
        var rootDir = Ti.Filesystem.resourcesDirectory;
    
        if(typeof path === 'string')
        {
            var protocol   = [], // container for protocol matches, such as "app://"
                pathArray  = [], // path split into elements by / or \
                pathLength = 0,  // pathArray.length
                fileName   = '', // the base name of the path
                fileDir    = '', // the directory that contains the file name
                fileList   = []; // list of files in fileDir
    
            /**
             * Some Titanium-provided directory strings have "app://" at the
             * beginning of them. We need to remove that we can split
             * our path more easily below.
             */
            protocol = path.match(/^\w+:\/+/);
    
            if(protocol && protocol.length > 0)
                // since a protocol was provided, the path is absolute
                rootDir = protocol[0];
    
            var rootPattern = new RegExp("^"+rootDir, 'i');
            path.replace(rootPattern, '');
    
            pathArray  = path.split(/[\\\/]/);
            pathLength = pathArray.length;
    
            if(pathLength > 0)
            {
                if(pathLength > 1)
                {
                    // get file name without Array.pop(), which is destructive
                    fileName = pathArray[pathLength-1];
    
                    // get the directory of the file and join with the system separator
                    fileDir  = pathArray.slice(0, pathLength-1).join(Ti.Filesystem.separator);
                }
                else if(pathLength === 1)
                {
                    // the directory is root
                    fileName = pathArray[0];
                }
    
                fileList = Ti.Filesystem.getFile(rootDir+fileDir).getDirectoryListing();
    
                if(typeof fileList.length === 'number')
                {
                    var listLength = fileList.length;
    
                    if(listLength > 0)
                        for(var i = 0; i < listLength; i++)
                            if(fileList[i] === fileName)
                                return true;
                }
            }
        }
    
        return false;
    };
    
    — answered July 18th 2011 by Stephen Tellis
    permalink
    0 Comments
  • I have found the same problem and have now opened a JIRA ticket as this is definitely a bug with the latest stable release of the SDK 1.7.2
    http://jira.appcelerator.org/browse/TC-211.

    Once this is fixed, I will post a message back in here.

    — answered August 16th 2011 by Matthew ORiordan
    permalink
    0 Comments
  • Hi guys,

    So it seems this bug STILL hasn't been fixed and still always returns true…

    As a workaround, I guess we can use the file.size property to assess if it is larger than a specified 'minimum' to determine whether it does / doesn't contain what you expect?

    — answered February 11th 2013 by Robin Williams
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.