Unable to use os.listdir() on a VFS mounted multifile

Hello p3d’s,

I’m trying to create a multifile explorer for Panda3D (i’ll keep you updated about it :wink:) to make easier multifile manipulations (add files, folders, encrypt, add certificate, etc.).

I need to get the content of multifiles. To do so, I mount the file on the virtual file system and then I use the os.listdir() function via the direct.stdpy.file.os module…
It worked well when I did this on a single main.py file.

The problem is that the project structure of the archiver is more complex (it’s not that much :roll_eyes:):

mfExplorer
      - src/
          | --------- MfHandler.py # It's where I mount and check file's content
          | --------- Some other GUI and utilities modules
	      | --------- __init__.py
      - main.py

In this case, in the MfHandler.py file, I’m able to mount the file (from arbitrary path), load models contained in the multifile, but I cannot call the os.listdir() function that throws a FileNotFoundError error (it seems that it’s calling the builtin python os module because here is the output if I do print(os) :thinking: : <module 'os' from 'C:\\Users\\valentin\\AppData\\Local\\Programs\\Python\\Python39\\lib\\os.py'>, but I’m using the panda’s version in all my modules [I did check everything]).
That error occurs whenever I call that function in another module than the main one.

Here is a simplified example to reproduce the issue: https://www.martinscoding.xvelta.com/p3dissues/multifile_error_osdir.zip

Do you have any idea ?
Any help would be appreciated :innocent: !

Thanks in advance for your help :grinning: !

Hmm… Have you experimented with any of the methods provided by the VirtualFileSystem class?

I’m not sure offhand of which might be applicable, but it might be worth looking at “glob”, “findAllFiles”, and “scanDirectory”, based on a quick look at the API page.

There seem to be multiple problems with your code:

  1. it would appear that one needs to import listdir from direct.stdpy.file, not os; accordingly, one needs to call listdir(directory) instead of os.listdir(directory);

  2. there doesn’t seem to be a test directory within your multifile, but I do see a test2 directory, so you could call listdir with that one as argument.

So your print_multifile.py could look like this:

# coding:utf-8
from direct.stdpy.file import listdir
from panda3d.core import VirtualFileSystem


def printMultifileContent():
    path = "test.mf"

    vfs=VirtualFileSystem.getGlobalPtr()
    print("Mounting. Please wait... ")
    if vfs.mount(path, ".", VirtualFileSystem.MF_read_only):
        print(vfs.getCwd())
        print(vfs.getMounts())
        vfs.lsAll("test2")

        print("Using listdir...")
        print(listdir("test2"))

Hope this helps. :slight_smile:

2 Likes

Thanks @Epihaius, it works perfectly now👌.

1 Like