WEBVTT

00:00:00.700 --> 00:00:08.083
In this lesson, we will turn a folder of text files into a small inventory, then save an uppercase copy

00:00:08.083 --> 00:00:09.191
of one file.

00:00:09.341 --> 00:00:11.666
The original files stay unchanged.

00:00:11.816 --> 00:00:16.125
Open the downloaded examples folder before running the command.

00:00:16.275 --> 00:00:21.779
All reads use the fixtures directory, and all generated files go into out.

00:00:21.929 --> 00:00:28.946
This separation makes it easy to inspect the result and repeat the demonstration without touching your

00:00:28.946 --> 00:00:29.823
own documents.

00:00:31.970 --> 00:00:34.957
A Path represents a filesystem location.

00:00:35.107 --> 00:00:41.400
A String represents text, so wrap a filename in path when calling these file APIs.

00:00:41.550 --> 00:00:47.289
The name and extension fields are read only, and the extension includes its leading dot.

00:00:47.439 --> 00:00:51.471
A relative data path starts at your current working directory.

00:00:51.621 --> 00:00:55.717
That is why our run instructions first move into examples.

00:00:55.867 --> 00:00:59.941
Later, module imports will have a different relative path rule.

00:01:02.090 --> 00:01:06.634
The files function produces a lazy stream of filesystem entries.

00:01:06.784 --> 00:01:12.075
Our pattern selects text files, including matches below nested directories.

00:01:12.225 --> 00:01:17.643
We explicitly retain regular files, then project each entry to its name.

00:01:17.793 --> 00:01:24.471
Sorting makes our teaching output deterministic instead of depending on directory traversal order.

00:01:24.621 --> 00:01:27.394
Collect consumes the stream and creates a List.

00:01:27.544 --> 00:01:33.837
Notice that a filesystem entry contains metadata; it is not simply a filename string.

00:01:35.990 --> 00:01:39.702
Use read_text when you need one complete text value.

00:01:39.852 --> 00:01:44.183
Use read_lines when your processing works one line at a time.

00:01:44.333 --> 00:01:48.983
Both are text APIs and expect valid UTF eight input.

00:01:49.133 --> 00:01:53.059
Images and archives belong with the byte APIs instead.

00:01:53.209 --> 00:01:58.457
Here, read_lines supplies a stream directly, so we do not add stream after it.

00:01:58.607 --> 00:02:04.751
Each callback returns a transformed line without changing the original file on disk.

00:02:06.900 --> 00:02:09.332
Now add a terminal operation.

00:02:09.482 --> 00:02:14.815
Save_lines consumes the line stream and adds a line ending for each value.

00:02:14.965 --> 00:02:20.043
Create_parents allows the out directory to be created on the first run.

00:02:20.193 --> 00:02:27.297
The documented save operation writes a temporary sibling file and commits the replacement atomically.

00:02:27.447 --> 00:02:30.689
That prevents readers from seeing a half written target.

00:02:30.839 --> 00:02:36.322
It does not mean several different output files become one transaction together.

00:02:38.470 --> 00:02:41.030
Read the saved file back and print it.

00:02:41.180 --> 00:02:46.279
This checks the complete path from discovery and transformation to disk output.

00:02:46.429 --> 00:02:52.061
The uppercase text should contain the same two lines as notes, with their letters changed.

00:02:52.211 --> 00:02:59.379
Trim is only used for clean terminal presentation here; it is not part of the saved transformation.

00:02:59.529 --> 00:03:07.059
Open both files side by side and verify that the input still contains its original lowercase text.

00:03:09.210 --> 00:03:15.866
Write_text replaces the target by default, while append_text adds content to an existing file.

00:03:16.016 --> 00:03:22.693
We intentionally reset our demonstration journal at the start of every run, then append the second line.

00:03:22.843 --> 00:03:25.126
That makes repeated runs predictable.

00:03:25.276 --> 00:03:32.508
Pay attention to the explicit newline characters: a text write receives exactly the text you supply.

00:03:32.658 --> 00:03:39.527
Choose save_lines when your input already consists of separate line values and needs line endings.

00:03:41.680 --> 00:03:48.165
A common mistake is assuming a write will refuse to replace an existing file automatically.

00:03:48.315 --> 00:03:52.198
Set overwrite to false when replacement is not acceptable.

00:03:52.348 --> 00:03:56.636
This deliberate attempt fails because our journal already exists.

00:03:56.786 --> 00:04:02.951
The catch block lets the demonstration continue, and the journal still contains first and second.

00:04:03.101 --> 00:04:05.960
We will study structured errors in lesson nine.

00:04:06.110 --> 00:04:11.379
For now, compare the protected failure with the successful explicit reset above.

00:04:13.530 --> 00:04:18.543
For practice, add a third text file inside fixtures and rerun the script.

00:04:18.693 --> 00:04:24.048
The sorted inventory should grow, while the uppercase copy should still come from notes.

00:04:24.198 --> 00:04:30.342
Then change the selected source to your new fixture and predict its output before running again.

00:04:30.492 --> 00:04:32.241
Keep writes inside out.

00:04:32.391 --> 00:04:40.459
You have now connected Path values, lazy directory traversal, line processing, and controlled saving into

00:04:40.459 --> 00:04:42.610
one useful automation script.

