Introduction to fscache package

fscache helps handle a user file system cache for an application or package.

Let us suppose we have an application called myapp for which we want to save text content on disk in order to reload it later. With fscache we will create a Cache object that will place our content in a standard location, according to the poperating system we are running on, and help us manage it (save, load, delete, place in sub-folders, etc).

Initializing the cache

First, start by loading the package:

library(fscache)

Then we create a Cache instance:

my.folder.cache <- file.path(tempdir(), 'my.cache') # We would usually use here a relative path like 'myapp'
cache <- Cache$new(my.folder.cache)

For this vignette, we use a temporary folder as our cache folder. Since the temporary folder is an absolute path, the user HOME folder will not be used. However, usually, in practice, we give the name of our application as the cache folder to create. The folder will be created in the user space, inside the standard path defined for the operating system, given by the tools package.

If we look at the cache object, we can see the exact location of the created cache folder:

cache
#> Cache class
#>   The main cache folder is at /tmp/RtmpXImciY/my.cache.
#>   The cache is readable.
#>   The cache is writable.

We also see that the cache is both readable and writable by default. However we may block either read access or write access for our cache, using the setReadable() and setWritable() methods. It is sometimes useuful for testing purposes.

The full path to the cache folder is also accessible through the getFolder() method:

cache$getFolder()
#> [1] "/tmp/RtmpXImciY/my.cache"

Saving and loading content

Let us save the following text contents into the cache:

x <- c('abc', 'def', 'ghi')

For that we use the saveContents() method:

cache$saveContents(x, c('a.txt', 'b.txt', 'c.txt'))
#> INFO  [18:25:10.917] Save 3 contents to /tmp/RtmpXImciY/my.cache.

We have saved our three strings into three files inside the cache folder. Since all three files have the same extension, we may have used the suffix parameters to avoid repeating the extension in the filenames:

cache$saveContents(x, c('a', 'b', 'c'), suffix='.txt')
#> INFO  [18:25:10.964] Save 3 contents to /tmp/RtmpXImciY/my.cache.

Note that fscache does not complain that the files already exist. It overrides them silently.

We can list the existing files inside the cache folder with the following command:

cache$globPaths(suffix='.txt')
#> [1] "/tmp/RtmpXImciY/my.cache/a.txt" "/tmp/RtmpXImciY/my.cache/b.txt"
#> [3] "/tmp/RtmpXImciY/my.cache/c.txt"

Loading the contents from cached files is done with the loadContents() method, which returns a character vector with names set with the file paths:

cache$loadContents(c('a', 'b', 'c'), suffix='.txt')
#> INFO  [18:25:10.983] Load 3 contents, from /tmp/RtmpXImciY/my.cache.
#> /tmp/RtmpXImciY/my.cache/a.txt /tmp/RtmpXImciY/my.cache/b.txt 
#>                          "abc"                          "def" 
#> /tmp/RtmpXImciY/my.cache/c.txt 
#>                          "ghi"

Note that if we try to load the content from non-existing file, a NA value will be returned:

cache$loadContents(c('a', 'b', 'c', 'd'), suffix='.txt')
#> INFO  [18:25:10.994] Load 4 contents, from /tmp/RtmpXImciY/my.cache.
#> /tmp/RtmpXImciY/my.cache/a.txt /tmp/RtmpXImciY/my.cache/b.txt 
#>                          "abc"                          "def" 
#> /tmp/RtmpXImciY/my.cache/c.txt /tmp/RtmpXImciY/my.cache/d.txt 
#>                          "ghi"                             NA

Prior to loading contents, we may test the existence of files inside the cache folder, with the pathsExist() method:

cache$pathsExist(c('a', 'b', 'c', 'd'), suffix='.txt')
#> [1]  TRUE  TRUE  TRUE FALSE

Using sub-folders

Instead of putting them directly inside the cache folder, files may be put inside sub-folders to organize them.

Here we put our contents into three new files inside a sub-folder named "mysub" that will be automatically created:

cache$saveContents(x, c('x', 'y', 'z'), suffix='.txt', sub.folder='mysub')
#> INFO  [18:25:11.010] Create cache folder "/tmp/RtmpXImciY/my.cache/mysub".
#> INFO  [18:25:11.011] Save 3 contents to /tmp/RtmpXImciY/my.cache/mysub.

Let us look a the content of our sub-folder:

cache$globPaths(sub.folder='mysub')
#> [1] "/tmp/RtmpXImciY/my.cache/mysub/x.txt"
#> [2] "/tmp/RtmpXImciY/my.cache/mysub/y.txt"
#> [3] "/tmp/RtmpXImciY/my.cache/mysub/z.txt"

Deleting files

Files may be deleted from the cache, as in the following command:

cache$delPaths(c('a', 'c'), suffix='.txt')

The remaining files are:

cache$globPaths()
#> [1] "/tmp/RtmpXImciY/my.cache/b.txt"

For deleting files inside a sub-folder, use the sub.folder parameter:

cache$delPaths('y', suffix='.txt', sub.folder='mysub')

For deleting a sub-folder with all its content, use the delFolder() method:

cache$delFolder('mysub')
#> INFO  [18:25:11.043] Erasing sub-folder "mysub".

Copying or moving files into the cache

It is also possible to move or copy files that reside outside the cache folder, into the cache folder.

Let us create a file:

my.file <- tempfile('my.file', fileext='.txt')
cat('My text content.', file=my.file)
my.file
#> [1] "/tmp/RtmpXImciY/my.file7f20b3e3a1095.txt"

To move it into the cache, we use the importFiles() method:

cache$importFiles(my.file, action='move')
#> INFO  [18:25:11.058] move 1 files to /tmp/RtmpXImciY/my.cache.
#> INFO  [18:25:11.059] Done importing files.

For copying, we would have set action to "copy".

Here the new list of cached files:

cache$globPaths()
#> [1] "/tmp/RtmpXImciY/my.cache/b.txt"                   
#> [2] "/tmp/RtmpXImciY/my.cache/my.file7f20b3e3a1095.txt"

Erasing the cache

If we wish to delete the whole cache folder with all its content, we have to run the following command:

cache$erase()
#> INFO  [18:25:11.075] Erasing cache "/tmp/RtmpXImciY/my.cache".