finish lecture 12, add invert to special slide snippets

main
borb 3 weeks ago
parent 9646c62fe8
commit 7a2601d0c6

@ -62,13 +62,13 @@
"prefix": "extra",
"body": [
"## Extra: $0",
"<!-- _class: extra -->",
"<!-- _class: \"extra invert\" -->",
],
"description": "Extra slide colors"
},
"exercise slide" : {
"scope": "markdown",
"prefix": "exercise",
"prefix": "\"exercise invert\"",
"body": [
"## Exercise $0.",
"<!--_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)
---
# Overview
Files and Streams
Reading from a File
Writing to a File
JSON Serialization
JSON Deserialization
marp: true
paginate: true
math: mathjax
theme: buutti
title: 12. Files and Streams
---
# Files and Streams
The .NET library contains classes 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
Application Code
<!-- headingDivider: 5 -->
<!-- class: invert -->
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;
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:
```
* `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:
```csharp
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
if (!File.Exists(path))
{
Console.WriteLine($"The file {path} does not exist.");
}
```
---
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
## 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`
```csharp
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
if (!File.Exists(path))
{
Console.WriteLine($"The file {path} does not exist.");
}
else
{
var allLines = File.ReadAllLines(path);
foreach (string line in allLines)
Console.WriteLine(line);
}
```
# Writing to a File
## Writing to a file
Writing to a file is done with File.WriteAllText and File.WriteAllLines methods:
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
* Writing to a file is done with `File.WriteAllText` and `File.WriteAllLines` methods:
```csharp
string path = @"C:\Users\Public\TestFolder\TestFile.txt";
string[] lyrics = new string[]
{
"Hello",
"Is it me you're looking for",
"I can see it in your eyes",
"I can see it in your smile"
};
if (File.Exists(path))
{
File.Delete(path); // If file exists, deletes the old file
}
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
* Consists of two types of structures
* Objects, or unordered name-value pairs
* Ordered lists of values
* 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
* A __NuGet package__ for that exists, called __Newtonsoft.Json __
* Install the package from _Tools _ -> _NuGet Package Manager_ -> M _anage NuGet Packages for Solution…_
* A *__NuGet package__* for that exists, called `Newtonsoft.Json`
* Install the package from _Tools > NuGet Package Manager > Manage NuGet Packages for Solution…_
* Select _Browse_
* 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_
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 string Name { get; set; }
}
static void Main(string[] args)
{
List<Product> products = new List<Product>
{
new Product{Id=1, Name="Awesome Product"},
new Product{Id=2, Name="Terrible Product"}
};
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:
![](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>();
deserializedProducts = JsonConvert.DeserializeObject<List<Product>>(json);
foreach(Product product in deserializedProducts)
{
Console.WriteLine(product.Name);
}
```
# Exercise 2: Serializing Your Classes
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.
## Exercise 2: Serializing Your Classes
<!--_class: exercise -->
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
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:
## Extra: FileStream
<!-- _class: extra -->
* 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)
* 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
This creates a __FileStream __ object that can be used for accessing parts of the file
## FileStream (continued)
<!-- _class: "extra invert" -->
# FileStream (continued)
When inserting string data into a file, it needs to be converted into bytes
string path = @"C:\\Users\\Public\\TestFolder\\TestWriteFile.txt";
* When inserting string data into a file, it needs to be converted into bytes
```csharp
string path = @"C:\Users\Public\TestFolder\TestWriteFile.txt";
int nOfLines = 4;
FileStream fs = null;
if (!File.Exists(path)) // If file does not exist
fs = File.Create(path); // create a new file and open it
else // If file exists
fs = File.OpenWrite(path); // open an existing file for writing
for (int i = 0; i < nOfLines; ++i)
{
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
fs.Write(byteInput, 0, byteInput.Length); // Write the bytes at the end of the file
}
fs.Close(); // Close the file
```
# The Using Statement
From the Microsoft Documentation about the FileStream class:
## Extra: The `using` statement
<!-- _class: "extra invert" -->
* From the Microsoft Documentation about the FileStream class:
![](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
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
```csharp
string path = @"C:\Users\Public\TestFolder\TestFile.txt";
int nOfBytesToPrint = 20;
byte[] byteArray = new byte[nOfBytesToPrint];
if (!File.Exists(path))
Console.WriteLine($"The file {path} does not exist.");
else
using (FileStream fs = File.OpenRead(path))
{
fs.Read(byteArray, 0, nOfBytesToPrint);
};
// No need to close the file since it was handled inside of a using block
Console.WriteLine(Encoding.UTF8.GetString(byteArray, 0, byteArray.Length));
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Loading…
Cancel
Save