diff --git a/.vscode/markdown.code-snippets b/.vscode/markdown.code-snippets index af1f5c9..01e8643 100644 --- a/.vscode/markdown.code-snippets +++ b/.vscode/markdown.code-snippets @@ -62,13 +62,13 @@ "prefix": "extra", "body": [ "## Extra: $0", - "", + "", ], "description": "Extra slide colors" }, "exercise slide" : { "scope": "markdown", - "prefix": "exercise", + "prefix": "\"exercise invert\"", "body": [ "## Exercise $0.", "", diff --git a/12. Files and Streams-slides.html b/12. Files and Streams-slides.html new file mode 100644 index 0000000..cdf2ccf --- /dev/null +++ b/12. Files and Streams-slides.html @@ -0,0 +1,241 @@ +12. Files and Streams
+

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
  • +
+

+
+
+

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.");
    +}
    +
    +
  • +
+
+
+

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
    +{
    +  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:
  • +
+
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

+ +
    +
  1. Create a console application which keeps asking the user for a string. Each string is added into a list of strings.
  2. +
  3. If the user returns an empty string, the program asks for a path to a .txt file.
  4. +
  5. 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.
  6. +
+
+
+

JSON

+
    +
  • JSON (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.)
  • +
+
+
+

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 > 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
    • +
    +
  • +
+
+
+

JSON Serialization: an example

+

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);
+}
+
+
+
+

The contents of the output file Products.json are as follows:

+

+
+
+
+
+

JSON Deserialization

+

Deserializing the contents of a JSON file into an object in your program can be done with the JsonConvert.DeserializeObject() method:

+
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

+ +
    +
  1. Create a class Note with the properties int Id, DateTime TimeStamp and string Text.
  2. +
  3. Create a main loop that keeps asking the user for a new note.
  4. +
  5. 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.
  6. +
  7. 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!)
  8. +
+
+
+

Extra: FileStream

+ +
    +
  • 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 (continued)

+ +
    +
  • When inserting string data into a file, it needs to be converted into bytes
  • +
+
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
+
+
+
+

Extra: The using statement

+ +
    +
  • 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
  • +
+
+
+

The following reads the first 20 characters of a file and prints them to the console

+
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));
+
+
+
\ No newline at end of file diff --git a/12. Files and Streams.md b/12. Files and Streams.md index f1d387b..ca24885 100644 --- a/12. Files and Streams.md +++ b/12. Files and Streams.md @@ -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 - -# 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 -{ + + -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 +![](imgs/12%20Files%20and%20Streams_0.png) -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 +``` -File.WriteAllLines(path, lyrics); // Creates a new file with lyrics -# Exercise 1: A Simple Parser +## 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. +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. -If the user returns an empty string, the program asks for a path to a .txt file. +## JSON -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 (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) - -* .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…_ - * 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 products = new List - -{ -new Product{Id=1, Name="Awesome Product"}, -new Product{Id=2, Name="Terrible Product"} +### JSON Serialization: set-up -}; - -string jsonString = JsonConvert.SerializeObject(products); - -File.WriteAllText(@"C:\\Users\\OMISTAJA\\source\\repos\\Example\\Products.json", jsonString); - -} +* .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 > 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_ + +### JSON Serialization: an example + +You can *__serialize__* an object (e.g. a list) into a JSON string with the `JsonConvert.SerializeObject()` method: + +
+
+ + ```csharp + class Product + { + public int Id { get; set; } + public string Name { get; set; } + } + static void Main(string[] args) + { + List products = new List + { + 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); + } + ``` + +
+
The contents of the output file Products.json are as follows: ![](imgs/12%20Files%20and%20Streams_1.png) -# JSON Deserialization +
+
-__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 deserializedProducts = new List(); - deserializedProducts = JsonConvert.DeserializeObject>(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 + -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 + -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: + ![](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 -# FileStream +## FileStream (continued) + -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: - -![](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 - -# 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 - +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 - + 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 +``` -fs.Close(); // Close the file - -# The Using Statement - -From the Microsoft Documentation about the FileStream class: +## Extra: The `using` statement + -![](imgs/12%20Files%20and%20Streams_3.png) +* 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 +--- + 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)); - +``` \ No newline at end of file diff --git a/imgs/12 Files and Streams_0.png b/imgs/12 Files and Streams_0.png new file mode 100644 index 0000000..d9e5479 Binary files /dev/null and b/imgs/12 Files and Streams_0.png differ