Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/r-lib/fs
Provide cross platform file operations based on libuv.
https://github.com/r-lib/fs
filesystem libuv r
Last synced: 3 months ago
JSON representation
Provide cross platform file operations based on libuv.
- Host: GitHub
- URL: https://github.com/r-lib/fs
- Owner: r-lib
- License: other
- Created: 2017-12-13T21:01:16.000Z (almost 7 years ago)
- Default Branch: main
- Last Pushed: 2024-06-19T15:56:26.000Z (5 months ago)
- Last Synced: 2024-07-26T22:46:44.475Z (3 months ago)
- Topics: filesystem, libuv, r
- Language: C
- Homepage: https://fs.r-lib.org/
- Size: 14.1 MB
- Stars: 362
- Watchers: 13
- Forks: 79
- Open Issues: 74
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
- jimsghstars - r-lib/fs - Provide cross platform file operations based on libuv. (C)
README
---
output: github_document
---```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
if (basename(getwd()) == "docs") {
knitr::opts_knit$set(root.dir = file.path(getwd(), ".."))
}
fs:::pkgdown_tmp(c("/tmp/filedd463d6d7e0f", "/tmp/filedd464dbb3467"))
```[![lifecycle](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#maturing)
[![R-CMD-check](https://github.com/r-lib/fs/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/fs/actions/workflows/R-CMD-check.yaml)
[![Codecov test coverage](https://codecov.io/gh/r-lib/fs/branch/main/graph/badge.svg)](https://app.codecov.io/gh/r-lib/fs?branch=main)**fs** provides a cross-platform, uniform interface to file system operations.
It shares the same back-end component as [nodejs](https://nodejs.org), the
[libuv](https://docs.libuv.org/en/v1.x/fs.html) C library, which brings the
benefit of extensive real-world use and rigorous cross-platform testing. The
name, and some of the interface, is partially inspired by Rust's [fs
module](https://doc.rust-lang.org/std/fs/index.html).## Installation
You can install the released version of **fs** from [CRAN](https://CRAN.R-project.org) with:
``` r
install.packages("fs")
```And the development version from [GitHub](https://github.com/) with:
```r
pak::pak("r-lib/fs")
```## Comparison vs base equivalents
**fs** functions smooth over some of the idiosyncrasies of file handling with
base R functions:* Vectorization. All **fs** functions are vectorized, accepting multiple paths
as input. Base functions are inconsistently vectorized.* Predictable return values that always convey a path. All **fs** functions
return a character vector of paths, a named integer or a logical vector, where
the names give the paths. Base return values are more varied: they are often
logical or contain error codes which require downstream processing.* Explicit failure. If **fs** operations fail, they throw an error. Base
functions tend to generate a warning and a system dependent error code. This
makes it easy to miss a failure.* UTF-8 all the things. **fs** functions always convert input paths to UTF-8 and
return results as UTF-8. This gives you path encoding consistency across OSes.
Base functions rely on the native system encoding.* Naming convention. **fs** functions use a consistent naming convention.
Because base R's functions were gradually added over time there are a number
of different conventions used (e.g. `path.expand()` vs `normalizePath()`;
`Sys.chmod()` vs `file.access()`).### Tidy paths
**fs** functions always return 'tidy' paths. Tidy paths
- Always use `/` to delimit directories
- never have multiple `/` or trailing `/`Tidy paths are also coloured (if your terminal supports it) based on the
file permissions and file type. This colouring can be customized or extended by
setting the `LS_COLORS` environment variable, in the same output format as [GNU
dircolors](https://www.bigsoft.co.uk/blog/index.php/2008/04/11/configuring-ls_colors).## Usage
**fs** functions are divided into four main categories:
* `path_` for manipulating and constructing paths
* `file_` for files
* `dir_` for directories
* `link_` for linksDirectories and links are special types of files, so `file_` functions
will generally also work when applied to a directory or link.```{r}
library(fs)# Construct a path to a file with `path()`
path("foo", "bar", letters[1:3], ext = "txt")# list files in the current directory
dir_ls()# create a new directory
tmp <- dir_create(file_temp())
tmp# create new files in that directory
file_create(path(tmp, "my-file.txt"))
dir_ls(tmp)# remove files from the directory
file_delete(path(tmp, "my-file.txt"))
dir_ls(tmp)# remove the directory
dir_delete(tmp)
```**fs** is designed to work well with the pipe, though because it is a
minimal-dependency infrastructure package it doesn't provide the pipe itself.
You will need to attach [magrittr](https://magrittr.tidyverse.org) or similar.```{r}
library(magrittr)paths <- file_temp() %>%
dir_create() %>%
path(letters[1:5]) %>%
file_create()
pathspaths %>% file_delete()
```**fs** functions also work well in conjunction with other
[tidyverse](https://www.tidyverse.org/) packages, like
[dplyr](https://dplyr.tidyverse.org) and [purrr](https://purrr.tidyverse.org).Some examples...
```{r}
suppressMessages(
library(tidyverse))
```Filter files by type, permission and size
```{r}
dir_info("src", recurse = FALSE) %>%
filter(type == "file", permissions == "u+r", size > "10KB") %>%
arrange(desc(size)) %>%
select(path, permissions, size, modification_time)
```Tabulate and display folder size.
```{r}
dir_info("src", recurse = TRUE) %>%
group_by(directory = path_dir(path)) %>%
tally(wt = size, sort = TRUE)
```Read a collection of files into one data frame.
`dir_ls()` returns a named vector, so it can be used directly with
`purrr::map_df(.id)`.```{r}
# Create separate files for each species
iris %>%
split(.$Species) %>%
map(select, -Species) %>%
iwalk(~ write_tsv(.x, paste0(.y, ".tsv")))# Show the files
iris_files <- dir_ls(glob = "*.tsv")
iris_files# Read the data into a single table, including the filenames
iris_files %>%
map_df(read_tsv, .id = "file", col_types = cols(), n_max = 2)file_delete(iris_files)
```## Feedback wanted!
We hope **fs** is a useful tool for both analysis scripts and packages.
Please open [GitHub issues](https://github.com/r-lib/fs) for any feature requests or bugs.In particular, we have found non-ASCII filenames in non-English locales on
Windows to be especially tricky to reproduce and handle correctly. Feedback
from users who use commonly have this situation is greatly appreciated.## Code of Conduct
Please note that the fs project is released with a
[Contributor Code of Conduct](https://fs.r-lib.org/dev/CODE_OF_CONDUCT.html).
By contributing to this project, you agree to abide by its terms.