{"id":20474187,"url":"https://github.com/marschall/memoryfilesystem","last_synced_at":"2025-05-14T14:07:37.647Z","repository":{"id":5915824,"uuid":"7135155","full_name":"marschall/memoryfilesystem","owner":"marschall","description":"An in memory implementation of a JSR-203 file system","archived":false,"fork":false,"pushed_at":"2025-02-02T10:42:44.000Z","size":2247,"stargazers_count":287,"open_issues_count":27,"forks_count":38,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-07T23:02:55.082Z","etag":null,"topics":["java","jsr-203"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marschall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-12-12T18:12:30.000Z","updated_at":"2025-04-28T17:55:24.000Z","dependencies_parsed_at":"2024-11-15T14:30:58.101Z","dependency_job_id":"b828b921-8a9b-4c1d-aa2c-f3be8e0adae9","html_url":"https://github.com/marschall/memoryfilesystem","commit_stats":{"total_commits":699,"total_committers":13,"mean_commits":53.76923076923077,"dds":0.0844062947067239,"last_synced_commit":"e4ac8c16c84926e2393337ca6460c013a9fd91e8"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fmemoryfilesystem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fmemoryfilesystem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fmemoryfilesystem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fmemoryfilesystem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marschall","download_url":"https://codeload.github.com/marschall/memoryfilesystem/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254159194,"owners_count":22024558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jsr-203"],"created_at":"2024-11-15T14:28:32.094Z","updated_at":"2025-05-14T14:07:37.641Z","avatar_url":"https://github.com/marschall.png","language":"Java","readme":"Memory File System [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/marschall/memoryfilesystem/badge)](https://api.securityscorecards.dev/projects/github.com/marschall/memoryfilesystem) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/memoryfilesystem/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/memoryfilesystem) [![Javadocs](https://www.javadoc.io/badge/com.github.marschall/memoryfilesystem.svg)](https://www.javadoc.io/doc/com.github.marschall/memoryfilesystem)\n==================\nAn in memory implementation of a [JSR-203](http://jcp.org/en/jsr/detail?id=203) (Java 7) file system for testing purposes.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.marschall\u003c/groupId\u003e\n    \u003cartifactId\u003ememoryfilesystem\u003c/artifactId\u003e\n    \u003cversion\u003e2.8.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nVersions 2.x require Java 8+, versions 1.x require Java 7+.\n\nToC\n---\n* [Supported Features](#supported)\n* [Not Supported Features](#not-supported)\n* [FAQ](#faq)\n* [Usage](#usage)\n* [Guidelines for Testable File Code](#guidelines-for-testable-file-code)\n\nSupported\n---------\n* \u003ccode\u003eSeekableByteChannel\u003c/code\u003e\n* \u003ccode\u003eFileChannel\u003c/code\u003e\n* \u003ccode\u003eAsynchronousFileChannel\u003c/code\u003e\n* \u003ccode\u003eInputStream\u003c/code\u003e\n* \u003ccode\u003eOutputStream\u003c/code\u003e\n* \u003ccode\u003eBasicFileAttributeView\u003c/code\u003e, \u003ccode\u003eBasicFileAttributes\u003c/code\u003e\n* \u003ccode\u003eDosFileAttributeView\u003c/code\u003e, \u003ccode\u003eDosFileAttributes\u003c/code\u003e\n* \u003ccode\u003ePosixFileAttributeView\u003c/code\u003e, \u003ccode\u003ePosixFileAttributes\u003c/code\u003e\n* \u003ccode\u003eUserDefinedFileAttributeView\u003c/code\u003e\n* \u003ccode\u003eFileLock\u003c/code\u003e\n* \u003ccode\u003eDirectoryStream\u003c/code\u003e\n* \u003ccode\u003ePathMatcher\u003c/code\u003e\n  * glob\n  * regex\n* \u003ccode\u003eStandardCopyOption\u003c/code\u003e\n  * REPLACE_EXISTING\n  * COPY_ATTRIBUTES\n  * ATOMIC_MOVE\n* \u003ccode\u003eStandardOpenOption\u003c/code\u003e\n  * READ\n  * WRITE\n  * TRUNCATE_EXISTING\n  * CREATE\n  * DELETE_ON_CLOSE\n* symbolic links\n* symbolic link loop detection\n* hard links\n* switching the current user\n* switching the current group\n* DOS access checks\n* POSIX access checks\n* [umask](http://en.wikipedia.org/wiki/Umask)\n* `java.net.URL` starting with version 2.6.0. Requires any of the following actions\n  * Add `-Djava.protocol.handler.pkgs=com.github.marschall.memoryfilesystem` command line parameter\n  * Call `URL.setURLStreamHandlerFactory(new MemoryURLStreamHandlerFactory())`\n\nNot Supported\n-------------\n* `FileChannel#map`, `MappedByteBuffer` has final methods that call native methods\n* `SecureDirectoryStream`\n* `WatchService`\n* `FileTypeDetector`, has to be accessible by system classloader\n* faked DOS attribute view under Linux, totally unspecified\n* `UnixFileAttributeView`, [sun package](http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html), totally unspecified\n* `AclFileAttributeView`\n* files larger than 16MB\n* `StandardOpenOption`\n  * SPARSE\n  * SYNC\n  * DSYNC\n* maximum path length checks\n* hard link count checks\n\nVersion History\n---------------\n\nVersion 2 requires Java 8 and supports nanosecond time resolution. Automatically set mtime, atime and ctime will have nanosecond resolution only with Java 9+.\n\nVersion 1 requires Java 7.\n\nFAQ\n---\n### Does it have bugs?\nQuite likely.\n\n### What license is it?\nMIT\n\n### Does it support concurrent access?\nYes, but hasn't been subject to much scrutiny so bugs are likely. \n\n### Does it work with the zipfs provider?\nIt should work fine in JDK 8+.\n\n### Is it production ready?\nNo, it's only intended for testing purposes.\n\n### Does it scale?\nNo\n\n### Does it have any dependencies?\nNo\n\n### Does it support JDK 9?\nYes, starting from version 0.9.2 the JAR is a [modular](https://github.com/marschall/memoryfilesystem/blob/master/src/main/java/module-info.java) JAR with the name `com.github.marschall.memoryfilesystem`. The only module required besides `java.base` is `java.annotation` which is [optional](http://openjdk.java.net/projects/jigsaw/spec/issues/#CompileTimeDependences).\n\n### Does it work with Spring?\nYes, there is a POJO factory bean. It has been tested with Spring 3.2.4 but since it doesn't have any dependencies on Spring it should work with every ⩾ 2.x version. You can of course also use Java configuration or any other IoC container.\n\n### Does it work with OSGi?\nYes, it's a bundle and there's an activator that prevents class loader leaks. You should use the `MemoryFileSystemBuilder` instead of `FileSystems#newFileSystem` because `ServiceLoader` uses the thread context class loader. `MemoryFileSystemBuilder` avoids this by passing in the correct class loader.\n\n### Does it do any logging?\nNo\n\n### But I want all my file access logged\nA logging file system that wraps an other file system is the best way to do this.\n\n### How can I set the current user?\nUse `CurrentUser#useDuring`\n\n### How can I set the current group?\nUse `CurrentGroup#useDuring`\n\n### Can I run Lucene?\nYes, starting with version 2.1 running Lucene is supported, see [LuceneRegressionTest](https://github.com/marschall/memoryfilesystem/blob/master/src/test/java/com/github/marschall/memoryfilesystem/LuceneRegressionTest.java). It is important you use the `#newLinux()` method on `MemoryFileSystemBuilder`.\n\n### Are there other similar projects?\nYes, [google/jimfs](https://github.com/google/jimfs), [sbridges/ephemeralfs](https://github.com/sbridges/ephemeralfs), [pbzdyl/memoryfs](https://github.com/pbzdyl/memoryfs), [sylvainjuge/memoryfs](https://github.com/sylvainjuge/memoryfs), [twh270/jmemfs](https://github.com/twh270/jmemfs) and [nidi3/j7sf](https://github.com/nidi3/j7sf) seem similar.\n\n### How does this compare to ShrinkWrap NIO.2?\n[ShrinkWrap NIO.2](http://exitcondition.alrubinger.com/2012/08/17/shrinkwrap-nio2/) seems to be mainly targeted at interacting with a ShrinkWrap archive instead of simulating a file system.\n\nUsage\n-----\n### Getting Started\nThe easiest way to get started is to use the `MemoryFileSystemBuilder`\n\n```java\ntry (FileSystem fileSystem = MemoryFileSystemBuilder.newEmpty().build()) {\n  Path p = fileSystem.getPath(\"p\");\n  System.out.println(Files.exists(p));\n}\n```\n\nIt's important to know that at any given time there can only be one memory file system with a given name. Any attempt to create a memory file system with the name of an existing one will throw an exception. \n\nThere are other `new` methods on `MemoryFileSystemBuilder` that allow you to create different file systems and other methods that allow you to customize the file system.\n\n### Next Steps JUnit 4\nYou probably want to create a JUnit `TestRule` that sets up and tears down a file system for you. A rule can look like this\n\n```java\nfinal class FileSystemRule implements TestRule {\n\n  private FileSystem fileSystem;\n\n  FileSystem getFileSystem() {\n    return this.fileSystem;\n  }\n\n  @Override\n  public Statement apply(final Statement base, Description description) {\n    return new Statement() {\n\n      @Override\n      public void evaluate() throws Throwable {\n        fileSystem = MemoryFileSystemBuilder.newEmpty().build();\n        try {\n          base.evaluate();\n        } finally {\n          fileSystem.close();\n        }\n      }\n\n    };\n  }\n\n}\n```\n\nand is used like this\n```java\npublic class FileSystemTest {\n\n  @Rule\n  public final FileSystemRule rule = new FileSystemRule();\n\n  @Test\n  public void lockAsyncChannel() throws IOException {\n    FileSystem fileSystem = this.rule.getFileSystem();\n\n    Path path = fileSystem.getPath(\"sample.txt\");\n    assertFalse(Files.exists(path));\n  }\n\n}\n```\n\nIt's important to note that the field holding the rule must be public.\n\n### Next Steps JUnit 5\nYou probably want to create a JUnit extension that sets up and tears down a file system for you. A rule can look like this\n\n```java\nclass FileSystemExtension implements BeforeEachCallback, AfterEachCallback {\n\n  private FileSystem fileSystem;\n\n  FileSystem getFileSystem() {\n    return this.fileSystem;\n  }\n\n  @Override\n  public void beforeEach(ExtensionContext context) throws Exception {\n    this.fileSystem = MemoryFileSystemBuilder.newEmpty().build(\"name\");\n  }\n\n  @Override\n  public void afterEach(ExtensionContext context) throws Exception {\n    if (this.fileSystem != null) {\n      this.fileSystem.close();\n    }\n  }\n}\n```\n\nand is used like this\n```java\nclass FileSystemTest {\n\n  @RegisterExtension\n  final FileSystemExtension extension = new FileSystemExtension();\n\n  @Test\n  public void lockAsyncChannel() throws IOException {\n    FileSystem fileSystem = this.extension.getFileSystem();\n\n    Path path = fileSystem.getPath(\"sample.txt\");\n    assertFalse(Files.exists(path));\n  }\n\n}\n```\n\nIf you're using an IoC container for integration tests check out the section below.\n\n### Spring\nThe `com.github.marschall.memoryfilesystem.MemoryFileSystemFactoryBean` provides integration with Spring.\n\n```xml\n  \u003cbean id=\"memoryFileSystemFactory\"\n      class=\"com.github.marschall.memoryfilesystem.MemoryFileSystemFactoryBean\"/\u003e\n\n  \u003cbean id=\"memoryFileSystem\" destroy-method=\"close\"\n    factory-bean=\"memoryFileSystemFactory\" factory-method=\"getObject\"/\u003e\n```\n\nYou can of course also write a [Java Configuration](http://static.springsource.org/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-java) class and a `@Bean` method that uses `MemoryFileSystemBuilder` to create a new file system. Or a CDI class with a `@Produces` method that uses `MemoryFileSystemBuilder` to create a new file system. \n\nBy setting the \"type\" attribute to \"windows\", \"linux\" or \"macos\" you can control the semantics of the created file system.\n\nFor more information check out the [Javadoc](http://www.javadoc.io/doc/com.github.marschall/memoryfilesystem).\n\nGuidelines for Testable File Code\n================================\n\nThe following guidelines are designed to help you write code that can easily be tested using this project. In general code using the old `File` API has to moved over to the new Java 7 API.\n\n* Inject a `Path` or `FileSystem` instance into the object doing the file handling. This allows you to pass in an instance of a memory file system when testing and an instance of the default file system when running in production. You can always get the file system of a path by using `Path#getFileSystem()`.\n* Don't use `File`, `FileInputStream`, `FileOutputStream`, `RandomAccessFile` and `Path#toFile()`. These classes are hard wired to the default file system.\n  * Use `Path` instead of `File`.\n  * Use `SeekableByteChannel` instead of `RandomAccessFile`. Use `Files#newByteChannel` to create an instance of `SeekableByteChannel`.\n  * Use `Files#newInputStream` and `Files#newOutputStream` to create `InputStream`s and `OutputStream`s on files.\n  * Use `FileChannel#open` instead of `FileInputStream#getChannel()`, `FileOutputStream#getChannel()`, or `RandomAccessFile#getChannel()` to create a `FileChannel`\n* Use `FileSystem#getPath(String, String...)` instead of `Paths#get(String, String...)` to create a `Path` instance because the latter creates an instance on the default file system.\n\n\nBuilding\n--------\n\nThe project requires that JAVA_HOME is set to a JDK 11 or a [toolchain](https://maven.apache.org/guides/mini/guide-using-toolchains.html) with version 11 is set up.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarschall%2Fmemoryfilesystem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarschall%2Fmemoryfilesystem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarschall%2Fmemoryfilesystem/lists"}