finish lecture 12, add invert to special slide snippets
parent
9646c62fe8
commit
7a2601d0c6
File diff suppressed because one or more lines are too long
@ -1,295 +1,233 @@
|
||||
# Files and Streams
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# Overview
|
||||
|
||||
Files and Streams
|
||||
|
||||
Reading from a File
|
||||
|
||||
Writing to a File
|
||||
|
||||
JSON Serialization
|
||||
|
||||
JSON Deserialization
|
||||
|
||||
# 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
|
||||
|
||||
Stream writer / reader
|
||||
|
||||
String, int, ...
|
||||
|
||||
FileStream object
|
||||
|
||||
.txt, .csv, .png, ...
|
||||
|
||||
marp: true
|
||||
paginate: true
|
||||
math: mathjax
|
||||
theme: buutti
|
||||
title: 12. Files and Streams
|
||||
---
|
||||
|
||||
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 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:
|
||||
|
||||
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
|
||||
|
||||
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
|
||||
|
||||
if (!File.Exists(path))
|
||||
|
||||
{
|
||||
|
||||
Console.WriteLine($"The file {path} does not exist.");
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
# Files and Streams
|
||||
|
||||
{
|
||||
<!-- headingDivider: 5 -->
|
||||
<!-- class: invert -->
|
||||
|
||||
var allLines = File.ReadAllLines(path);
|
||||
## Overview
|
||||
|
||||
foreach (string line in allLines)
|
||||
* Files and Streams
|
||||
* Reading from a File
|
||||
* Writing to a File
|
||||
* JSON Serialization
|
||||
* JSON Deserialization
|
||||
|
||||
Console.WriteLine(line);
|
||||
## Files and streams
|
||||
|
||||
}
|
||||
* 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
|
||||
|
||||
# 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";
|
||||
|
||||
## 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:
|
||||
```csharp
|
||||
string path = @"C:\\Users\\Public\\TestFolder\\TestFile.txt";
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Console.WriteLine($"The file {path} does not exist.");
|
||||
}
|
||||
```
|
||||
|
||||
## 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 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"
|
||||
|
||||
};
|
||||
{
|
||||
"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.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:
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
* Select the package, check the checkbox next to _Project_ and click _Install_
|
||||
|
||||
### JSON Serialization: an example
|
||||
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
<div markdown='1'>
|
||||
|
||||
The contents of the output file Products.json are as follows:
|
||||
|
||||

|
||||
|
||||
# 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);
|
||||
|
||||
Console.WriteLine(product.Name);
|
||||
}
|
||||
```
|
||||
|
||||
# Exercise 2: Serializing Your Classes
|
||||
|
||||
Create a class Note with the properties int Id, DateTime TimeStamp and string Text.
|
||||
## Exercise 2: Serializing Your Classes
|
||||
<!--_class: exercise -->
|
||||
|
||||
Create a main loop that keeps asking the user for a new note.
|
||||
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!)
|
||||
|
||||
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.
|
||||
## Extra: FileStream
|
||||
<!-- _class: extra -->
|
||||
|
||||
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!)
|
||||
* 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:
|
||||

|
||||
* 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
|
||||
## FileStream (continued)
|
||||
<!-- _class: "extra invert" -->
|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||

|
||||
* 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.");
|
||||
|
||||
Console.WriteLine($"The file {path} does not exist.");
|
||||
else
|
||||
|
||||
using (FileStream fs = File.OpenRead(path))
|
||||
|
||||
{
|
||||
|
||||
fs.Read(byteArray, 0, nOfBytesToPrint);
|
||||
|
||||
};
|
||||
|
||||
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…
Reference in New Issue