uos.stat(): differentiate between file and folder

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
User avatar
jcf
Posts: 60
Joined: Wed Mar 03, 2021 11:14 am

uos.stat(): differentiate between file and folder

Post by jcf » Mon Aug 09, 2021 3:31 pm

I have not found any possibility to differentiate between file and folder, like os.path.isdir() does.
My idea is to use uos.stat()
However there is not much documentation.
So I tried this:

Code: Select all

>>> import uos
>>> uos.stat('SD')						# this is a folder
(16384, 0, 0, 0, 0, 0, 536892856, 0, 0, 0)
>>> uos.stat('filetools.py')				# this is a file
(32768, 0, 0, 0, 0, 0, 1507, 1609470216, 1609470216, 1609470216)
Can I use the difference in the first return value to make the difference? Does that always work?

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: uos.stat(): differentiate between file and folder

Post by Roberthh » Mon Aug 09, 2021 5:12 pm

The answer to your question is yes. 32768 tells, that it is a file.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: uos.stat(): differentiate between file and folder

Post by dhylands » Mon Aug 09, 2021 10:15 pm

Note that the value is actually a collection of bit fields, so to check properly you should just be checking for a particular bit value.

So for example:

Code: Select all

val = uos.stat(filename)
if val[0] & 0x4000 != 0:
    print('This is a directory')
if val[0] & 0x8000 != 0:
    print('This is a file')

User avatar
jcf
Posts: 60
Joined: Wed Mar 03, 2021 11:14 am

Re: uos.stat(): differentiate between file and folder

Post by jcf » Tue Aug 10, 2021 8:28 am

That's exactly what I thought.
So I wrote these short functions that seem to work fine:

Code: Select all

def is_folder(filename):
    if uos.stat(filename)[0] & 0x4000:
        return True
    else:
        return False
    
def list_folders(folder):
    # list subfolders of folder
    l = uos.listdir(folder)
    folders = [f for f in l if is_folder(f)]
    return folders
Is there any official documentation on the stat function?

hippy
Posts: 130
Joined: Sat Feb 20, 2021 2:46 pm
Location: UK

Re: uos.stat(): differentiate between file and folder

Post by hippy » Tue Aug 10, 2021 1:39 pm

jcf wrote:
Tue Aug 10, 2021 8:28 am
Is there any official documentation on the stat function?
Not a lot that I found. Just "Get the status of a file or directory" at https://docs.micropython.org/en/latest/library/uos.html

My go to reference is an earlier post by Roberthh - viewtopic.php?t=5291

Given the RP2 has a reasonable amount of Flash I believe there is a case which can be made to add os.path.isfile() etc for that port. This would really help Python programmers coming from Pi to migrate to MicroPython.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: uos.stat(): differentiate between file and folder

Post by dhylands » Tue Aug 10, 2021 11:24 pm

The values 0x8000 and 0x4000 correspond to the values stat.IFREG and stat.IFDIR from CPython:

Code: Select all

Python 3.7.4 (default, Aug 13 2019, 15:17:50) 
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import stat
>>> hex(stat.S_IFREG)
'0x8000'
>>> hex(stat.S_IFDIR)
'0x4000'
>>> 
This page: https://docs.python.org/3/library/stat.html has the documentation for the return values from os.stat() used by CPython.
https://docs.python.org/3/library/stat.html

For the FAT filesystem, S_IFREG and S_IFDIR are the only two flags that would ever be non-zero (st_mode also includes the user/group/other permissions, so read-only files might get mapped in there somehow).

Post Reply