Is there a way to check the modified date/time, or size of a file or folder?

146 views
Skip to first unread message

Warren Downs

unread,
Nov 25, 2014, 3:10:07 PM11/25/14
to androi...@googlegroups.com
Is there a way to check the modified date/time, or size of a file or folder?

I'm caching playback lengths of files in multiple folders and need to know when the cache should be updated.

I tried this test:

if (window.File && window.FileReader && window.FileList && window.Blob) { app.Alert('Great success! All the File APIs are supported.'); }
else { app.Alert('The File APIs are not fully supported.'); }

And it appears the Javascript File APIs are supported, but as far as I can tell, they only work with files selected by a Browser user.

That makes sense in a browser since you don't want some web page you visit to be able to access local files without the user selecting them.

However, for this context, I need to access thousands of files and it's not practical to require the user to select them all.  There must be a better way...

Warren Downs

unread,
Nov 25, 2014, 3:11:22 PM11/25/14
to androi...@googlegroups.com
(Credit: above test is from this informative page)

Dave Smart

unread,
Nov 26, 2014, 5:51:10 AM11/26/14
to androi...@googlegroups.com
Hi Warren,

We currently don't support that, but I think it would be a prime candidate to go on the 'Tell us what you want' list.  

If you get a few others to second you, then it will go higher on the priority :)

Warren Downs

unread,
Feb 12, 2015, 9:40:13 PM2/12/15
to androi...@googlegroups.com
I would like a method to find the free space available at a target path.  I need to remove my oldest cache files (that's why I need the file date too)

Steve Garman

unread,
Feb 13, 2015, 12:36:19 AM2/13/15
to androi...@googlegroups.com
In version 1.15 (released December 5th, 2014) the following methods were added.

app.GetFreeSpace(path), app.GetFileDate(path), app.GetFileSize(path)

Warren Downs

unread,
Feb 13, 2015, 12:08:37 PM2/13/15
to androi...@googlegroups.com
Perfect!  I had just installed updates but for some reason Play Store didn't give me the latest version until I updated again (I haven't been keeping up with the updates recently).  Now, if the documentation could be updated too...

Thanks!

Netpower8

unread,
Jun 27, 2016, 2:19:37 PM6/27/16
to DroidScript
I know this is an old thread. But i plan to use these functions to get filesize and available disk space for my filemanager/file picker... Etc. Also did not see these functions in the docs.

App.GetFreeSpace(path) <-- return free space in Gb byte count.

App.GetFileSize(path) <-- return file size in bytes count.

A bit confusing. I prefer both return in byte count format and let me do the convertion/computation for display or whatever purpose.

Unless there is a switch option to make both of them return in byte count.

Message has been deleted

Warren Downs

unread,
Jun 27, 2016, 3:04:09 PM6/27/16
to DroidScript

I agree it would be nice to have them both return bytes.  Perhaps you can submit this in the "Tell us what you want" thread.  However, I understand that free space is somewhat harder to calculate accurately, especially with some filesystems that retain a buffer of space which may be garbage collected later, or may be shared space, etc.  Thus, a byte count may not be particularly useful: Someone may try to fill the filesystem down to the last byte, but find it gets full faster than expected.  (I've had that happen to me).

Warren Downs

unread,
Jun 27, 2016, 3:13:58 PM6/27/16
to DroidScript

On a related note, I created a DiskUsage function to find the usage of an entire tree, as well as a DiskUsedSynchronous() function (more convenient for the programmer).  I found the latter to be slightly slower though, so take your pick:


var nn1=null;
var nn2=null;

var basePath="/sdcard/0RadioAudio"; // Customize this


//Called when application is started.

function OnStart() {

   app.SetDebugEnabled( false );

//Create a layout with objects vertically centered.

lay = app.CreateLayout( "linear", "VCenter,FillXY" );


//Create a button and add it to layout.

btn1 = app.CreateButton( "Check 1" );

     btn1.SetTextSize( 32 );

    btn1.SetOnTouch(onClick1);

   lay.AddChild( btn1 );


   //Create a button and add it to layout.

   btn2 = app.CreateButton( "Check 2" );

   btn2.SetTextSize( 32 );

   btn2.SetOnTouch(onClick2);

   lay.AddChild( btn2 );


   //Add layout to app.

   app.AddLayout( lay );


   alert("Free Space: "+app.GetFreeSpace(basePath)*1024*1024*1024);


   // alert(app.diskUsed("basePath)); // 2970561643

   var d=new Date();

   var result=app.diskUsedSyncronous(basePath+"/Logs");

   alert("diskUsedSyncronous="+result+" took "+((new Date()-d))/1000+" sec"); // 68681 took 0.249


    var d=new Date();

   var result=app.diskUsedSyncronous(basePath);

   alert("diskUsedSyncronous="+result+" took "+((new Date()-d))/1000+" sec"); // 68681 took 35.977

}


function onClick1(p1) {

   if(nn1 == null) {

       var d=new Date();

       nn1=new DiskUsage(basePath, function(result) { // 2970561643 took 53.067 w/o status

          nn1=null;

          alert('result='+result+" took "+((new Date()-d))/1000+" sec");

      }).check();

   }

   else app.ShowPopup('curTotal1='+nn1.total);

}


function onClick2(p1) {

   if(nn2 == null) {

       var d=new Date();

       nn2=new DiskUsage(basePath+"/Logs", function(result) { // 68681 took 4.421, .356 w/o status

          nn2=null;

          alert('result='+result+" took "+((new Date()-d))/1000+" sec");

      }).check();

   }

   else app.ShowPopup('curTotal2='+nn2.total);

}


function DiskUsage(path, callback) {

   this.path = path;

   this.callback = callback;

   this.q = [];

   this.total = 0;

   this.check = function(path) {

       if(path == null) { path=this.path; }

       if(!app.IsFolder(path)) { this.total += app.GetFileSize(path); }

       else {

           //app.ShowPopup('Listing folder: '+path);

           var files=app.ListFolder(path, null, null, "FullPath");

           //app.ShowPopup('Listed folder: '+path+'; '+files.length);

           for(var xa=0; xa<files.length; xa++) { this.q.push(files[xa]); }

       }

       //app.ShowPopup('Current Total('+this.path+')='+this.total);

       var nextPath=this.q.shift();

       if(nextPath != null) {

           setTimeout(function() { this.check(nextPath); }.bind(this), 0);

       }

       else { callback(this.total); }

   }

}


app.diskUsedSyncronous=function(path) {

   var files=app.ListFolder(path);

   var total=0;

   for(var xa=0; xa<files.length; xa++) {

       var subPath=path + "/" + files[xa];

       if(!app.IsFolder(subPath)) { total += app.GetFileSize(subPath); }

       else { total += app.diskUsedSyncronous(subPath); }

   }

   return total;

}






























































































}



Netpower8

unread,
Jun 27, 2016, 9:34:44 PM6/27/16
to DroidScript
Thanks for the disk usage. Will study it and maybe make my own implementing code (maybe improve it further if its possible).

Here's a code method from my (big plugin) library you might find it useful. Converts bytes size to relevant display size. Its set to last 2 decimal places but you could adjust it if you want more. The strFilesize() can handle an insane file size up to yottabyte. This method wont be obsolete anytime soon.

I use tabs instead of spaces. Just cut and paste the code.


// display the filesize in string with proper units
// option -> decimal (SI standard)
function strFilesize (size,option) {

// binary counting base 2
var usiz=1024;
// decimal "SI" international system
if (option!=undefined)
if ((option=="decimal") || (option=="si")) usiz=1000;

// determine unit display
var dsize=size; dunt=0;
while (dsize>usiz) { dunt++; dsize=dsize/usiz; }

// file size unit
var dunit="";
switch (dunt) {
case 0: dunit="B"; break; // Byte
case 1: dunit="K"; break; // Kilobyte
case 2: dunit="M"; break; // Megabyte
case 3: dunit="G"; break; // Gigabyte
case 4: dunit="T"; break; // Terrabyte
case 5: dunit="P"; break; // Petabyte
case 6: dunit="E"; break; // Exabyte
case 7: dunit="Z"; break; // Zettabyte
case 8: dunit="Y"; break; // Yottabyte
}
var dstr="";
if (dunt==0) dstr=dsize.toString()+dunit;
else {
if (usiz==1000) dunit=dunit.toLowerCase();
dstr=dsize.toFixed(2).toString()+dunit+"B";
}
return dstr
} // strFilesize (size,option)

Netpower8

unread,
Jun 27, 2016, 9:46:19 PM6/27/16
to DroidScript
Theres a small but significant difference between kB ("si" system base 10 1000=1kB) and KB ( base 2 1024=1KB). These can be found on the wiki page. I base the "si" conversion there.

Netpower8

unread,
Jul 8, 2016, 12:42:18 AM7/8/16
to DroidScript
After some further testing the method app.GetFreeSpace() always returns the internal sd card space. I pass an external sd folder path but it returned free space reading for the internal sd. Is there something wrong with the method? Or a bug?

Here's the line of code to test.

extsd=app.GetExternalFolder();
Alert('Disk space: '+app.GetFreeSpace(extsd);

Dave Smart

unread,
Jul 12, 2016, 5:27:58 PM7/12/16
to DroidScript
The GetFreespace call uses keywords not paths:-  "External" or "Internal"

Netpower8

unread,
Jul 15, 2016, 2:15:28 PM7/15/16
to DroidScript
Hi dave. Sorry for the late reply. Just tried ypur suggestion. It does not seem to work. Both 'internal' and 'external' keywords returns thebsame value which is internal sd card free space. Can some one else verify this. I tried it on version 1.34 of droidscript in case anuone is wondering about this.

Netpower8

unread,
Jul 15, 2016, 3:46:55 PM7/15/16
to DroidScript
Can somebody else try this out.

alert(app.GetFreeSpace("internal")+' '+app.GetFreeSpace("external"));

Check if both return the same number of free space. They are suppose to be different between internal sd card and external sd card. Thanks.

Alex F

unread,
Jul 15, 2016, 3:54:11 PM7/15/16
to DroidScript
It is different at my device:
1.5747948
1.5552635

Manuel Lopes

unread,
Jul 15, 2016, 6:53:40 PM7/15/16
to DroidScript
my space is same with other in beta

Netpower8

unread,
Jul 15, 2016, 11:21:58 PM7/15/16
to DroidScript
@alex F
Alaex i mention that my droidscript version is 1.34. Your in the beta group most likely your droidscript version is 1.35. Please when you make a post please make sure your droidscript version is the same with the PUBLIC version. Because it can cause a lot of confusion. I made a note that your version is different from ours so your replies may not be reliable. Because your version is different.

Netpower8

unread,
Jul 15, 2016, 11:26:21 PM7/15/16
to DroidScript
@alex f
Thanks for trying.

@everybody.
Please before trying it out. Please check your droidscript version. My version is 1.34.

Netpower8

unread,
Jul 15, 2016, 11:28:38 PM7/15/16
to DroidScript
@alex f
If you like to try again. Please do. But please make sure your droidscript version is 1.34 (public version) not the beta version
Message has been deleted

Alex F

unread,
Jul 16, 2016, 3:25:35 AM7/16/16
to DroidScript
I installed DroidScript_135a3
from androidscript.org/alpha
In about it it 1.34
If i install 134a7 it is 1.33

here the results again:
1.5824318
1.5629005

Dave Smart

unread,
Jul 16, 2016, 4:10:28 AM7/16/16
to DroidScript
It does not matter which version of DS you use as this code has not changed for ages.

Here is the Java source code for you to examine, maybe you can investigate this subject on StackOverflow or put this code in a plugin and experiment with alternative folders:-

     
  //Get amount of free space on internal or external sdcard in Gigs
 
public static float GetFreeSpace( String mode )
 
{
 
StatFs stat;
 
if( mode.toLowerCase().indexOf("extern") > -1 )
 stat
= new StatFs( Environment.getExternalStorageDirectory().getPath() );
 
else
 stat
= new StatFs( Environment.getDataDirectory().getPath() );


 
//One binary gigabyte equals 1,073,741,824 bytes.
 
double sdAvailSize = (double)stat.getAvailableBlocks() * (double)stat.getBlockSize();
 
return (float)(sdAvailSize / 1073741824);
 
}



Daniel Bolik

unread,
Jul 16, 2016, 5:39:03 AM7/16/16
to DroidScript
galaxy S7 running 6.0.1:
showing internal results for both.

Netpower8

unread,
Jul 16, 2016, 6:29:33 AM7/16/16
to DroidScript
Thanks dave. Will investigate further. Thanks

Netpower8

unread,
Jul 16, 2016, 6:53:35 AM7/16/16
to DroidScript
@daniel
Whats your android version?
Tried it on 2 device. Galaxy note 2 and tab 2 10 both results for internal and external show same value (internal sd)
My android version is 4.4.2 kitkat and 4.4.4 kitkat

Netpower8

unread,
Jul 16, 2016, 6:54:20 AM7/16/16
to DroidScript
Maybe its kitkat os. Will try a jelly bean os.

Daniel Bolik

unread,
Jul 16, 2016, 2:27:29 PM7/16/16
to DroidScript
I'm running android 6.0.1

Manuel Lopes

unread,
Jul 17, 2016, 6:12:20 AM7/17/16
to DroidScript
my android 4.4.2 both same internal size

Jem Easom

unread,
Jul 18, 2016, 11:47:19 AM7/18/16
to DroidScript
FWIW, on Android 5.1.1 running Droidscript 1.34 I do get two slightly different results... but I should get two very different results. I get two quite similar values, both just over 4.

Internal free space is reported as about 4.0 GB according to basic system utilities like Samsung's in built file browser, so internal appears to be working more or less as intended.

The problem is, the free space on my SD card should be more like 46 GB than 4.

Jem Easom

unread,
Jul 18, 2016, 11:55:37 AM7/18/16
to DroidScript
Oh, and having just tested it on my older HTC One (Android 4.4.3) that I'm using as a development device I get:

(for "Internal" / "External")
4.493328 / 4.395672

Which is interesting. Because the HTC One doesn't have space for an external SD card. Total Commander reports 4.3 GB of free space on internal storage.

Steve Garman

unread,
Jul 18, 2016, 12:21:19 PM7/18/16
to DroidScript
The problem here is terminology.
https://developer.android.com/guide/topics/data/data-storage.html

Android regards evey device as having external and internal storage, whether it has an removable drive or not.

The difference between internal and external is whether they are private or public, not where they are stored.

For a while, a removable card could be pretty much recognised as Secondary Storage, but that seems to have gone out the window recently.

Personally, I can't find anyway to separate my removeable card from fixed storage on my Marshmallow phone.

If I move a gigabyte of files from one to another, the free space of nothing gets bigger or smaller, even as reported by df.

Environment variable point to volumes that haven't existed since I was on lollipop.

I am sure the utility-writers have kept track of all this as it happens but my main source of information on fhis sort of thing, Stack Overflow, seems to be as confused as I am.

If anyone can find a source of information on dealing with this in Java, please post a link.

Dave has recently posted his current Java code for internal and external space.

If I could find a good suggestion for removable storage(which I suspect includes different algorithms for different API levels) I would be happy to try building a plugin function and ask others to test it on different devices.

If we can get a reliable plugin, I am sure Dave will be happy to absorb the code into DroidScript.

However, I can't currently find even any sensible suggestions.

sankarshan dudhate

unread,
Jul 19, 2016, 7:42:56 AM7/19/16
to DroidScript
My Micromax Unite 2, running 5.0 returns two different results.
I think I know what's behind it. On my Unite 2, "Internal" is where apps are installed and that's where apps store data. "External" is Phone Storage which is like a prey installed SD Card. In many modern ones ( including the successors of my device ), Phone Storage and Internal Storage the the same. Maybe, that's the reason behind the same results on some devices.
Reply all
Reply to author
Forward
0 new messages