finish lecture 12, add invert to special slide snippets

main
borb 3 weeks ago
parent 9646c62fe8
commit 7a2601d0c6

@ -62,13 +62,13 @@
"prefix": "extra", "prefix": "extra",
"body": [ "body": [
"## Extra: $0", "## Extra: $0",
"<!-- _class: extra -->", "<!-- _class: \"extra invert\" -->",
], ],
"description": "Extra slide colors" "description": "Extra slide colors"
}, },
"exercise slide" : { "exercise slide" : {
"scope": "markdown", "scope": "markdown",
"prefix": "exercise", "prefix": "\"exercise invert\"",
"body": [ "body": [
"## Exercise $0.", "## Exercise $0.",
"<!--_class: exercise -->", "<!--_class: exercise -->",

File diff suppressed because one or more lines are too long

@ -1,295 +1,233 @@
# Files and Streams
![](imgs/12%20Files%20and%20Streams_0.png)
--- ---
marp: true
# Overview paginate: true
math: mathjax
Files and Streams theme: buutti
title: 12. Files and Streams
Reading from a File ---
Writing to a File
JSON Serialization
JSON Deserialization
# Files and Streams # Files and Streams
The .NET library contains classes for manipulating files and directories <!-- headingDivider: 5 -->
<!-- class: invert -->
The FileStream class contains methods for read and write operations for files
The goal is usually to turn the data in your code into an outside resource, such as a .txt file, and vice versa
Application Code
Stream writer / reader ## Overview
String, int, ... * Files and Streams
* Reading from a File
* Writing to a File
* JSON Serialization
* JSON Deserialization
FileStream object ## Files and streams
.txt, .csv, .png, ... * The .NET library [contains classes](https://learn.microsoft.com/en-us/dotnet/api/system.io?view=net-7.0
) for manipulating files and directories
* The `FileStream` class contains methods for read and write operations for files
* The goal is usually to turn the data in your code into an outside resource, such as a .txt file, and vice versa
--- ![](imgs/12%20Files%20and%20Streams_0.png)
https://learn.microsoft.com/en-us/dotnet/api/system.io?view=net-7.0
# Using the File Class
To get started, add the following namespace to your project: ## Using the `File` Class
* To get started, add the following namespace to your project:
```csharp
using System.IO; using System.IO;
```
System.IO provides basic directory and folder support, and allows reading and writing to files and data streams * `System.IO` provides basic directory and folder support, and allows reading and writing to files and data streams
* Check if a file exists with the `.Exists()` method:
Check if a file exists with the .Exists() method: ```csharp
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt"; string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
if (!File.Exists(path)) if (!File.Exists(path))
{ {
Console.WriteLine($"The file {path} does not exist."); Console.WriteLine($"The file {path} does not exist.");
} }
```
--- ## Reading from a file
https://learn.microsoft.com/en-us/dotnet/api/system.io?view=net-7.0
# Reading from a File
Get the entire document as a string with File.ReadAllText
Get all lines of a document as a string array with File.ReadAllLines
* Get the entire document as a string with `File.ReadAllText`
* Get all lines of a document as a string array with `File.ReadAllLines`
```csharp
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt"; string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
if (!File.Exists(path)) if (!File.Exists(path))
{ {
Console.WriteLine($"The file {path} does not exist."); Console.WriteLine($"The file {path} does not exist.");
} }
else else
{ {
var allLines = File.ReadAllLines(path); var allLines = File.ReadAllLines(path);
foreach (string line in allLines) foreach (string line in allLines)
Console.WriteLine(line); Console.WriteLine(line);
} }
```
# Writing to a File ## Writing to a file
Writing to a file is done with File.WriteAllText and File.WriteAllLines methods: * Writing to a file is done with `File.WriteAllText` and `File.WriteAllLines` methods:
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
```csharp
string path = @"C:\Users\Public\TestFolder\TestFile.txt";
string[] lyrics = new string[] string[] lyrics = new string[]
{ {
"Hello", "Hello",
"Is it me you're looking for", "Is it me you're looking for",
"I can see it in your eyes", "I can see it in your eyes",
"I can see it in your smile" "I can see it in your smile"
}; };
if (File.Exists(path)) if (File.Exists(path))
{
File.Delete(path); // If file exists, deletes the old file File.Delete(path); // If file exists, deletes the old file
}
File.WriteAllLines(path, lyrics); // Creates a new file with lyrics File.WriteAllLines(path, lyrics); // Creates a new file with lyrics
```
# Exercise 1: A Simple Parser
Create a console application which keeps asking the user for a string. Each string is added into a list of strings.
If the user returns an empty string, the program asks for a path to a .txt file. ## Exercise 1: A simple parser
<!--_class: exercise -->
If the file exists, its contents are replaced with each string written to a separate line. If not, a new file with the contents is created. 1. Create a console application which keeps asking the user for a string. Each string is added into a list of strings.
2. If the user returns an empty string, the program asks for a path to a .txt file.
3. If the file exists, its contents are replaced with each string written to a separate line. If not, a new file with the contents is created.
# JSON Serialization ## JSON
* JSON (JavaScript Object Notation) is a way to represent code objects in text form, a "data-interchange format" * [JSON](https://www.json.org/json-en.html) (JavaScript Object Notation) is a way to represent code objects in text form, a "data-interchange format"
* Enables reading and writing series of objects into a text file * Enables reading and writing series of objects into a text file
* Consists of two types of structures * Consists of two types of structures
* Objects, or unordered name-value pairs * Objects, or unordered name-value pairs
* Ordered lists of values * Ordered lists of values
* Language-independent, although the JSON notation resembles the C-family of languages (C#, Java, JavaScript etc.) * Language-independent, although the JSON notation resembles the C-family of languages (C#, Java, JavaScript etc.)
---
https://www.json.org/json-en.html
# JSON Serialization (continued)
### JSON Serialization: set-up
* .NET projects do not directly support JSON serialization * .NET projects do not directly support JSON serialization
* A __NuGet package__ for that exists, called __Newtonsoft.Json __ * A *__NuGet package__* for that exists, called `Newtonsoft.Json`
* Install the package from _Tools _ -> _NuGet Package Manager_ -> M _anage NuGet Packages for Solution…_ * Install the package from _Tools > NuGet Package Manager > Manage NuGet Packages for Solution…_
* Select _Browse_ * Select _Browse_
* The _Newtonsoft.Json_ should be the topmost package. If not, search for it from the search bar * The _Newtonsoft.Json_ should be the topmost package. If not, search for it from the search bar
* Select the package, check the checkbox next to _Project_ and click _Install_ * Select the package, check the checkbox next to _Project_ and click _Install_
You can __serialize __ an object (e.g. a list) into a JSON string with the JsonConvert.SerializeObject() method: ### JSON Serialization: an example
class Product You can *__serialize__* an object (e.g. a list) into a JSON string with the `JsonConvert.SerializeObject()` method:
{ <div class='columns21' markdown='1'>
<div markdown='1'>
```csharp
class Product
{
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
} }
static void Main(string[] args) static void Main(string[] args)
{ {
List<Product> products = new List<Product> List<Product> products = new List<Product>
{ {
new Product{Id=1, Name="Awesome Product"}, new Product{Id=1, Name="Awesome Product"},
new Product{Id=2, Name="Terrible Product"} new Product{Id=2, Name="Terrible Product"}
}; };
string jsonString = JsonConvert.SerializeObject(products); string jsonString = JsonConvert.SerializeObject(products);
File.WriteAllText(@"C:\Users\OMISTAJA\source\repos\Example\Products.json", jsonString);
File.WriteAllText(@"C:\\Users\\OMISTAJA\\source\\repos\\Example\\Products.json", jsonString);
} }
```
</div>
<div markdown='1'>
The contents of the output file Products.json are as follows: The contents of the output file Products.json are as follows:
![](imgs/12%20Files%20and%20Streams_1.png) ![](imgs/12%20Files%20and%20Streams_1.png)
# JSON Deserialization </div>
</div>
__Deserializing __ the contents of a JSON file into an object in your program can be done with the JsonConvert.DeserializeObject() method: ## JSON Deserialization
string json = File.ReadAllText( *__Deserializing__* the contents of a JSON file into an object in your program can be done with the `JsonConvert.DeserializeObject()` method:
@"C:\\Users\\Johannes\\source\\repos\\Luentoesimerkit\\Luentoesimerkit\\db.json"); ```csharp
string json = File.ReadAllText(
@"C:\Users\OMISTAJA\source\repos\Luentoesimerkit\Luentoesimerkit\db.json");
List<Product> deserializedProducts = new List<Product>(); List<Product> deserializedProducts = new List<Product>();
deserializedProducts = JsonConvert.DeserializeObject<List<Product>>(json); deserializedProducts = JsonConvert.DeserializeObject<List<Product>>(json);
foreach(Product product in deserializedProducts) foreach(Product product in deserializedProducts)
{ {
Console.WriteLine(product.Name); Console.WriteLine(product.Name);
} }
```
# Exercise 2: Serializing Your Classes ## Exercise 2: Serializing Your Classes
<!--_class: exercise -->
Create a class Note with the properties int Id, DateTime TimeStamp and string Text.
Create a main loop that keeps asking the user for a new note.
After the user has entered each note, a new Note object is created with a running Id (1, 2, 3…), TimeStamp set to current time and Text is the inputted note. Each new note is added to a list of notes, allNotes.
Every time a new note is submitted, the allNotes list is serialized into a json file, "notes.json". Set the path to the current project path (you can get the path by right-clicking the project in solution explorer and selecting "Copy Full Path". Remember to change the file name!) 1. Create a class `Note` with the properties `int Id`, `DateTime TimeStamp` and `string Text`.
2. Create a main loop that keeps asking the user for a new note.
3. After the user has entered each note, a new `Note` object is created with a running `Id` (1, 2, 3…), `TimeStamp` set to current time and `Text` as the inputted note. Each new note is added to a list of notes `allNotes`.
4. Every time a new note is submitted, the `allNotes` list is serialized into a json file `notes.json`. Set the path to the current project path (you can get the path by right-clicking the project in solution explorer and selecting _Copy Full Path_. Remember to change the file name!)
# FileStream ## Extra: FileStream
<!-- _class: extra -->
The files have to be opened before read/write and closed after
Behind the scenes, the ReadAll... and WriteAll… methods automatically do the opening and closing, as described in the Microsoft documentation:
* The files have to be opened before reading or writing and closed after
* Behind the scenes, the `ReadAll...` and `WriteAll...` methods automatically do the opening and closing, as described in the Microsoft documentation:
![](imgs/12%20Files%20and%20Streams_2.png) ![](imgs/12%20Files%20and%20Streams_2.png)
* Writing to or reading only a part of the file requires opening and closing the file manually
* This creates a *__FileStream__* object that can be used for accessing parts of the file
Writing to or reading only a part of the file requires opening and closing the file manually ## FileStream (continued)
<!-- _class: "extra invert" -->
This creates a __FileStream __ object that can be used for accessing parts of the file
# FileStream (continued) * When inserting string data into a file, it needs to be converted into bytes
When inserting string data into a file, it needs to be converted into bytes
string path = @"C:\\Users\\Public\\TestFolder\\TestWriteFile.txt";
```csharp
string path = @"C:\Users\Public\TestFolder\TestWriteFile.txt";
int nOfLines = 4; int nOfLines = 4;
FileStream fs = null; FileStream fs = null;
if (!File.Exists(path)) // If file does not exist if (!File.Exists(path)) // If file does not exist
fs = File.Create(path); // create a new file and open it fs = File.Create(path); // create a new file and open it
else // If file exists else // If file exists
fs = File.OpenWrite(path); // open an existing file for writing fs = File.OpenWrite(path); // open an existing file for writing
for (int i = 0; i < nOfLines; ++i) for (int i = 0; i < nOfLines; ++i)
{ {
string input = Console.ReadLine() + "\\n"; // Read user input, add newline string input = Console.ReadLine() + "\\n"; // Read user input, add newline
byte[] byteInput = new UTF8Encoding(true).GetBytes(input); // Get the string as a sequence of bytes byte[] byteInput = new UTF8Encoding(true).GetBytes(input); // Get the string as a sequence of bytes
fs.Write(byteInput, 0, byteInput.Length); // Write the bytes at the end of the file fs.Write(byteInput, 0, byteInput.Length); // Write the bytes at the end of the file
} }
fs.Close(); // Close the file fs.Close(); // Close the file
```
# The Using Statement ## Extra: The `using` statement
<!-- _class: "extra invert" -->
From the Microsoft Documentation about the FileStream class:
* From the Microsoft Documentation about the FileStream class:
![](imgs/12%20Files%20and%20Streams_3.png) ![](imgs/12%20Files%20and%20Streams_3.png)
* This means that wrapping the file handling in an `using` block handles the opening and closing of the stream for you
This means that wrapping the file handling in an __using __ block handles the opening and closing of the stream for you ---
<!-- _class: "extra invert" -->
The following reads the first 20 characters of a file and prints them to the console The following reads the first 20 characters of a file and prints them to the console
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt"; ```csharp
string path = @"C:\Users\Public\TestFolder\TestFile.txt";
int nOfBytesToPrint = 20; int nOfBytesToPrint = 20;
byte[] byteArray = new byte[nOfBytesToPrint]; byte[] byteArray = new byte[nOfBytesToPrint];
if (!File.Exists(path)) if (!File.Exists(path))
Console.WriteLine($"The file {path} does not exist."); Console.WriteLine($"The file {path} does not exist.");
else else
using (FileStream fs = File.OpenRead(path)) using (FileStream fs = File.OpenRead(path))
{ {
fs.Read(byteArray, 0, nOfBytesToPrint); fs.Read(byteArray, 0, nOfBytesToPrint);
}; };
// No need to close the file since it was handled inside of a using block // No need to close the file since it was handled inside of a using block
Console.WriteLine(Encoding.UTF8.GetString(byteArray, 0, byteArray.Length)); Console.WriteLine(Encoding.UTF8.GetString(byteArray, 0, byteArray.Length));
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Loading…
Cancel
Save