creating a virtual file system with JIMFS
Asked Answered
J

4

5

I'd like to use Google's JIMFS for creating a virtual file system for testing purposes. I have trouble getting started, though.

I looked at this tutorial: http://www.hascode.com/2015/03/creating-in-memory-file-systems-with-googles-jimfs/

However, when I create the file system, it actually gets created in the existing file system, i. e. I cannot do:

Files.createDirectory("/virtualfolder");

because I am denied access.

Am I missing something?

Currently, my code looks something like this:

Test Class:

FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
Path vTargetFolder = fs.getPath("/Store/homes/linux/abc/virtual");

TestedClass test = new TestedClass(vTargetFolder.toAbsolutePath().toString());

Java class somewhere:

targetPath = Paths.get(targetName);
Files.createDirectory(targetPath);

// etc., creating files and writing them to the target directory

However, I created a separate class just to test JIMFS and here the creation of the directory doesnt fail, but I cannot create a new file like this:

FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
Path data = fs.getPath("/virtual");
Path dir = Files.createDirectory(data);
        
Path file = Files.createFile(Paths.get(dir + "/abc.txt")); // throws NoSuchFileException

What am I doing wrong?

Jiggermast answered 10/4, 2015 at 12:10 Comment(0)
C
16

The problem is a mix of Default FileSystem and new FileSystem.

Problem 1:

Files.createDirectory("/virtualfolder"); 

This will actually not compile so I suspect you meant:

Files.createDirectory( Paths.get("/virtualfolder"));

This attempts to create a directory in your root directory of the default filesystem. You need privileges to do that and probably should not do it as a test. I suspect you tried to work around this problem by using strings and run into

Problem 2:

Lets look at your code with comments

FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
// now get path in the new FileSystem
Path data = fs.getPath("/virtual");    
// create a directory in the new FileSystem
Path dir = Files.createDirectory(data);
// create a file in the default FileSystem 
// with a parent that was never created there
Path file = Files.createFile(Paths.get(dir + "/abc.txt")); // throws NoSuchFileException

Lets look at the last line:

dir + "/abc.txt"            >> is the string "/virtual/abc.txt"
Paths.get(dir + "/abc.txt") >> is this as path in the default filesystem

Remember the virtual filesystem lives parallel to the default filesystem. Paths have a filesystem and can not be used in an other filesystem. They are not just names.

Notes:

  • Working with virtual filesystems avoid the Paths class. This class will always work in the default filesystem. Files is ok because you have create a path in the correct filesystem first.

  • if your original plan was to work with a virtual filesystem mounted to the default filesystem you need bit more. I have a project where I create a Webdav server based on a virtual filesystem and then use OS build in methods to mount that as a volume.

Chiang answered 25/6, 2015 at 13:15 Comment(0)
A
2

Seems like instead of

Path file = Files.createFile(Paths.get(dir + "/abc.txt"));

You should be doing

Path file = Files.createFile(dir.resolve("/abc.txt"))

This way, the context of dir (it's filesystem) is not lost.

Ahumada answered 28/2, 2020 at 21:55 Comment(0)
B
0

In your shell try ls / the output should contain the "/virtual" directory.

If this is not the case which I suspect it is then:

The program is masking a:

java.nio.file.AccessDeniedException: /virtual/abc.txt

In reality the code should be failing at Path dir = Files.createDirectory(data);

But for some reason this exception is silent and the program continues without creating the directory (or thinking it has) and attempts to write to the directory that doesn't exist

Leaving a misleading java.nio.file.NoSuchFileException

Broder answered 10/4, 2015 at 12:51 Comment(2)
you're right, those cheeky bastards :D Well, how does this classify as virtual file system then? Or am I missing something?Jiggermast
No. A file or directory created in a virtual filesystem will not just show up in the default filesystem. This are separate entities.Chiang
P
0

I suggest you use memoryfilesystem instead. It has a much more complete implementation than Jimfs; in particular, it supports POSIX attributes when creating a "Linux" filesystem etc.

Using it, your code will actually work:

try (
    final FileSystem fs = MemoryFileSystemBuilder.newLinux()
        .build("testfs");
) {
    // create a directory, a file within this directory etc
}
Plier answered 14/4, 2015 at 10:47 Comment(3)
No. The suggested filesystem is a good one but can not "fix" the mixup of the 2 filesystems.Chiang
@Chiang what are you talking about?Plier
The original question did not have a problem creating directories in a JimFS filesystem. He mixed up the default filesystem with the virtual filesystem, see problem 2 in my answer. If you replace jimfs with memoryfs in the first line you get the same problem.Chiang

© 2022 - 2024 — McMap. All rights reserved.