• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

R/H08-Dec-2021-2,4981,236

build/H03-May-2022-

inst/H08-Dec-2021-676546

man/H08-Dec-2021-1,3681,161

src/H08-Dec-2021-104,89676,959

tests/H04-Jul-2019-2,4172,061

vignettes/H08-Dec-2021-9579

DESCRIPTIONH A D08-Dec-20211.4 KiB3938

LICENSEH A D08-Dec-202140 32

MD5H A D08-Dec-202115 KiB251250

NAMESPACEH A D08-Dec-20212.3 KiB110108

NEWS.mdH A D08-Dec-202110.5 KiB322189

README.mdH A D08-Dec-20218.8 KiB255198

README.md

1
2<!-- README.md is generated from README.Rmd. Please edit that file -->
3
4# fs
5
6<!-- badges: start -->
7
8[![lifecycle](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#maturing)
9[![R build
10status](https://github.com/r-lib/fs/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/fs/actions)
11[![Coverage
12status](https://codecov.io/gh/r-lib/fs/branch/main/graph/badge.svg)](https://codecov.io/github/r-lib/fs?branch=main)
13<!-- badges: end -->
14
15<p align="center">
16<img src="https://i.imgur.com/NAux1Xc.png" width = "75%"/>
17</p>
18
19**fs** provides a cross-platform, uniform interface to file system
20operations. It shares the same back-end component as
21[nodejs](https://nodejs.org), the
22[libuv](http://docs.libuv.org/en/v1.x/fs.html) C library, which brings
23the benefit of extensive real-world use and rigorous cross-platform
24testing. The name, and some of the interface, is partially inspired by
25Rust’s [fs module](https://doc.rust-lang.org/std/fs/index.html).
26
27## Installation
28
29You can install the released version of **fs** from
30[CRAN](https://CRAN.R-project.org) with:
31
32``` r
33install.packages("fs")
34```
35
36And the development version from [GitHub](https://github.com/) with:
37
38``` r
39# install.packages("devtools")
40devtools::install_github("r-lib/fs")
41```
42
43## Comparison vs base equivalents
44
45**fs** functions smooth over some of the idiosyncrasies of file handling
46with base R functions:
47
48-   Vectorization. All **fs** functions are vectorized, accepting
49    multiple paths as input. Base functions are inconsistently
50    vectorized.
51
52-   Predictable return values that always convey a path. All **fs**
53    functions return a character vector of paths, a named integer or a
54    logical vector, where the names give the paths. Base return values
55    are more varied: they are often logical or contain error codes which
56    require downstream processing.
57
58-   Explicit failure. If **fs** operations fail, they throw an error.
59    Base functions tend to generate a warning and a system dependent
60    error code. This makes it easy to miss a failure.
61
62-   UTF-8 all the things. **fs** functions always convert input paths to
63    UTF-8 and return results as UTF-8. This gives you path encoding
64    consistency across OSes. Base functions rely on the native system
65    encoding.
66
67-   Naming convention. **fs** functions use a consistent naming
68    convention. Because base R’s functions were gradually added over
69    time there are a number of different conventions used
70    (e.g. `path.expand()` vs `normalizePath()`; `Sys.chmod()` vs
71    `file.access()`).
72
73### Tidy paths
74
75**fs** functions always return ‘tidy’ paths. Tidy paths
76
77-   Always use `/` to delimit directories
78-   never have multiple `/` or trailing `/`
79
80Tidy paths are also coloured (if your terminal supports it) based on the
81file permissions and file type. This colouring can be customized or
82extended by setting the `LS_COLORS` environment variable, in the same
83output format as [GNU
84dircolors](http://www.bigsoft.co.uk/blog/index.php/2008/04/11/configuring-ls_colors).
85
86## Usage
87
88**fs** functions are divided into four main categories:
89
90-   `path_` for manipulating and constructing paths
91-   `file_` for files
92-   `dir_` for directories
93-   `link_` for links
94
95Directories and links are special types of files, so `file_` functions
96will generally also work when applied to a directory or link.
97
98``` r
99library(fs)
100
101# Construct a path to a file with `path()`
102path("foo", "bar", letters[1:3], ext = "txt")
103#> foo/bar/a.txt foo/bar/b.txt foo/bar/c.txt
104
105# list files in the current directory
106dir_ls()
107#> DESCRIPTION      LICENSE          LICENSE.md       MAINTENANCE.md
108#> NAMESPACE        NEWS.md          R                README.Rmd
109#> README.md        _pkgdown.yml     codecov.yml      cran-comments.md
110#> fs.Rproj         inst             man              man-roxygen
111#> revdep           src              tests            vignettes
112
113# create a new directory
114tmp <- dir_create(file_temp())
115tmp
116#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file553519e91baa
117
118# create new files in that directory
119file_create(path(tmp, "my-file.txt"))
120dir_ls(tmp)
121#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file553519e91baa/my-file.txt
122
123# remove files from the directory
124file_delete(path(tmp, "my-file.txt"))
125dir_ls(tmp)
126#> character(0)
127
128# remove the directory
129dir_delete(tmp)
130```
131
132**fs** is designed to work well with the pipe, though because it is a
133minimal-dependency infrastructure package it doesn’t provide the pipe
134itself. You will need to attach
135[magrittr](https://magrittr.tidyverse.org) or similar.
136
137``` r
138library(magrittr)
139
140paths <- file_temp() %>%
141  dir_create() %>%
142  path(letters[1:5]) %>%
143  file_create()
144paths
145#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file5535783c1027/a
146#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file5535783c1027/b
147#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file5535783c1027/c
148#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file5535783c1027/d
149#> /var/folders/9x/_8jnmxwj3rq1t90mlr6_0k1w0000gn/T/Rtmp8qNYF8/file5535783c1027/e
150
151paths %>% file_delete()
152```
153
154**fs** functions also work well in conjunction with other
155[tidyverse](https://www.tidyverse.org/) packages, like
156[dplyr](https://dplyr.tidyverse.org) and
157[purrr](https://purrr.tidyverse.org).
158
159Some examples…
160
161``` r
162suppressMessages(
163  library(tidyverse))
164```
165
166Filter files by type, permission and size
167
168``` r
169dir_info("src", recurse = FALSE) %>%
170  filter(type == "file", permissions == "u+r", size > "10KB") %>%
171  arrange(desc(size)) %>%
172  select(path, permissions, size, modification_time)
173#> # A tibble: 12 × 4
174#>    path          permissions        size modification_time
175#>    <fs::path>    <fs::perms> <fs::bytes> <dttm>
176#>  1 src/fs.so     rwxr-xr-x        267.7K 2021-11-29 17:54:31
177#>  2 src/id.o      rw-r--r--        159.2K 2021-11-29 17:54:10
178#>  3 src/dir.o     rw-r--r--         96.7K 2021-11-29 17:54:10
179#>  4 src/path.o    rw-r--r--         94.2K 2021-11-29 17:54:10
180#>  5 src/link.o    rw-r--r--           76K 2021-11-29 17:54:10
181#>  6 src/utils.o   rw-r--r--         75.1K 2021-11-29 17:54:10
182#>  7 src/getmode.o rw-r--r--           67K 2021-11-29 17:54:10
183#>  8 src/file.o    rw-r--r--         61.5K 2021-11-29 17:54:10
184#>  9 src/error.o   rw-r--r--         19.8K 2021-11-29 17:54:10
185#> 10 src/init.o    rw-r--r--         17.3K 2021-11-29 17:54:10
186#> 11 src/fs.o      rw-r--r--         12.1K 2021-11-29 17:54:10
187#> 12 src/file.cc   rw-r--r--         11.5K 2021-11-29 17:54:06
188```
189
190Tabulate and display folder size.
191
192``` r
193dir_info("src", recurse = TRUE) %>%
194  group_by(directory = path_dir(path)) %>%
195  tally(wt = size, sort = TRUE)
196#> # A tibble: 11 × 2
197#>    directory                             n
198#>    <chr>                       <fs::bytes>
199#>  1 src/libuv-1.38.1                  2.67M
200#>  2 src/libuv-1.38.1/src/unix         1.37M
201#>  3 src                              986.5K
202#>  4 src/libuv-1.38.1/src/win        729.66K
203#>  5 src/libuv-1.38.1/src            329.28K
204#>  6 src/libuv-1.38.1/include/uv     138.27K
205#>  7 src/libuv-1.38.1/include         64.03K
206#>  8 src/unix                         63.43K
207#>  9 src/bsd                          20.02K
208#> 10 src/windows                       4.73K
209#> 11 src/libuv-1.38.1/test                64
210```
211
212Read a collection of files into one data frame.
213
214`dir_ls()` returns a named vector, so it can be used directly with
215`purrr::map_df(.id)`.
216
217``` r
218# Create separate files for each species
219iris %>%
220  split(.$Species) %>%
221  map(select, -Species) %>%
222  iwalk(~ write_tsv(.x, paste0(.y, ".tsv")))
223
224# Show the files
225iris_files <- dir_ls(glob = "*.tsv")
226iris_files
227#> setosa.tsv     versicolor.tsv virginica.tsv
228
229# Read the data into a single table, including the filenames
230iris_files %>%
231  map_df(read_tsv, .id = "file", col_types = cols(), n_max = 2)
232#> # A tibble: 6 × 5
233#>   file           Sepal.Length Sepal.Width Petal.Length Petal.Width
234#>   <chr>                 <dbl>       <dbl>        <dbl>       <dbl>
235#> 1 setosa.tsv              5.1         3.5          1.4         0.2
236#> 2 setosa.tsv              4.9         3            1.4         0.2
237#> 3 versicolor.tsv          7           3.2          4.7         1.4
238#> 4 versicolor.tsv          6.4         3.2          4.5         1.5
239#> 5 virginica.tsv           6.3         3.3          6           2.5
240#> 6 virginica.tsv           5.8         2.7          5.1         1.9
241
242file_delete(iris_files)
243```
244
245## Feedback wanted!
246
247We hope **fs** is a useful tool for both analysis scripts and packages.
248Please open [GitHub issues](https://github.com/r-lib/fs) for any feature
249requests or bugs.
250
251In particular, we have found non-ASCII filenames in non-English locales
252on Windows to be especially tricky to reproduce and handle correctly.
253Feedback from users who use commonly have this situation is greatly
254appreciated.
255