7.3 KiB
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, ...
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
{
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
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.
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"
- 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"}
};
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\Johannes\source\repos\Luentoesimerkit\Luentoesimerkit\db.json");
List deserializedProducts = new List();
deserializedProducts = JsonConvert.DeserializeObject<List>(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.
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:
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
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));