File IO
Program Deployment
Understanding .NET components
-
Deployment: Software deployment is all of the activities that make a software system available for use.
-
Language Compilers: These turn your source code written with languages C# into intermediate language (IL) code stored in assemblies. With C# 6.0 and later, Microsoft switched to an open source rewritten compiler known as Roslyn that is also used by Visual Basic.
-
Assembly: Assemblies form the fundamental units of deployment, version control, reuse, activation scoping, and security permissions for .NET-based applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (.dll) files, and are the building blocks of .NET applications. Doc
-
Common Language Runtime (CLR): This runtime loads assemblies, compiles the IL code stored in them into native code instructions for your computer’s CPU, and executes the code within an environment that manages resources such as threads and memory.
-
Package (Class Library) Manager: A package manager or package-management system is a collection of software tools that automates the process of installing, upgrading, configuring, and removing computer programs for a computer in a consistent manner.
- Packages can ship on their own schedule.
- Packages can be tested independently of other packages.
- Packages can support different OSes and CPUs by including multiple versions of the same assembly built for different OSes and CPUs.
- Packages can have dependencies specific to only one library.
- Apps are smaller because unreferenced packages aren’t part of the distribution.
-
NuGet Packages: NuGet is the package manager for .NET. Note that .NET is split into a set of packages, distributed using a Microsoft-supported package management technology named NuGet. Doc
-
Base Class Library (BCL): The BCL provides the most foundational types and utility functionality and is the base of all other .NET class libraries. Doc
-
Namespace: A namespace is the address of a type. Namespaces are a mechanism to uniquely identify a type by requiring a full address rather than just a short name.
-
Dependency: A dependency in programming is an essential functionality, library or piece of code that is essential for a different part of the code to work.
Understanding the Microsoft .NET project SDKs
By default, console applications have a dependency reference on the Microsoft .NET SDK. This platform contains thousands of types in NuGet packages that almost all applications would need, such as the int and string types.
-
Software Development Kit (SDK): A software development kit (SDK) is a collection of software development tools in one installable package.
-
Application Programming Interface (API): An application programming interface is a connection between computers or between computer programs.
Understanding Frameworks
There is a two-way relationship between frameworks and packages. Packages define the APIs, while frameworks group packages. A framework without any packages would not define any APIs.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
$ cd C:\Program Files\dotnet\sdk // Windows 10
$ cd /usr/local/share/dotnet/sdk // MacOS
using System;
// using System.Xml.Linq;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
// XDocument doc = new XDocument();
Stack<int> myStack = new Stack<int>();
}
}
}
Publishing your Applications for Deployment
- Framework-dependent Deployment (FDD).
- Framework-dependent Executables (FDEs).
- Self-contained.
using System;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("I can run everywhere!");
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RuntimeIdentifiers>
win10-x64;osx-x64;rhel.7.4-x64
</RuntimeIdentifiers>
</PropertyGroup>
</Project>
- The win10-x64 RID value means Windows 10 or Windows Server 2016.
- The osx-x64 RID value means macOS High Sierra 10.13 or later.
- The rhel.7.4-x64 RID value means Red Hat Enterprise Linux (RHEL) 7.4 or later.
You can find the currently supported Runtime Identifier (RID) values from Doc.
Understanding dotnet Commands
- dotnet restore: This downloads dependencies for the project.
- dotnet build: This compiles the project.
- dotnet test: This runs unit tests on the project.
- dotnet run: This runs the project.
- dotnet pack: This creates a NuGet package for the project.
- dotnet publish: This compiles and then publishes the project, either with dependencies or as a self-contained application.
- dotnet add package: This adds a reference to a package or class library to the project.
- dotnet remove package: This removes a reference to a package or class library from the project.
- dotnet list package: This lists the package or class library references for the project.
$ dotnet list package
$ dotnet add package Newtonsoft.Json --version 13.0.1
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>
Publishing a Self-Contained App
- Debug Mode: Debug includes debugging information in the compiled files (allowing easy debugging).
- Release Mode: Release usually has optimizations enabled.
$ dotnet publish -c Release -r osx-x64
Publishing a Single-File App
$ dotnet publish -r osx-x64 -c Release --self-contained=false -p:PublishSingleFile=true
// The pdb is a program database file that stores debugging information.
Packaging a Library for NuGet
$ dotnet build -c Release
$ dotnet pack -c Release
Managing the filesystem
Handling cross-platform environments and filesystems
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Directory;
using static System.IO.Path;
using static System.Environment;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
OutputFileSystemInfo();
}
static void OutputFileSystemInfo()
{
WriteLine("{0,-33} {1}", "Path.PathSeparator", PathSeparator);
WriteLine("{0,-33} {1}", "Path.DirectorySeparatorChar",
DirectorySeparatorChar);
WriteLine("{0,-33} {1}", "Directory.GetCurrentDirectory()",
GetCurrentDirectory());
WriteLine("{0,-33} {1}", "Environment.CurrentDirectory",
CurrentDirectory);
WriteLine("{0,-33} {1}", "Environment.SystemDirectory",
SystemDirectory);
WriteLine("{0,-33} {1}", "Path.GetTempPath()", GetTempPath());
WriteLine("GetFolderPath(SpecialFolder");
WriteLine("{0,-33} {1}", " .System)",
GetFolderPath(SpecialFolder.System));
WriteLine("{0,-33} {1}", " .ApplicationData)",
GetFolderPath(SpecialFolder.ApplicationData));
WriteLine("{0,-33} {1}", " .MyDocuments)",
GetFolderPath(SpecialFolder.MyDocuments));
WriteLine("{0,-33} {1}", " .Personal)",
GetFolderPath(SpecialFolder.Personal));
}
}
}
On Windows
$ Path.PathSeparator ;
$ Path.DirectorySeparatorChar \
$ Directory.GetCurrentDirectory() C:\Users\lbwu\Dropbox\FH\BCC\C-Sharp\Codes\CRC_CSD-09\MyBusiness
$ Environment.CurrentDirectory C:\Users\lbwu\Dropbox\FH\BCC\C-Sharp\Codes\CRC_CSD-09\MyBusiness
$ Environment.SystemDirectory C:\Windows\system32
$ Path.GetTempPath() C:\Users\lbwu\AppData\Local\Temp\
$ GetFolderPath(SpecialFolder
$ .System) C:\Windows\system32
$ .ApplicationData) C:\Users\lbwu\AppData\Roaming
$ .MyDocuments) C:\Users\lbwu\Documents
$ .Personal) C:\Users\lbwu\Documents
On MacOS
$ Path.PathSeparator :
$ Path.DirectorySeparatorChar /
$ Directory.GetCurrentDirectory() /Users/yun/Dropbox/FH/BCC/C-Sharp/Codes/CRC_CSD-09/MyBusiness
$ Environment.CurrentDirectory /Users/yun/Dropbox/FH/BCC/C-Sharp/Codes/CRC_CSD-09/MyBusiness
$ Environment.SystemDirectory /System
$ Path.GetTempPath() /var/folders/y_/jv3nd6kn7_v88vmf3378p6p40000gn/T/
$ GetFolderPath(SpecialFolder
$ .System) /System
$ .ApplicationData) /Users/yun/.config
$ .MyDocuments) /Users/yun
$ .Personal) /Users/yun
Managing drives
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Directory;
using static System.IO.Path;
using static System.Environment;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithDrives();
}
static void WorkWithDrives()
{
WriteLine("{0,-30} | {1,-10} | {2,-7} | {3,18} | {4,18}",
"NAME", "TYPE", "FORMAT", "SIZE (BYTES)", "FREE SPACE");
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.IsReady)
{
WriteLine(
"{0,-30} | {1,-10} | {2,-7} | {3,18:N0} | {4,18:N0}",
drive.Name, drive.DriveType, drive.DriveFormat,
drive.TotalSize, drive.AvailableFreeSpace);
}
else
{
WriteLine("{0,-30} | {1,-10}", drive.Name, drive.DriveType);
}
}
}
}
}
On Windows
$ NAME | TYPE | FORMAT | SIZE (BYTES) | FREE SPACE
$ C:\ | Fixed | NTFS | 1,023,551,021,056 | 776,903,106,560
$ H:\ | Network | NTFS | 2,147,483,648 | 2,147,479,552
$ I:\ | Network | NTFS | 6,596,932,399,104 | 260,713,881,600
$ M:\ | Network | NTFS | 53,687,091,200 | 53,687,091,200
$ P:\ | Network | NTFS | 2,199,005,425,664 | 834,980,163,584
$ S:\ | Network | NTFS | 6,596,932,399,104 | 260,713,881,600
On MacOS
$ NAME | TYPE | FORMAT | SIZE (BYTES) | FREE SPACE
$ / | Fixed | apfs | 500,068,036,608 | 6,828,941,312
$ /dev | Ram | devfs | 194,048 | 0
$ /private/var/vm | Fixed | apfs | 500,068,036,608 | 6,828,941,312
$ /net | Network | autofs | 0 | 0
$ /home | Network | autofs | 0 | 0
$ /Volumes/firmwaresyncd.J9xOfG | Fixed | msdos | 206,472,192 | 182,210,048
Managing directories
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Directory;
using static System.IO.Path;
using static System.Environment;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithDirectories();
}
static void WorkWithDirectories()
{
// define a directory path for a new folder // starting in the user's folder
var newFolder = Combine(
GetFolderPath(SpecialFolder.Personal),
"Desktop", "MyNewFolder");
WriteLine($"Working with: {newFolder}"); // check if it exists
WriteLine($"Does it exist? {Exists(newFolder)}");
// create directory
WriteLine("Creating it...");
CreateDirectory(newFolder);
WriteLine($"Does it exist? {Exists(newFolder)}");
Write("Confirm the directory exists, and then press ENTER: ");
ReadLine();
// delete directory
WriteLine("Deleting it...");
Delete(newFolder, recursive: true);
WriteLine($"Does it exist? {Exists(newFolder)}");
}
}
}
$ Working with: /Users/yun/Desktop/MyNewFolder
$ Does it exist? False
$ Creating it...
$ Does it exist? True
$ Confirm the directory exists, and then press ENTER:
$ Deleting it...
$ Does it exist? False
Managing files
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Directory;
using static System.IO.Path;
using static System.Environment;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithFiles();
}
static void WorkWithFiles()
{
// define a directory path to output files // starting in the user's folder
var dir = Combine(
GetFolderPath(SpecialFolder.Personal),
"Desktop", "MyNewFiles");
CreateDirectory(dir);
// define file paths
string textFile = Combine(dir, "Dummy.txt");
string backupFile = Combine(dir, "Dummy.bak");
WriteLine($"Working with: {textFile}");
// check if a file exists
WriteLine($"Does it 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.Close(); // close file and release resources
WriteLine($"Does it exist? {File.Exists(textFile)}");
// copy the file, and overwrite if it already exists
File.Copy(sourceFileName: textFile,
destFileName: backupFile, overwrite: true);
WriteLine(
$"Does {backupFile} exist? {File.Exists(backupFile)}");
Write("Confirm the files exist, and then press ENTER: ");
ReadLine();
// delete file
File.Delete(textFile);
WriteLine($"Does it exist? {File.Exists(textFile)}");
// read from the text file backup
WriteLine($"Reading contents of {backupFile}:");
StreamReader textReader = File.OpenText(backupFile);
WriteLine(textReader.ReadToEnd());
textReader.Close();
}
}
}
$ Working with: /Users/yun/Desktop/MyNewFiles/Dummy.txt
$ Does it exist? False
$ Does /Users/yun/Desktop/MyNewFiles/Dummy.bak exist? True
$ Confirm the files exist, and then press ENTER:
$ Does it exist? False
$ Reading contents of /Users/yun/Desktop/MyNewFiles/Dummy.bak:
$ Hello, C#!
Managing paths
// Managing paths
WriteLine($"Folder Name: {GetDirectoryName(textFile)}");
WriteLine($"File Name: {GetFileName(textFile)}");
WriteLine("File Name without Extension: {0}",
GetFileNameWithoutExtension(textFile));
WriteLine($"File Extension: {GetExtension(textFile)}");
WriteLine($"Random File Name: {GetRandomFileName()}");
WriteLine($"Temporary File Name: {GetTempFileName()}");
$ Folder Name: /Users/yun/Desktop/MyNewFiles
$ File Name: Dummy.txt
$ File Name without Extension: Dummy
$ File Extension: .txt
$ Random File Name: qh4j5vy2.kgn
$ Temporary File Name: /var/folders/y_/jv3nd6kn7_v88vmf3378p6p40000gn/T/tmpfQQNS0.tmp
Getting file information
var info = new FileInfo(backupFile);
WriteLine($"{backupFile}:");
WriteLine($"Contains {info.Length} bytes");
WriteLine($"Last accessed {info.LastAccessTime}");
WriteLine($"Has readonly set to {info.IsReadOnly}")
$ /Users/yun/Desktop/MyNewFiles/Dummy.bak:
$ Contains 11 bytes
$ Last accessed 3/30/2022 8:44:26 AM
$ Has readonly set to False
Reading and writing with streams
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Directory;
using static System.IO.Path;
using static System.Environment;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithText();
}
// define an array of Viper pilot call signs
static string[] callsigns = new string[] {
"Husker", "Starbuck", "Apollo", "Boomer",
"Bulldog", "Athena", "Helo", "Racetrack" };
static void WorkWithText()
{
// define a file to write to
string textFile = Combine(CurrentDirectory, "streams.txt");
// create a text file and return a helper writer
StreamWriter text = File.CreateText(textFile);
// enumerate the strings, writing each one
// to the stream on a separate line
foreach (string item in callsigns)
{
text.WriteLine(item);
}
text.Close(); // release resources
// output the contents of the file
WriteLine("{0} contains {1:N0} bytes.",
arg0: textFile,
arg1: new FileInfo(textFile).Length);
WriteLine(File.ReadAllText(textFile));
}
}
}
/Users/yun/Dropbox/FH/BCC/C-Sharp/Codes/CRC_CSD-09/MyBusiness/streams.txt contains 60 bytes.
$ Husker
$ Starbuck
$ Apollo
$ Boomer
$ Bulldog
$ Athena
$ Helo
$ Racetrack
Writing to XML streams
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Path;
using static System.Environment;
using System.Xml;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithXml();
}
// define an array of Viper pilot call signs
static string[] callsigns = new string[] {
"Husker", "Starbuck", "Apollo", "Boomer",
"Bulldog", "Athena", "Helo", "Racetrack" };
static void WorkWithXml()
{
// define a file to write to
string xmlFile = Combine(CurrentDirectory, "streams.xml");
// create a file stream
FileStream xmlFileStream = File.Create(xmlFile);
// wrap the file stream in an XML writer helper
// and automatically indent nested elements
XmlWriter xml = XmlWriter.Create(xmlFileStream,
new XmlWriterSettings { Indent = true });
// write the XML declaration
xml.WriteStartDocument();
// write a root element
xml.WriteStartElement("callsigns");
// enumerate the strings writing each one to the stream
foreach (string item in callsigns)
{
xml.WriteElementString("callsign", item);
}
// write the close root element
xml.WriteEndElement();
// close helper and stream
xml.Close();
xmlFileStream.Close();
// output all the contents of the file
WriteLine("{0} contains {1:N0} bytes.",
arg0: xmlFile,
arg1: new FileInfo(xmlFile).Length);
WriteLine(File.ReadAllText(xmlFile));
}
}
}
$ /Users/yun/Dropbox/FH/BCC/C-Sharp/Codes/CRC_CSD-09/MyBusiness/streams.xml contains 310 bytes.
$ <?xml version="1.0" encoding="utf-8"?>
$ <callsigns>
$ <callsign>Husker</callsign>
$ <callsign>Starbuck</callsign>
$ <callsign>Apollo</callsign>
$ <callsign>Boomer</callsign>
$ <callsign>Bulldog</callsign>
$ <callsign>Athena</callsign>
$ <callsign>Helo</callsign>
$ <callsign>Racetrack</callsign>
$ </callsigns>
Disposing of file resources
When you open a file to read or write to it, you are using resources outside of .NET. These are called unmanaged resources and must be disposed of when you are done working with them.
using System.IO; // types for managing the filesystem
using static System.Console;
using static System.IO.Path;
using static System.Environment;
using System.Xml;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithXml();
}
// define an array of Viper pilot call signs
static string[] callsigns = new string[] {
"Husker", "Starbuck", "Apollo", "Boomer",
"Bulldog", "Athena", "Helo", "Racetrack" };
static void WorkWithXml()
{
FileStream? xmlFileStream = null;
XmlWriter? xml = null;
try
{
// define a file to write to
string xmlFile = Combine(CurrentDirectory, "streams.xml");
// create a file stream
xmlFileStream = File.Create(xmlFile);
// wrap the file stream in an XML writer helper
// and automatically indent nested elements
xml = XmlWriter.Create(xmlFileStream,
new XmlWriterSettings { Indent = true });
// write the XML declaration
xml.WriteStartDocument();
// write a root element
xml.WriteStartElement("callsigns");
// enumerate the strings writing each one to the stream
foreach (string item in callsigns)
{
xml.WriteElementString("callsign", item);
}
// write the close root element
xml.WriteEndElement();
// close helper and stream
xml.Close();
xmlFileStream.Close();
// output all the contents of the file
WriteLine($"{0} contains {1:N0} bytes.",
arg0: xmlFile,
arg1: new FileInfo(xmlFile).Length);
WriteLine(File.ReadAllText(xmlFile));
}
catch (Exception ex)
{
WriteLine($"{ex.GetType()} says {ex.Message}");
}
finally
{
if (xml != null)
{
xml.Dispose();
WriteLine("The XML writer's unmanaged resources have been disposed.");
}
if (xmlFileStream != null)
{
xmlFileStream.Dispose();
WriteLine("The file stream's unmanaged resources have been disposed.");
}
}
}
}
}
$ 0 contains 1 bytes.
$ <?xml version="1.0" encoding="utf-8"?>
$ <callsigns>
$ <callsign>Husker</callsign>
$ <callsign>Starbuck</callsign>
$ <callsign>Apollo</callsign>
$ <callsign>Boomer</callsign>
$ <callsign>Bulldog</callsign>
$ <callsign>Athena</callsign>
$ <callsign>Helo</callsign>
$ <callsign>Racetrack</callsign>
$ </callsigns>
$ The XML writer\'s unmanaged resources have been disposed.
$ The file stream\'s unmanaged resources have been disposed.
Encoding strings as byte arrays
using static System.Console;
using System.Text;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
WorkWithText();
}
static void WorkWithText()
{
WriteLine("Encodings");
WriteLine("[1] ASCII");
WriteLine("[2] UTF-7");
WriteLine("[3] UTF-8");
WriteLine("[4] UTF-16 (Unicode)");
WriteLine("[5] UTF-32");
WriteLine("[any other key] Default");
// choose an encoding
Write("Press a number to choose an encoding: ");
ConsoleKey number = ReadKey(intercept: false).Key;
WriteLine();
WriteLine();
Encoding encoder = number switch
{
ConsoleKey.D1 => Encoding.ASCII,
ConsoleKey.D2 => Encoding.UTF7,
ConsoleKey.D3 => Encoding.UTF8,
ConsoleKey.D4 => Encoding.Unicode,
ConsoleKey.D5 => Encoding.UTF32,
_ => Encoding.Default
};
// define a string to encode
string message = "A pint of milk is £1.99";
// encode the string into a byte array
byte[] encoded = encoder.GetBytes(message);
// check how many bytes the encoding needed
WriteLine("{0} uses {1:N0} bytes.",
encoder.GetType().Name, encoded.Length);
// enumerate each byte
WriteLine($"BYTE HEX CHAR");
foreach (byte b in encoded)
{
WriteLine($"{b,4} {b.ToString("X"),4} {(char)b,5}");
}
// decode the byte array back into a string and display it
string decoded = encoder.GetString(encoded);
WriteLine(decoded);
}
}
}
$ Encodings
$ [1] ASCII
$ [2] UTF-7
$ [3] UTF-8
$ [4] UTF-16 (Unicode)
$ [5] UTF-32
$ [any other key] Default
$ Press a number to choose an encoding: 1
$ ASCIIEncodingSealed uses 23 bytes.
$ BYTE HEX CHAR
$ 65 41 A
$ 32 20
$ 112 70 p
$ 105 69 i
$ 110 6E n
$ 116 74 t
$ 32 20
$ 111 6F o
$ 102 66 f
$ 32 20
$ 109 6D m
$ 105 69 i
$ 108 6C l
$ 107 6B k
$ 32 20
$ 105 69 i
$ 115 73 s
$ 32 20
$ 63 3F ?
$ 49 31 1
$ 46 2E .
$ 57 39 9
$ 57 39 9
$ A pint of milk is ?1.99
Serializing Objects
- Serialization: is the process of converting a live object into a sequence of bytes using a specified format.
- Deserialization: is the reverse process of Serialization:.
There are dozens of formats you can specify, but the two most common ones are eXtensible Markup Language (XML) and JavaScript Object Notation (JSON).
Serializing as XML
In Program.cs,
using System; // DateTime
using System.Collections.Generic; // List<T>, HashSet<T>
using System.Xml.Serialization; // XmlSerializer
using System.Xml;
using static System.Console;
using static System.Environment;
using static System.IO.Path;
using Animals;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
// create an object graph
var people = new List<Person> {
new Person(30000M) { FirstName = "Alice",
LastName = "Smith",
DateOfBirth = new DateTime(1974, 3, 14) },
new Person(40000M) { FirstName = "Bob",
LastName = "Jones",
DateOfBirth = new DateTime(1969, 11, 23) },
new Person(20000M) { FirstName = "Charlie",
LastName = "Cox",
DateOfBirth = new DateTime(1984, 5, 4),
Children = new HashSet<Person> {
new Person(0M) { FirstName = "Sally",
LastName = "Cox",
DateOfBirth = new DateTime(2000, 7, 12) } } }
};
// create object that will format a List of Persons as XML
var xs = new XmlSerializer(typeof(List<Person>));
// create a file to write to
string path = Combine(CurrentDirectory, "people.xml");
using (FileStream stream = File.Create(path))
{
// serialize the object graph to the stream
xs.Serialize(stream, people);
}
WriteLine("Written {0:N0} bytes of XML to {1}",
arg0: new FileInfo(path).Length,
arg1: path);
WriteLine();
// Display the serialized object graph
WriteLine(File.ReadAllText(path));
}
}
}
In Animals.cs,
using System;
using System.Collections.Generic;
/*
The animal namespace
*/
namespace Animals
{
public class Person
{
public Person()
{
}
public Person(decimal initialSalary)
{
Salary = initialSalary;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public HashSet<Person> Children { get; set; }
protected decimal Salary { get; set; }
}
}
$ <?xml version="1.0" encoding="utf-8"?><ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Person><FirstName>Alice</FirstName><LastName>Smith</LastName><DateOfBirth>1974-03-14T00:00:00</DateOfBirth></Person><Person><FirstName>Bob</FirstName><LastName>Jones</LastName><DateOfBirth>1969-11-23T00:00:00</DateOfBirth></Person><Person><FirstName>Charlie</FirstName><LastName>Cox</LastName><DateOfBirth>1984-05-04T00:00:00</DateOfBirth><Children><Person><FirstName>Sally</FirstName><LastName>Cox</LastName><DateOfBirth>2000-07-12T00:00:00</DateOfBirth></Person></Children></Person></ArrayOfPerson>
Deserializing XML files
using (FileStream xmlLoad = File.Open(path, FileMode.Open))
{
// deserialize and cast the object graph into a List of Person
var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
foreach (var item in loadedPeople)
{
WriteLine("{0} has {1} children.",
item.LastName, item.Children.Count);
}
}
$ Smith has 0 children.
$ Jones has 0 children.
$ Cox has 1 children.
Taking Care of System-Dependent Methods Doc
using System;
namespace MyBusiness
{
class Program
{
static void Main(string[] args)
{
Console.Write("My operating system (OS) is ");
Console.WriteLine(Environment.OSVersion);
Console.Write("Is my OS a Mac? ");
Console.WriteLine(OperatingSystem.IsMacOS());
// Console.WriteLine(OperatingSystem.IsWindows());
// Console.WriteLine(OperatingSystem.IsLinux());
Console.Write("Environment.SpecialFolder.Personal = ");
Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
Console.Write("Environment.SpecialFolder.UserProfile = ");
Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
}
}
}
On Windows
My operating system (OS) is Microsoft Windows NT 10.0.19044.0
Is my OS a Mac? False
Environment.SpecialFolder.Personal = C:\Users\lbwu\Documents
Environment.SpecialFolder.UserProfile = C:\Users\lbwu
On MacOS
My operating system (OS) is Unix 10.14.6
Is my OS a Mac? True
Environment.SpecialFolder.Personal = /Users/yun
Environment.SpecialFolder.UserProfile = /Users/yun