Chapter 10. Working with Files, Streams, and Serialization

This chapter is about reading and writing to files and streams, text encoding, and serialization.

This chapter will cover the following topics:

  • Managing the filesystem
  • Reading and writing with streams
  • Encoding text
  • Serializing object graphs

Managing the filesystem

Your applications will often need to perform input and output with files and directories. The System.IO namespace contains classes for this purpose.

Managing directories

In Visual Studio 2017, press Ctrl + Shift + N or choose File | New | Project....

In the New Project dialog, in the Installed | Templates list, select .NET Core. In the center list, select Console App (.NET Core), type Name as Ch10_FileSystem, change the location to C:Code, type the solution name as Chapter10, and then click on OK.

In Visual Studio Code, in the Integrated Terminal, make a new directory named Chapter10, and a subdirectory named Ch10_FileSystem. Open the folder and enter the command dotnet new console.

At the top of the Program.cs file, add the following import statements. Note that we will statically import the Directory type to simplify our code:

    using static System.Console; 
    using System.IO; 
    using static System.IO.Directory; 

In the Main method, write the following statements to check for the existence of a directory. Then, create and delete it. Note that the path is different for Windows and macOS:

    // define a directory path 
    // string dir = @"C:CodeCh10_Example"; // Windows 
    string dir = @"/Users/markjprice/Code/Ch10_Example/"; // macOS 
 
    // check if it exists 
    WriteLine($"Does {dir} exist? {Exists(dir)}"); 
    // create a directory 
    CreateDirectory(dir); 
    WriteLine($"Does {dir} exist? {Exists(dir)}"); 
    // delete a directory 
    Delete(dir); 
    WriteLine($"Does {dir} exist? {Exists(dir)}");

Run the console application and view the output:

Does /Users/markjprice/Code/Ch10_Example/ exist? False
Does /Users/markjprice/Code/Ch10_Example/ exist? True
Does /Users/markjprice/Code/Ch10_Example/ exist? False

Managing files

Note that, this time we will not statically import the File type, because it has some of the same methods as the Directory type and they would conflict. The File type has a short enough name not to matter in this case.

In the Main method, add the following statements to:

  • Check for the existence of a file
  • Create a text file
  • Write a line of text to the file
  • Copy the file to a backup
  • Delete the original file
  • Read the backup file's contents
    // string textFile = @"C:CodeCh10.txt"; // Windows 
    // string backupFile = @"C:CodeCh10.bak"; // Windows 
    string textFile = @"/Users/markjprice/Code/Ch10.txt"; // macOS 
    string backupFile = @"/Users/markjprice/Code/Ch10.bak"; // macOS 
 
    // check if a file exists 
    WriteLine($"Does {textFile} exist? {File.Exists(textFile)}"); 
 
    // create a new text file and write a line to it 
    StreamWriter textWriter = File.CreateText(textFile); 
    textWriter.WriteLine("Hello, C#!"); 
    textWriter.Dispose(); 
    WriteLine($"Does {textFile} exist? {File.Exists(textFile)}"); 
 
    // copy a file and overwrite if it already exists 
    File.Copy(textFile, backupFile, true); 
    WriteLine($"Does {backupFile} exist? {File.Exists(backupFile)}"); 
 
    // delete a file 
    File.Delete(textFile); 
    WriteLine($"Does {textFile} exist? {File.Exists(textFile)}"); 
 
    // read from a text file 
    StreamReader textReader = File.OpenText(backupFile); 
    WriteLine(textReader.ReadToEnd()); 
    textReader.Dispose(); 

Run the console application and view the output:

Does C:CodeCh10.txt exist? False
Does C:CodeCh10.txt exist? True
Does C:CodeCh10.bak exist? True
Does C:CodeCh10.txt exist? False
Hello, C#!

Note

In .NET Framework, you can use either the Close or Dispose method when you are finished with StreamReader or StreamWriter. In .NET Core, you can only use Dispose, because Microsoft has simplified the API.

Managing paths

Sometimes, you need to work with paths, for example, you might want to extract just the folder name, the file name, or the extension. Sometimes, you need to generate temporary folders and file names. You can do this with the Path class.

Add the following statements to the Main method:

    WriteLine($"File Name: {Path.GetFileName(textFile)}"); 
    WriteLine($"File Name without Extension:
    {Path.GetFileNameWithoutExtension(textFile)}"); 
    WriteLine($"File Extension: {Path.GetExtension(textFile)}"); 
    WriteLine($"Random File Name: {Path.GetRandomFileName()}"); 
    WriteLine($"Temporary File Name: {Path.GetTempFileName()}"); 

Run the console application and view the output:

File Name: Ch10.txt
File Name without Extension: Ch10
File Extension: .txt
Random File Name: u45w1zki.co3
Temporary File Name:  /var/folders/tz/xx0y_wld5sx0nv0fjtq4tnpc0000gn/T/tmpyqrepP.
tmp

Note

The GetTempFileName method creates a zero-byte file and returns its name, ready for you to use. GetRandomFileName just returns a filename; it doesn't create the file.

Getting file information

To get more information about a file or directory, you can create an instance of the FileInfo or DirectoryInfo class.

Add the following statements to the end of the Main method:

    string backup = @"/Users/markjprice/Code/Ch10.bak"; // macOS 
    // string backup = @"C:CodeCh10.bak"; // Windows 
    var info = new FileInfo(backup); 
    WriteLine($"{backup} contains {info.Length} bytes."); 
    WriteLine($"{backup} was last accessed {info.LastAccessTime}."); 
    WriteLine($"{backup} has readonly set to {info.IsReadOnly}."); 
Run the console application and view the output:
C:CodeCh10.bak contains 11 bytes.
C:CodeCh10.bak was last accessed 29/08/2015 16:25:47.
C:CodeCh10.bak has readonly set to False.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.134.232