You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To access and work with files, use the `file()`method, which returns a file system object given a file path string:
7
+
Use the `file()`function to obtain a reference to a file by name:
8
8
9
9
```nextflow
10
10
myFile = file('some/path/to/my_file.file')
11
11
```
12
12
13
-
The `file()`method can reference both files and directories, depending on what the string path refers to in the file system.
13
+
The `file()`function can reference both files and directories.
14
14
15
-
When using the wildcard characters `*`, `?`, `[]` and `{}`, the argument is interpreted as a [glob](http://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob)path matcher and the `file()` method returns a list object holding the paths of files whose names match the specified pattern, or an empty list if no match is found:
15
+
Use the `files()` function to obtain a list of files. When using the wildcard characters `*`, `?`, `[]` and `{}`, the file name is treated as a [glob](http://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob)pattern, returning all files that match the given pattern, or an empty list if no matching files are found:
16
16
17
17
```nextflow
18
-
listOfFiles = file('some/path/*.fa')
18
+
listOfFiles = files('some/path/*.fa')
19
19
```
20
20
21
21
:::{note}
22
-
The `file()`method does not return a list if only one file is matched. Use the `files()` method to always return a list.
22
+
The `file()`function can also be called with a glob pattern, as long as the pattern is intended to match exactly one file.
23
23
:::
24
24
25
-
:::{note}
26
-
A double asterisk (`**`) in a glob pattern works like `*` but also searches through subdirectories.
27
-
:::
25
+
A double asterisk (`**`) in a glob pattern works like `*` but also searches through subdirectories:
28
26
29
-
By default, wildcard characters do not match directories or hidden files. For example, if you want to include hidden files in the result list, enable the `hidden` option:
27
+
```nextflow
28
+
deeplyNestedFiles = files('some/path/**/*.fa')
29
+
```
30
+
31
+
By default, wildcard characters do not match directories or hidden files. Use the `hidden` option to include hidden files:
The `file()`method returns a [Path](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Path.html), which has several methods for retrieving metadata about the file:
50
+
The `file()`function returns a {ref}`Path <stdlib-types-path>`, which has several methods for retrieving metadata about the file:
When calling an object method, any method that looks like `get*()` can also be accessed as a field. For example, `path.getName()` is equivalent to `path.name`, `path.getBaseName()` is equivalent to `path.baseName`, and so on.
62
-
:::
63
-
64
61
See the {ref}`stdlib-types-path` reference for the list of available methods.
65
62
66
63
## Reading and writing
67
64
68
65
### Reading and writing an entire file
69
66
70
-
Given a file variable, created with the `file()` method as shown previously, reading a file is as easy as getting the file's `text` property, which returns the file content as a string:
67
+
Reading a file is as easy as using the file's `text` property, which returns the file contents as a string:
71
68
72
69
```nextflow
73
70
print myFile.text
74
71
```
75
72
76
-
Similarly, you can save a string to a file by assigning it to the file's `text` property:
73
+
Similarly, you can write text to a file by assigning it to the file's `text` property:
77
74
78
75
```nextflow
79
76
myFile.text = 'Hello world!'
80
77
```
81
78
82
-
Binary data can be managed in the same way, just using the file property `bytes` instead of `text`. Thus, the following example reads the file and returns its content as a byte array:
83
-
84
-
```nextflow
85
-
binaryContent = myFile.bytes
86
-
```
79
+
This approach overwrites any existing file contents, and implicitly creates the file if it doesn't exist.
87
80
88
-
Or you can save a byte array to a file:
81
+
:::{tip}
82
+
The `text` property is shorthand for the `getText()` and `setText()` methods:
89
83
90
84
```nextflow
91
-
myFile.bytes = binaryContent
85
+
println myFile.getText()
86
+
myFile.setText('Hello world!')
92
87
```
93
-
94
-
:::{note}
95
-
The above assignment overwrites any existing file contents, and implicitly creates the file if it doesn't exist.
96
88
:::
97
89
98
90
:::{warning}
99
-
The above methods read and write the **entire** file contents at once, in a single variable or buffer. For this reason, when dealing with large files it is recommended that you use a more memoryefficient approach, such as reading/writing a file line by line or using a fixed size buffer.
91
+
The above methods read and write the *entire* file contents at once, requiring the entire file to be loaded into memory. Consider using a more memory-efficient approach for large files, such as reading/writing the file line by line.
100
92
:::
101
93
102
-
### Appending to a file
103
-
104
-
In order to append a string value to a file without erasing existing content, you can use the `append()` method:
105
-
106
-
```nextflow
107
-
myFile.append('Add this line\n')
108
-
```
109
-
110
-
Or use the left shift operator, a more idiomatic way to append text content to a file:
111
-
112
-
```nextflow
113
-
myFile << 'Add a line more\n'
114
-
```
115
-
116
94
### Reading a file line by line
117
95
118
-
In order to read a text file line by line you can use the method `readLines()` provided by the file object, which returns the file content as a list of strings:
119
-
120
-
```nextflow
121
-
myFile = file('some/my_file.txt')
122
-
allLines = myFile.readLines()
123
-
for( line : allLines ) {
124
-
println line
125
-
}
126
-
```
127
-
128
-
This can also be written in a more idiomatic syntax:
96
+
You can use the `readLines()` method to read a text file line by line:
129
97
130
98
```nextflow
131
99
file('some/my_file.txt')
132
100
.readLines()
133
-
.each { println it }
101
+
.each { line ->
102
+
println line
103
+
}
134
104
```
135
105
136
-
:::{warning}
137
-
The method `readLines()` reads the **entire** file at once and returns a list containing all the lines. For this reason, do not use it to read big files.
138
-
:::
106
+
The `readLines()` method loads the *entire* file into memory, so it is not ideal for large files.
139
107
140
-
To process a big file, use the method `eachLine()`, which reads only a single line at a time into memory:
108
+
You can use the `eachLine()` method to read line by line while only loading one line at a time into memory:
141
109
142
110
```nextflow
143
111
count = 0
144
-
myFile.eachLine { str ->
145
-
println "line ${count++}: $str"
112
+
myFile.eachLine { line ->
113
+
println "line ${count++}: $line"
146
114
}
147
115
```
148
116
149
-
### Advanced file reading
150
-
151
-
The classes `Reader` and `InputStream` provide fine-grained control for reading text and binary files, respectively.
117
+
The `withReader()` method creates a [Reader](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Reader.html) that you can use to read the file line by line, or even character by character. It is useful when you don't need to read the entire file.
152
118
153
-
The method `newReader()` creates a [Reader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Reader.html) object for the given file that allows you to read the content as single characters, lines or arrays of characters:
119
+
For example, to read only the first line of a file:
154
120
155
121
```nextflow
156
-
myReader = myFile.newReader()
157
-
String line
158
-
while( line = myReader.readLine() ) {
159
-
println line
122
+
myFile.withReader { r ->
123
+
def firstLine = r.readLine()
124
+
println firstLine
160
125
}
161
-
myReader.close()
162
126
```
163
127
164
-
The method `withReader()` works similarly, but automatically calls the `close()` method for you when you have finished processing the file. So, the previous example can be written more simply as:
128
+
### Writing a file line by line
129
+
130
+
You can use the `append()` method or left shirt (`<<`) operator to append text to a file without erasing the existing contents:
165
131
166
132
```nextflow
167
-
myFile.withReader {
168
-
String line
169
-
while( line = it.readLine() ) {
170
-
println line
171
-
}
172
-
}
133
+
myFile.append('Add this line\n')
134
+
myFile << 'Add a line more\n'
173
135
```
174
136
175
-
The methods `newInputStream()` and `withInputStream()` work similarly. The main difference is that they create an [InputStream](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/InputStream.html) object useful for writing binary data.
176
-
177
-
See the {ref}`stdlib-types-path` reference for the list of available methods.
178
-
179
-
### Advanced file writing
180
-
181
-
The `Writer` and `OutputStream` classes provide fine-grained control for writing text and binary files, respectively, including low-level operations for single characters or bytes, and support for big files.
182
-
183
-
For example, given two file objects `sourceFile` and `targetFile`, the following code copies the first file's content into the second file, replacing all `U` characters with `X`:
137
+
For example, the following snippet copies the contents of a source file into a target file, replacing all `U` characters with `X`:
184
138
185
139
```nextflow
186
-
sourceFile.withReader { source ->
187
-
targetFile.withWriter { target ->
188
-
String line
189
-
while( line=source.readLine() ) {
190
-
target << line.replaceAll('U','X')
191
-
}
192
-
}
140
+
sourceFile.eachLine { line ->
141
+
targetFile << line.replaceAll('U', 'X')
193
142
}
194
143
```
195
144
196
-
See the {ref}`stdlib-types-path` reference for the list of available methods.
197
-
198
145
## Filesystem operations
199
146
200
-
Methods for performing filesystem operations such as copying, deleting, and directory listing are documented in the {ref}`stdlib-types-path` reference.
147
+
See the {ref}`stdlib-types-path` reference for the complete list of methods for performing filesystem operations.
201
148
202
149
### Listing directories
203
150
204
-
The simplest way to list a directory is to use `list()` or `listFiles()`, which return a collection of first-level elements (files and directories) of a directory:
151
+
You can use the `listFiles()` method to list the contents of a directory:
205
152
206
153
```nextflow
207
-
for( def file : file('any/path').list() ) {
154
+
children = file('any/path').list()
155
+
children.each { file ->
208
156
println file
209
157
}
210
158
```
211
159
212
-
Additionally, the `eachFile()` method allows you to iterate through the first-level elements only (just like `listFiles()`). As with other `each*()` methods, `eachFile()` takes a closure as a parameter:
160
+
:::{versionchanged} 26.04.0
161
+
The `listFiles()` method is deprecated -- use `listDirectory()` instead.
162
+
:::
163
+
164
+
You can use the `eachFile()` method to iterate through the contents of a directory:
0 commit comments