0
# Line Processing
1
2
Process files line-by-line with closures, including splitting, filtering, and transformation operations with comprehensive charset support.
3
4
## Capabilities
5
6
### Line Iteration
7
8
Iterate through file lines with closures, supporting line numbers and charset options.
9
10
```java { .api }
11
/**
12
* Iterates through this path line by line. Each line is passed to the given 1 or 2 arg closure
13
* @param self a Path
14
* @param closure a closure (arg 1 is line, optional arg 2 is line number starting at line 1)
15
* @return the last value returned by the closure
16
* @throws IOException if an IOException occurs
17
*/
18
<T> T eachLine(Path self, Closure<T> closure);
19
20
/**
21
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
22
* @param self a Path
23
* @param charset opens the file with a specified charset
24
* @param closure a closure (arg 1 is line, optional arg 2 is line number starting at line 1)
25
* @return the last value returned by the closure
26
* @throws IOException if an IOException occurs
27
*/
28
<T> T eachLine(Path self, String charset, Closure<T> closure);
29
30
/**
31
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
32
* @param self a Path
33
* @param firstLine the line number value used for the first line (default is 1, set to 0 to start counting from 0)
34
* @param closure a closure (arg 1 is line, optional arg 2 is line number)
35
* @return the last value returned by the closure
36
* @throws IOException if an IOException occurs
37
*/
38
<T> T eachLine(Path self, int firstLine, Closure<T> closure);
39
40
/**
41
* Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure
42
* @param self a Path
43
* @param charset opens the file with a specified charset
44
* @param firstLine the line number value used for the first line (default is 1, set to 0 to start counting from 0)
45
* @param closure a closure (arg 1 is line, optional arg 2 is line number)
46
* @return the last value returned by the closure
47
* @throws IOException if an IOException occurs
48
*/
49
<T> T eachLine(Path self, String charset, int firstLine, Closure<T> closure);
50
```
51
52
**Usage Examples:**
53
54
```groovy
55
import java.nio.file.Path
56
import java.nio.file.Paths
57
58
Path file = Paths.get("data.txt")
59
60
// Simple line iteration
61
file.eachLine { line ->
62
println line
63
}
64
65
// With line numbers (starting from 1)
66
file.eachLine { line, lineNumber ->
67
println "${lineNumber}: ${line}"
68
}
69
70
// With charset
71
file.eachLine("UTF-8") { line ->
72
println line
73
}
74
75
// With custom starting line number (0-based)
76
file.eachLine(0) { line, lineNumber ->
77
println "Line ${lineNumber}: ${line}"
78
}
79
80
// With charset and custom starting line number
81
file.eachLine("UTF-8", 0) { line, lineNumber ->
82
println "[${lineNumber}] ${line}"
83
}
84
85
// Collect lines (return value from closure)
86
List<String> upperCaseLines = file.eachLine { line ->
87
line.toUpperCase()
88
}
89
```
90
91
### Line Splitting
92
93
Split each line using regular expressions or patterns, with closure processing of the split results.
94
95
```java { .api }
96
/**
97
* Iterates through this file line by line, splitting each line using the given regex separator.
98
* For each line, the given closure is called with a single parameter being the list of strings
99
* computed by splitting the line around matches of the given regular expression
100
* @param self a Path
101
* @param regex the delimiting regular expression
102
* @param closure a closure
103
* @return the last value returned by the closure
104
* @throws IOException if an IOException occurs
105
* @throws PatternSyntaxException if the regular expression's syntax is invalid
106
*/
107
<T> T splitEachLine(Path self, String regex, Closure<T> closure);
108
109
/**
110
* Iterates through this file line by line, splitting each line using the given separator Pattern.
111
* For each line, the given closure is called with a single parameter being the list of strings
112
* computed by splitting the line around matches of the given regular expression Pattern
113
* @param self a Path
114
* @param pattern the regular expression Pattern for the delimiter
115
* @param closure a closure
116
* @return the last value returned by the closure
117
* @throws IOException if an IOException occurs
118
*/
119
<T> T splitEachLine(Path self, Pattern pattern, Closure<T> closure);
120
121
/**
122
* Iterates through this file line by line, splitting each line using the given regex separator.
123
* For each line, the given closure is called with a single parameter being the list of strings
124
* computed by splitting the line around matches of the given regular expression
125
* @param self a Path
126
* @param regex the delimiting regular expression
127
* @param charset opens the file with a specified charset
128
* @param closure a closure
129
* @return the last value returned by the closure
130
* @throws IOException if an IOException occurs
131
* @throws PatternSyntaxException if the regular expression's syntax is invalid
132
*/
133
<T> T splitEachLine(Path self, String regex, String charset, Closure<T> closure);
134
135
/**
136
* Iterates through this file line by line, splitting each line using the given regex separator Pattern.
137
* For each line, the given closure is called with a single parameter being the list of strings
138
* computed by splitting the line around matches of the given regular expression
139
* @param self a Path
140
* @param pattern the regular expression Pattern for the delimiter
141
* @param charset opens the file with a specified charset
142
* @param closure a closure
143
* @return the last value returned by the closure
144
* @throws IOException if an IOException occurs
145
*/
146
<T> T splitEachLine(Path self, Pattern pattern, String charset, Closure<T> closure);
147
```
148
149
**Usage Examples:**
150
151
```groovy
152
import java.nio.file.Path
153
import java.nio.file.Paths
154
import java.util.regex.Pattern
155
156
Path csvFile = Paths.get("data.csv")
157
158
// Split CSV lines by comma
159
csvFile.splitEachLine(",") { fields ->
160
println "Name: ${fields[0]}, Age: ${fields[1]}, City: ${fields[2]}"
161
}
162
163
// Split with regex pattern
164
csvFile.splitEachLine(/\s*,\s*/) { fields ->
165
// Handle CSV with spaces around commas
166
println fields.join(" | ")
167
}
168
169
// Using Pattern object
170
Pattern tabPattern = Pattern.compile("\t")
171
Path tsvFile = Paths.get("data.tsv")
172
tsvFile.splitEachLine(tabPattern) { fields ->
173
println "Tab-separated: ${fields}"
174
}
175
176
// With charset
177
csvFile.splitEachLine(",", "UTF-8") { fields ->
178
println "Unicode data: ${fields}"
179
}
180
181
// Process log file with pipe separator
182
Path logFile = Paths.get("server.log")
183
logFile.splitEachLine("\\|") { parts ->
184
def timestamp = parts[0]
185
def level = parts[1]
186
def message = parts[2]
187
if (level == "ERROR") {
188
println "Error at ${timestamp}: ${message}"
189
}
190
}
191
```
192
193
### Line Filtering
194
195
Filter file lines based on closure predicates, returning Writable objects or writing to output streams.
196
197
```java { .api }
198
/**
199
* Filters the lines of a Path and creates a Writable in return to stream the filtered lines
200
* @param self a Path
201
* @param closure a closure which returns a boolean indicating to filter the line or not
202
* @return a Writable closure
203
* @throws IOException if self is not readable
204
*/
205
Writable filterLine(Path self, Closure closure);
206
207
/**
208
* Filters the lines of a Path and creates a Writable in return to stream the filtered lines
209
* @param self a Path
210
* @param charset opens the file with a specified charset
211
* @param closure a closure which returns a boolean indicating to filter the line or not
212
* @return a Writable closure
213
* @throws IOException if an IOException occurs
214
*/
215
Writable filterLine(Path self, String charset, Closure closure);
216
217
/**
218
* Filter the lines from this Path, and write them to the given writer based on the given closure predicate
219
* @param self a Path
220
* @param writer a writer destination to write filtered lines to
221
* @param closure a closure which takes each line as a parameter and returns true if the line should be written to this writer
222
* @throws IOException if self is not readable
223
*/
224
void filterLine(Path self, Writer writer, Closure closure);
225
226
/**
227
* Filter the lines from this Path, and write them to the given writer based on the given closure predicate
228
* @param self a Path
229
* @param writer a writer destination to write filtered lines to
230
* @param charset opens the file with a specified charset
231
* @param closure a closure which takes each line as a parameter and returns true if the line should be written to this writer
232
* @throws IOException if an IO error occurs
233
*/
234
void filterLine(Path self, Writer writer, String charset, Closure closure);
235
```
236
237
**Usage Examples:**
238
239
```groovy
240
import java.nio.file.Path
241
import java.nio.file.Paths
242
243
Path logFile = Paths.get("application.log")
244
Path errorLog = Paths.get("errors.log")
245
246
// Filter lines and get Writable
247
Writable errorLines = logFile.filterLine { line ->
248
line.contains("ERROR")
249
}
250
251
// Write filtered lines to another file
252
errorLog.withWriter { writer ->
253
errorLines.writeTo(writer)
254
}
255
256
// Filter directly to writer
257
errorLog.withWriter { writer ->
258
logFile.filterLine(writer) { line ->
259
line.contains("ERROR") || line.contains("FATAL")
260
}
261
}
262
263
// Filter with charset
264
logFile.filterLine("UTF-8") { line ->
265
line.startsWith("[WARN]")
266
}.writeTo(System.out)
267
268
// Complex filtering example
269
Path accessLog = Paths.get("access.log")
270
Path suspiciousLog = Paths.get("suspicious.log")
271
272
suspiciousLog.withWriter { writer ->
273
accessLog.filterLine(writer, "UTF-8") { line ->
274
// Filter for potential security issues
275
line.contains("404") ||
276
line.contains("sql") ||
277
line.contains("script") ||
278
line.contains("admin")
279
}
280
}
281
```
282
283
### Byte Processing
284
285
Process files byte-by-byte or in buffered chunks with closures.
286
287
```java { .api }
288
/**
289
* Traverse through each byte of this Path
290
* @param self a Path
291
* @param closure a closure
292
* @throws IOException if an IOException occurs
293
*/
294
void eachByte(Path self, Closure closure);
295
296
/**
297
* Traverse through the bytes of this Path, bufferLen bytes at a time
298
* @param self a Path
299
* @param bufferLen the length of the buffer to use
300
* @param closure a 2 parameter closure which is passed the byte[] and a number of bytes successfully read
301
* @throws IOException if an IOException occurs
302
*/
303
void eachByte(Path self, int bufferLen, Closure closure);
304
```
305
306
**Usage Examples:**
307
308
```groovy
309
import java.nio.file.Path
310
import java.nio.file.Paths
311
312
Path binaryFile = Paths.get("data.bin")
313
314
// Process each byte individually
315
binaryFile.eachByte { byte b ->
316
printf("%02X ", b)
317
}
318
319
// Process bytes in 1KB chunks
320
binaryFile.eachByte(1024) { byte[] buffer, int bytesRead ->
321
println "Read ${bytesRead} bytes"
322
// Process buffer[0] to buffer[bytesRead-1]
323
for (int i = 0; i < bytesRead; i++) {
324
// Process buffer[i]
325
}
326
}
327
328
// Calculate file checksum
329
def checksum = 0
330
binaryFile.eachByte { byte b ->
331
checksum += (b & 0xFF)
332
}
333
println "Simple checksum: ${checksum}"
334
```