06.文件(流)IO
- 2021 年 8 月 14 日
- 筆記
- ASP.NET 進階之路
參考文章
1. 驅動器操作
在Windows
作業系統中,存儲介質統稱為驅動器,硬碟由於可以劃分為多個區域,每一個區域稱為一個驅動器
.NET提供DriveInfo
類和 DriveType
枚舉型,以方便在程式中直接使用驅動器
1.1 驅動器資訊
DriveInfo
類表示單個驅動器資訊
實例屬性
屬性 | 屬性值類型 | 描述 |
---|---|---|
driveInfo.Name | string | 驅動器名(C:\) |
driveInfo.DriveFormat | string | 文件系統格式 |
driveInfo.DriveType | DriveType | 驅動器類型 |
driveInfo.TotalSize | long | 總空間(位元組) |
driveInfo.TotalFreeSpace | long | 可用空間(位元組) |
靜態方法
方法 | 返回值類型 | 描述 |
---|---|---|
DriveInfo.GetDrives() | DriveInfo | 獲取可用驅動器列表 |
DriveType
枚舉,驅動器類型
枚舉值 | 描述 | 枚舉值 | 描述 | |
---|---|---|---|---|
DriveType.CDRom | 光碟機 | DriveType.Network | 網路驅動器 | |
DriveType.Fixed | 硬碟 | DriveType.Removeable | 軟盤或U盤 |
1.2 示例程式碼
示例一:獲取本地所有驅動器資訊
using System;
using System.IO;
namespace io1
{
class Program
{
static void Main(string[] args)
{
DriveInfo[] dirves = DriveInfo.GetDrives();
foreach (var driveInfo in dirves)
{
Console.Write("驅動器名(C:\\):" + driveInfo.Name);
Console.Write("\t文件系統格式:" + driveInfo.DriveFormat);
Console.Write("\t驅動器類型:" + driveInfo.DriveType);
Console.Write("\t總空間(位元組):" + driveInfo.TotalSize);
Console.Write("\t可用空間(位元組):" + driveInfo.TotalFreeSpace);
Console.WriteLine();
}
}
}
}
示例二:獲取每個【硬碟】驅動器剩餘空間資訊
using System;
using System.IO;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
DriveInfo[] drivers = DriveInfo.GetDrives();
foreach (DriveInfo driver in drivers)
{
if (driver.DriveType == DriveType.Fixed && driver.DriveFormat == "NTFS")
{
Console.WriteLine("在{0}驅動器剩餘空間{1}位元組",
driver.Name, driver.TotalFreeSpace);
}
}
Console.ReadLine();
}
}
}
2. 目錄操作
在Windows
作業系統中,目錄又稱文件夾,每個驅動器都有一個根目錄,使用」\
」表示,如」C:\
」表示C驅動器的根目錄
.NET提供了Directory
類和DirectoryInfo
類,以方便在程式中直接操作目錄
2.1 Directory
類(靜態類)
靜態方法(常用)
方法 | 返回值類型 | 描述 |
---|---|---|
Directory.Exists(…) | bool | 判斷目錄是否存在 |
Directory.CreateDirectory(…) | DirectoryInfo | 創建新目錄 |
Directory.Delete(…) | void | 刪除目錄【子目錄】 |
Directory.Move(…) | void | 移動或重命名目錄 |
Directory.GetDirectories(…) | string[] | 獲得子目錄(路徑目錄)列表 |
Directory.GetFiles(…) | string[] | 獲得目錄的文件(包含路徑和後綴)列表 |
Directory.GetParent(…) | DirectoryInfo | 獲取此目錄的父目錄(以\ 符號為分界點) |
Directory.GetDirectoryRoot(…) | string | 獲取此文件夾的根目錄 |
程式碼示例
using System;
using System.IO;
namespace io2
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\今日安排";
if (!Directory.Exists(dir))
{
Console.WriteLine("文件夾不存在!");
return;
}
// 獲取目錄下所有子目錄(當前目錄下的目錄,無遞歸)
Console.WriteLine("\t\t目錄");
string[] directories = Directory.GetDirectories(dir);
foreach (var directorie_item in directories)
{
Console.WriteLine(directorie_item);
}
// 獲取目錄下所有文件(當前目錄下文件)
Console.WriteLine("\t\t文件");
string[] files = Directory.GetFiles(dir);
foreach (var file_item in files)
{
Console.WriteLine(file_item);
}
// 獲取文件夾創建時間
Console.WriteLine("\t\t創建時間");
Console.WriteLine(Directory.GetCreationTime(dir));
// 獲取文件夾根目錄
Console.WriteLine("\t\t根目錄");
Console.WriteLine(Directory.GetDirectoryRoot(dir));
Console.WriteLine("\t\t父目錄");
Console.WriteLine(Directory.GetParent(@"X:\今日安排").Name); // X:\
Console.WriteLine(Directory.GetParent(@"X:\今日安排\").Name); // 今日安排
Console.WriteLine("\t\t移動並重命名目錄(只限當前盤符內操作)");
Directory.Move(@"X:\今日安排\A", @"X:\B"); // 移動並重命名目錄
Directory.Move(@"X:\B", @"X:\C"); // 重命名目錄
Console.WriteLine("\t\t刪除目錄(謹慎操作)");
Directory.Delete(@"X:\d"); // 刪除空目錄,非空時異常
Directory.Delete(@"X:\e",true); // 遞歸刪除目錄(包括目錄下子目錄,文件)
}
}
}
2.2 DirectoryInfo
類(實例類)
實例屬性(常用)
屬性 | 屬性值類型 | 描述 |
---|---|---|
directory.Name | string | 目錄名 |
directory.Root | DirectoryInfo | 根目錄 |
directory.Parent | DirectoryInfo | 父目錄 |
directory.Exists | bool | 判斷目錄是否存在 |
directory.FullName | string | 目錄全路徑 |
實例方法
方法 | 返回值類型 | 描述 |
---|---|---|
directory.Create() | void | 創建目錄 |
directory.Delete(…) | void | 刪除目錄【子目錄】 |
directory.GetFiles(…) | FileInfo[] | 獲取目錄下文件對象(此目錄) |
directory.GetDirectories(…) | DirectoryInfo[] | 獲取目錄下目錄對象(此目錄) |
directory.MoveTo(…) | void | 移動目錄或重命名 |
示例程式碼
示例一:獲取目錄基本資訊
using System;
using System.IO;
namespace io2
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\今日安f排";
DirectoryInfo directory = new DirectoryInfo(dir);
Console.WriteLine("目錄名:"+directory.Name);
Console.WriteLine("根目錄:"+directory.Root.Name);
Console.WriteLine("父目錄:"+directory.Parent.Name);
Console.WriteLine("判斷目錄是否存在:" + directory.Exists);
Console.WriteLine("目錄全路徑:"+directory.FullName);
}
}
}
示例二:方法操作
using System;
using System.IO;
namespace io2
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\今日安排";
DirectoryInfo directory = new DirectoryInfo(dir);
if (directory.Exists)
{
directory.Create();
}
Console.WriteLine("\t\t目錄下文件對象");
foreach (FileInfo file_item in directory.GetFiles())
{
Console.WriteLine(file_item.Name);
}
Console.WriteLine("\t\t目錄下目錄對象");
foreach (DirectoryInfo dir_item in directory.GetDirectories())
{
Console.WriteLine(dir_item.Name);
}
DirectoryInfo info = new DirectoryInfo(@"X:\a");
info.MoveTo(@"x:\b");
}
}
}
3. 文件操作
文件的操作主要是分為兩個類,一個是File
類,一個是FileInfo
類,File
和FileInfo
類位於System.IO
命名空間,都可以用來實現創建、複製、移動、打開文件等操作
3.1 File
類(靜態類)
File
類是一個文件的基本操作類,提供用於創建、複製、刪除、移動和打開文件的靜態方法,並協助創建 FileStream
對象
靜態方法(常用)
方法 | 返回值類型 | 描述 |
---|---|---|
File.Exists(…) | bool | 判斷文件是否存在 |
File.Open(…) | FileStream | 打開或創建文件 |
File.Create(…) | FileStream | 創建或覆蓋文件,可以指定緩衝區大小 |
File.Delete(…) | void | 刪除文件 |
File.Copy(…) | void | 複製文件 |
File.Move(…) | void | 移動文件 |
File.AppendAllText(…) | void | 新建文件並添加文本內容 |
File.ReadAllText(…) | string | 打開並讀取文本內容 |
File.AppendText(…) | StreamWriter | 打開或創建文件並創建寫入對象 |
File.OpenText(…) | StreamReader | 打開或創建文件並創建讀取對象 |
File.Replace(…) | void | 刪除原始文件,並創建替換文件的備份 |
示例程式碼
using System;
using System.IO;
namespace io3
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\今日安排";
string file = "解壓密碼.txt";
string file_path = Path.Combine(dir, file);
if (!File.Exists(file_path))
{
// 創建文件(存在則覆蓋),並返回一個打開的 FileStream 流對象
FileStream stream = File.Create(file_path);
stream.Close();
}
// 打開或創建文件,返回一個可讀可寫的流對象
FileStream fileStream1 = File.Open(file_path,FileMode.OpenOrCreate);
fileStream1.Close();
// 打開或創建文件,返回一個可讀的文件流對象
FileStream fileStream2 = File.Open(file_path, FileMode.OpenOrCreate, FileAccess.Read);
fileStream2.Close();
// 打開文件,並指定模式為讀取模式
using (FileStream fileStream3 = File.OpenRead(file_path))
{
}
// 新建文件並添加文本
File.AppendAllText(file_path,"李白", System.Text.Encoding.UTF8);
// 打開並讀取文件內容
string text = File.ReadAllText(file_path,System.Text.Encoding.UTF8);
Console.WriteLine(text);
// 打開文件,並創建一個寫入對象
using (StreamWriter writer = File.AppendText(file_path))
{
}
// 打開文件,並創建一個讀取對象
using (StreamReader reader = File.OpenText(file_path))
{
}
// 複製文件,指定新文件路徑,文件名(若已存在在文件名則異常)
File.Copy(file_path,Path.Combine(dir,"1.txt"));
// 刪除文件,前提是文件必須存在,且沒有使用此文件
File.Delete(file_path);
File.Delete(Path.Combine(dir, "1.txt"));
}
}
}
3.2 FileInfo
類(實例類)
實例化FileInfo
實例時,若指定文件不存在,在使用實例屬性時不會異常,但是調用實例方法(具有返回值的方法)時會異常
實例屬性(常用)
屬性 | 屬性值類型 | 描述 |
---|---|---|
fileinfo.Name | string | 文件名 |
fileinfo.DirectoryName | string | 文件所在目錄名 |
fileinfo.Directory | DirectoryInfo | 文件所在目錄 |
fileinfo.Exists | bool | 文件是否存在 |
fileinfo.Extension | string | 文件後綴名 |
fileinfo.FullName | string | 文件全名稱 |
fileinfo.Length | long | 文件大小(位元組) |
fileinfo.IsReadOnly | bool | 文件是否只讀 |
實例方法(常用),常用的方法和
File
類中的相同
參考 File
類方法
程式碼示例
示例一:獲取文件基本資訊
using System;
using System.IO;
namespace io3
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\b";
string file = "1.txt";
string file_path = Path.Combine(dir, file);
FileInfo fileinfo = new FileInfo(file_path);
Console.WriteLine("文件名」" + fileinfo.Name);
Console.WriteLine("文件所在目錄:" + fileinfo.Directory.Name);
Console.WriteLine("文件所在目錄名:" + fileinfo.DirectoryName);
Console.WriteLine("文件是否存在:" + fileinfo.Exists);
Console.WriteLine("文件後綴名:" + fileinfo.Extension);
Console.WriteLine("文件全名稱:" + fileinfo.FullName);
Console.WriteLine("文件大小(位元組):" + fileinfo.Length);
Console.WriteLine("文件是否只讀:" + fileinfo.IsReadOnly);
}
}
}
示例二:方法操作
using System;
using System.IO;
namespace io3
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\b";
string file = "1.txt";
string file_path = Path.Combine(dir, file);
FileInfo fileinfo = new FileInfo(file_path);
// 打開或創建可讀文件
using (FileStream stream = fileinfo.Open(FileMode.OpenOrCreate, FileAccess.Read))
{
}
// 打開文件並創建輸入(寫)對象
using (StreamWriter writer = fileinfo.AppendText())
{
}
// 刪除文件
// fileinfo.Delete();
}
}
}
4. 數據流操作
流包括以下基本操作:
- 讀取(
read
):把數據從流傳輸到某種數據結構中,如輸出到字元數組中 - 寫入(
write
):把數據從某種數據結構傳輸到流中,如把位元組數組中的數據傳輸到流中 - 定位(
seek
):在流中查找或重新定位當前位置
4.1 Stream
類
一個抽象類,提供位元組流的基本屬性,操作,是各種數據流的基類
屬性
-
CanRead(是否支援讀取)
-
CanSeek(是否支援查找)
-
CanTimeout(是否可以超時)
-
CanWrite(是否支援寫入)
-
Length(流的長度)
-
Position(獲取或設置當前流中的位置)
-
ReadTimeout(獲取或設置讀取操作的超時時間)
-
WriteTimeout(獲取或設置寫操作的超時時間)
方法
-
BeginRead(開始非同步讀操作)
-
BeginWrite(開始非同步寫操作)
-
Close(關閉當前流)
-
EndRead(結束非同步讀操作)
-
EndWrite(結束非同步寫操作)
-
Flush(清除流的所有緩衝區並把緩衝數據寫入基礎設備)
-
Read(讀取位元組序列)
-
ReadByte(讀取一個位元組)
-
Seek(設置查找位置)
-
Write(寫入位元組序列)
-
WriteByte(寫入一個位元組)
4.2 各種文件流
FileStream
類
文件流類FileStream
以流的形式讀、寫、打開、關閉文件;另外,它還可以用來操作諸如:管道、標準輸入/輸出等其他與文件相關的作業系統句柄
MemoryStream
類
記憶體流MemoryStream
類用來在記憶體中創建流,以暫時保持數據,因此有了它就無須在硬碟上創建臨時文件;它將數據封裝為無符號的位元組序列,可以直接進行讀、寫、查找操作
BufferedStream
類
緩衝流BufferedStream
類表示把流先添加到緩衝區,再進行數據的讀/寫操作。緩衝區是存儲區中用來快取數據的位元組塊;使用緩衝區可以減少訪問數據時對作業系統的調用次數,增強系統的讀/寫功能
4.3 流讀寫器
- 流讀取器
StreamReader
類用來以一種特定的編碼(如:UTF-8)從位元組流中讀取字元 - 流寫入器
StreamWriter
類用來以一種特定的編碼(如:UTF-8)向流中寫入字元
try
{
//保留文件現有數據,以追加寫入的方式打開d:\file.txt文件
StreamWriter m_SW = new StreamWriter(@"d:\file.txt", true);
//向文件寫入新字元串,並關閉StreamWriter
m_SW.WriteLine("Another File Operation Method");
m_SW.Close();
}
catch (Exception ex)
{
Console.WriteLine("There is an IOException");
Console.WriteLine(ex.Message);
}
StreamWriter類提供了另一種從文件中讀取數據的方法,下面演示其用法:
try
{
//以絕對路徑方式構造新的StreamReader對象
StreamReader m_SR = new StreamReader(@"d:\file.txt");
//用ReadToEnd方法將d:\file.txt中的數據全部讀入到字元串m_Data中,並關閉StreamReader
string m_Data = m_SR.ReadToEnd();
m_SR.Close();
Console.WriteLine(m_Data);
}
catch (Exception ex)
{
Console.WriteLine("There is an IOException");
Console.WriteLine(ex.Message);
}
5. 序列化操作
5.1 二進位序列化
需要序列化的類必須支援可序列化
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace io5
{
class Program
{
static void Main(string[] args)
{
List<User> list = new List<User>
{
new User{ id=1,name="李白" },
new User{ id=2,name="貂蟬" },
new User{ id=3,name=null }
};
// 二進位序列化
list.BinarySerialize();
}
}
[Serializable] //必須添加序列化特性
public class User
{
public int id { get; set; }
public string name { get; set; }
}
// 使用擴展方法只是為了好調用,沒有其它
public static class SerializeHelper
{
// 二進位序列化器
public static void BinarySerialize<T>(this List<T> list)
{
//使用二進位序列化對象
string fileName = Path.Combine("File", @"BinarySerialize.txt");//文件名稱與路徑
if (!Directory.Exists("File"))
Directory.CreateDirectory("File");
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
BinaryFormatter binFormat = new BinaryFormatter();//創建二進位序列化器
binFormat.Serialize(fStream, list);
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
BinaryFormatter binFormat = new BinaryFormatter();//創建二進位序列化器
//使用二進位反序列化對象
fStream.Position = 0;//重置流位置
List<T> pList = (List<T>)binFormat.Deserialize(fStream);//反序列化對象
}
}
}
}
5.2 XML序列化
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace io5
{
class Program
{
static void Main(string[] args)
{
List<User> list = new List<User>
{
new User{ id=1,name="李白" },
new User{ id=2,name="貂蟬" },
new User{ id=3,name=null }
};
// 二進位序列化
list.XmlSerialize();
}
}
public class User
{
public int id { get; set; }
public string name { get; set; }
}
// 使用擴展方法只是為了好調用,沒有其它
public static class SerializeHelper
{
// XML序列化器
public static void XmlSerialize<T>(this List<T> list)
{
//使用XML序列化對象
string fileName = Path.Combine("File", @"XmlSerialize.xml");//文件名稱與路徑
if (!Directory.Exists("File"))
Directory.CreateDirectory("File");
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<T>));//創建XML序列化器,需要指定對象的類型
xmlFormat.Serialize(fStream, list);
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<T>));//創建XML序列化器,需要指定對象的類型
//使用XML反序列化對象
fStream.Position = 0;//重置流位置
List<T> pList = pList = (List<T>)xmlFormat.Deserialize(fStream);
}
}
}
}
5.3 JSON序列化
using Newtonsoft.Json;
using System.Collections.Generic;
namespace io5
{
class Program
{
static void Main(string[] args)
{
List<User> list = new List<User>
{
new User{ id=1,name="李白" },
new User{ id=2,name="貂蟬" },
new User{ id=3,name=null }
};
string jResult = list.ToJson();
List<User> list1 = SerializeHelper.ToObject<User>(jResult);
}
}
public class User
{
public int id { get; set; }
public string name { get; set; }
}
// 使用擴展方法只是為了好調用,沒有其它
public static class SerializeHelper
{
public static string ToJson<T>(this List<T> obj)
{
return JsonConvert.SerializeObject(obj);
}
public static List<T> ToObject<T>(string content)
{
return JsonConvert.DeserializeObject<List<T>>(content);
}
}
}
6. 示例程式碼
6.1 示例一:簡單文本日誌
using System;
using System.IO;
namespace io4
{
class Program
{
static void Main(string[] args)
{
Log("李白");
}
static void Log(string msg)
{
StreamWriter writer = null;
string file_path = Path.Combine("Log",DateTime.Now.ToString("yyyyMMddHHmmss")+".log");
try
{
// bin 文件夾中創建 Log 文件夾
if (!Directory.Exists("Log"))
{
Directory.CreateDirectory("Log");
}
writer = File.AppendText(file_path);
writer.WriteLine(msg);
}
catch (Exception ex)
{
writer.WriteLine(ex.Message);
}
finally
{
if (writer != null)
{
writer.Flush();
writer.Close();
writer.Dispose();
}
}
}
}
}
7. 擴展補充
7.1 Path類
using System;
using System.IO;
namespace io4
{
class Program
{
static void Main(string[] args)
{
string dir = @"X:\b";
string file = "1.txt";
string file_path = Path.Combine(dir,file);
Console.WriteLine(Path.GetDirectoryName(@"X:\b")); // X:\
Console.WriteLine(Path.GetDirectoryName(@"X:\b\")); // X:\b
Console.WriteLine(Path.GetRandomFileName()); // 返回隨機的文件名(包含後綴)
Console.WriteLine(Path.GetFileNameWithoutExtension(file_path)); // 返回當前文件(無後綴)/目錄名
Console.WriteLine(Path.GetInvalidPathChars()); // 返回在路徑中禁止使用額字元
Console.WriteLine(Path.GetInvalidFileNameChars()); // 返回在文件名中禁止使用額字元
Console.WriteLine(Path.Combine(dir,"c",file)); // 合併路徑與文件名,文件名必須在最後一個位
}
}
}
7.2 目錄操作
Directory
類和DirectoryInfo
類區別
兩者可以說絕大多數功能是重複的,只是directoryinfo
需要實例化使用,directory
為靜態函數,一個是實例類,一個是公用的靜態類
兩者是為不同的使用場景準備的,directoryinfo
與directory
的函數內部有一些是相同的處理函數,而且某些directoryinfo
的函數甚至就直接調用了directory
函數;如果多次使用某個對象一般使用前者(directoryinfo
),如果僅執行某一個操作則使用後者(directory
)提供的靜態方法效率更高一些
Directory
類獲取父目錄,使用時需要注意,目錄之間以\
為分界點
Console.WriteLine(Directory.GetParent(@"X:\今日安排").Name); // X:\
Console.WriteLine(Directory.GetParent(@"X:\今日安排\").Name); // 今日安排
Directory
和DirectoryInfo
移動目錄,移動操作只能在同一盤符內(window
上目錄名不區分大小寫)
Directory.Move(@"X:\今日安排\A", @"X:\B"); // 移動並重命名目錄
Directory.Move(@"X:\b", @"X:\C"); // 重命名目錄
DirectoryInfo info = new DirectoryInfo(@"X:\a");
info.MoveTo(@"x:\b"); // 重命名
Directory
類刪除目錄,需要注意目錄下是否有子項(目錄,文件)
Directory.Delete(@"X:\d"); // 刪除空目錄,非空時異常
Directory.Delete(@"X:\e",true); // 遞歸刪除目錄(包括目錄下子目錄,文件)
DirectoryInfo info = new DirectoryInfo(@"X:\a");
info.Deleve(); // 刪除目錄,有子項時異常
info.Deleve(true); // 刪除目錄,包括子項
初始化
DirectoryInfo
實例時,傳入的目錄路徑如果不存在也不會異常(推薦先判斷後操作)
說明:使用實例對象屬性時不會發生異常,但是使用實例方法時(具有返回值的方法)目錄不存在會異常
DirectoryInfo directory = new DirectoryInfo("X:\1"); // 如果目錄不存在不會異常
DirectoryInfo directory = new DirectoryInfo("X:\2");
directory.Create(); // 不存在不會異常
var files = directory.GetFiles(); // 不存在異常
7.3 文件操作
靜態類與實例類使用場景
File
類和Directory
類適合對不同的對象進行單一的處理,此種特殊情況下,靜態方法的調用速度比較快,不用進行實例化FileInfo
類和DirectoryInfo
類適合用於對同一文件或文件夾進行多種操作的情況,此種情況下,實例化後的對象不需要每次都尋找文件,可以直接對該文件進行操作
7.4 XML序列化
補充示例一
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace io5
{
class Program
{
static void Main(string[] args)
{
List<User> list = new List<User>
{
new User{ id=1,name="李白" },
new User{ id=2,name="貂蟬" },
new User{ id=3,name=null }
};
var text = SerializeHelper.ToXml(list);
var list1 = SerializeHelper.ToObject<List<User>>(text);
var list2 = SerializeHelper.FileToObject<List<User>>("");
}
}
public class User
{
public int id { get; set; }
public string name { get; set; }
}
// 使用擴展方法只是為了好調用,沒有其它
public static class SerializeHelper
{
// XmlSerializer序列化實體為字元串
public static string ToXml<T>(T t) where T : new()
{
XmlSerializer xmlSerializer = new XmlSerializer(t.GetType());
Stream stream = new MemoryStream();
xmlSerializer.Serialize(stream, t);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
return text;
}
// 字元串XML序列化成實體
public static T ToObject<T>(string content) where T : new()
{
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content)))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(T));
return (T)xmlFormat.Deserialize(stream);
}
}
// 文件反序列化成實體
public static T FileToObject<T>(string fileName) where T : new()
{
string CurrentXMLPath = "File";
fileName = Path.Combine(CurrentXMLPath, @"XmlSerialize.xml");
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(T));
return (T)xmlFormat.Deserialize(fStream);
}
}
}
}
補充示例二
using System;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.Data;
using System.Collections.Generic;
namespace IOSerialize.Serialize
{
public static class xHelper
{
/// <summary>
/// 實體轉化為XML
/// </summary>
public static string ParseToXml<T>(this T model, string fatherNodeName)
{
var xmldoc = new XmlDocument();
var modelNode = xmldoc.CreateElement(fatherNodeName);
xmldoc.AppendChild(modelNode);
if (model != null)
{
foreach (PropertyInfo property in model.GetType().GetProperties())
{
var attribute = xmldoc.CreateElement(property.Name);
if (property.GetValue(model, null) != null)
attribute.InnerText = property.GetValue(model, null).ToString();
//else
// attribute.InnerText = "[Null]";
modelNode.AppendChild(attribute);
}
}
return xmldoc.OuterXml;
}
/// <summary>
/// XML轉換為實體,默認 fatherNodeName="body"
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <param name="fatherNodeName"></param>
/// <returns></returns>
public static T ParseToModel<T>(this string xml, string fatherNodeName = "body") where T : class ,new()
{
if (string.IsNullOrEmpty(xml))
return default(T);
var xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
T model = new T();
var attributes = xmldoc.SelectSingleNode(fatherNodeName).ChildNodes;
foreach (XmlNode node in attributes)
{
foreach (var property in model.GetType().GetProperties().Where(property => node.Name == property.Name))
{
if (!string.IsNullOrEmpty(node.InnerText))
{
property.SetValue(model,
property.PropertyType == typeof(Guid)
? new Guid(node.InnerText)
: Convert.ChangeType(node.InnerText, property.PropertyType));
}
else
{
property.SetValue(model, null);
}
}
}
return model;
}
/// <summary>
/// XML轉實體
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <param name="headtag"></param>
/// <returns></returns>
public static List<T> XmlToObjList<T>(this string xml, string headtag)
where T : new()
{
var list = new List<T>();
XmlDocument doc = new XmlDocument();
PropertyInfo[] propinfos = null;
doc.LoadXml(xml);
XmlNodeList nodelist = doc.SelectNodes(headtag);
foreach (XmlNode node in nodelist)
{
T entity = new T();
if (propinfos == null)
{
Type objtype = entity.GetType();
propinfos = objtype.GetProperties();
}
foreach (PropertyInfo propinfo in propinfos)
{
//實體類欄位首字母變成小寫的
string name = propinfo.Name.Substring(0, 1) + propinfo.Name.Substring(1, propinfo.Name.Length - 1);
XmlNode cnode = node.SelectSingleNode(name);
string v = cnode.InnerText;
if (v != null)
propinfo.SetValue(entity, Convert.ChangeType(v, propinfo.PropertyType), null);
}
list.Add(entity);
}
return list;
}
}
}
7.5 Linq to xml示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace IOSerialize.Serialize
{
/// <summary>
/// Linq to xml示例
/// </summary>
public class LinqToXml
{
/// <summary>
/// 創建XML文件
/// </summary>
/// <param name="xmlPath"></param>
private static void CreateXmlFile(string xmlPath)
{
try
{
//定義一個XDocument結構
XDocument myXDoc = new XDocument(
new XElement("Users",
new XElement("User", new XAttribute("ID", "111111"),
new XElement("name", "EricSun"),
new XElement("password", "123456"),
new XElement("description", "Hello I'm from Dalian")),
new XElement("User", new XAttribute("ID", "222222"),
new XElement("name", "Ray"),
new XElement("password", "654321"),
new XElement("description", "Hello I'm from Jilin"))));
//保存此結構(即:我們預期的xml文件)
myXDoc.Save(xmlPath);
string aa = myXDoc.ToString();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
/// <summary>
/// 遍歷xml資訊
/// </summary>
/// <param name="xmlPath"></param>
private static void GetXmlNodeInformation(string xmlPath)
{
try
{
//定義並從xml文件中載入節點(根節點)
XElement rootNode = XElement.Load(xmlPath);
//XElement rootNode2 = XElement.Parse(xmlPath);
//查詢語句: 獲得根節點下name子節點(此時的子節點可以跨層次:孫節點、重孫節點......)
IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("name")
select target;
foreach (XElement node in targetNodes)
{
Console.WriteLine("name = {0}", node.Value);
}
//查詢語句: 獲取ID屬性值等於"111111"並且函數子節點的所有User節點(並列條件用"&&"符號連接)
IEnumerable<XElement> myTargetNodes = from myTarget in rootNode.Descendants("User")
where myTarget.Attribute("ID").Value.Equals("111111")
&& myTarget.HasElements
select myTarget;
foreach (XElement node in myTargetNodes)
{
Console.WriteLine("name = {0}", node.Element("name").Value);
Console.WriteLine("password = {0}", node.Element("password").Value);
Console.WriteLine("description = {0}", node.Element("description").Value);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public static void ModifyXmlNodeInformation(string xmlPath)
{
try
{
//定義並從xml文件中載入節點(根節點)
XElement rootNode = XElement.Load(xmlPath);
//查詢語句: 獲取ID屬性值等於"222222"或者等於"777777"的所有User節點(或條件用"||"符號連接)
IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("User")
where target.Attribute("ID").Value == "222222"
|| target.Attribute("ID").Value.Equals("777777")
select target;
//遍歷所獲得的目標節點(集合)
foreach (XElement node in targetNodes)
{
//將description節點的InnerText設置為"Hello, I'm from USA."
node.Element("description").SetValue("Hello, I'm from USA.");
}
//保存對xml的更改操作
rootNode.Save(xmlPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static void AddXmlNodeInformation(string xmlPath)
{
try
{
//定義並從xml文件中載入節點(根節點)
XElement rootNode = XElement.Load(xmlPath);
//定義一個新節點
XElement newNode = new XElement("User", new XAttribute("ID", "999999"),
new XElement("name", "Rose"),
new XElement("password", "456123"),
new XElement("description", "Hello, I'm from UK."));
//將此新節點添加到根節點下
rootNode.Add(newNode);
//Add 在 XContainer 的子內容的末尾添加內容。
//AddFirst 在 XContainer 的子內容的開頭添加內容。
//AddAfterSelf 在 XNode 後面添加內容。
//AddBeforeSelf 在 XNode 前面添加內容。
//保存對xml的更改操作
rootNode.Save(xmlPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static void DeleteXmlNodeInformation(string xmlPath)
{
try
{
//定義並從xml文件中載入節點(根節點)
XElement rootNode = XElement.Load(xmlPath);
//查詢語句: 獲取ID屬性值等於"999999"的所有User節點
IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("User")
where target.Attribute("ID").Value.Equals("999999")
select target;
//將獲得的節點集合中的每一個節點依次從它相應的父節點中刪除
targetNodes.Remove();
//保存對xml的更改操作
rootNode.Save(xmlPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
7.6 其它補充
(推薦方法)組合目錄與文件路徑,路徑末尾有無
\
效果一樣
Console.WriteLine(Path.Combine(@"X:\今日安排", "A..txt"));
Console.WriteLine(Path.Combine(@"X:\今日安排\", "A..txt"));
獲取項目根目錄方法集合
控制台應用程式
// 取得或設置當前工作目錄的完整限定路徑
Environment.CurrentDirectory
// 獲取基目錄,它由程式集衝突解決程式用來探測程式集
AppDomain.CurrentDomain.BaseDirectory
Web應用程式
// 獲取承載在當前應用程式域中的應用程式的應用程式目錄的物理驅動器路徑
HttpRuntime.AppDomainAppPath.ToString();
// 返回與Web伺服器上的指定的虛擬路徑相對的物理文件路徑
Server.MapPath("") / Server.MapPath("~/");
// 獲取伺服器上ASP.NET應用程式的虛擬應用程式根目錄
Request.ApplicationPath;
WinForm應用程式
// 獲取或設置當前工作目錄的完全限定路徑
Environment.CurrentDirectory.ToString();
// 獲取啟動了應用程式的可執行文件的路徑,不包括可執行文件的名稱
Application.StartupPath.ToString();
// 獲取應用程式的當前工作目錄
Directory.GetCurrentDirectory();
// 獲取基目錄,它由程式集衝突解決程式用來探測程式集
AppDomain.CurrentDomain.BaseDirectory;
// 獲取或設置包含該應用程式的目錄的名稱
AppDomain.CurrentDomain.SetupInformation.ApplicationBase;