参考文章
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(" 文件系统格式:" + driveInfo.DriveFormat);
Console.Write(" 驱动器类型:" + driveInfo.DriveType);
Console.Write(" 总空间(字节):" + driveInfo.TotalSize);
Console.Write(" 可用空间(字节):" + 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(" 目录");
string[] directories = Directory.GetDirectories(dir);
foreach (var directorie_item in directories)
{
Console.WriteLine(directorie_item);
}
// 获取目录下所有文件(当前目录下文件)
Console.WriteLine(" 文件");
string[] files = Directory.GetFiles(dir);
foreach (var file_item in files)
{
Console.WriteLine(file_item);
}
// 获取文件夹创建时间
Console.WriteLine(" 创建时间");
Console.WriteLine(Directory.GetCreationTime(dir));
// 获取文件夹根目录
Console.WriteLine(" 根目录");
Console.WriteLine(Directory.GetDirectoryRoot(dir));
Console.WriteLine(" 父目录");
Console.WriteLine(Directory.GetParent(@"X:今日安排").Name); // X:
Console.WriteLine(Directory.GetParent(@"X:今日安排").Name); // 今日安排
Console.WriteLine(" 移动并重命名目录(只限当前盘符内操作)");
Directory.Move(@"X:今日安排A", @"X:B"); // 移动并重命名目录
Directory.Move(@"X:B", @"X:C"); // 重命名目录
Console.WriteLine(" 删除目录(谨慎操作)");
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(" 目录下文件对象");
foreach (FileInfo file_item in directory.GetFiles())
{
Console.WriteLine(file_item.Name);
}
Console.WriteLine(" 目录下目录对象");
foreach (DirectoryInfo dir_item in directory.GetDirectories())
{
Console.WriteLine(dir_item.Name);
}
DirectoryInfo info = new DirectoryInfo(@"X:a");
info.MoveTo(@"x:");
}
}
}
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:";
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:";
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:";
string file = "1.txt";
string file_path = Path.Combine(dir,file);
Console.WriteLine(Path.GetDirectoryName(@"X:")); // X:
Console.WriteLine(Path.GetDirectoryName(@"X:")); // X:
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:", @"X:C"); // 重命名目录
DirectoryInfo info = new DirectoryInfo(@"X:a");
info.MoveTo(@"x:"); // 重命名
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;