06.I/O操作
参考文章
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;
06.I/O操作的更多相关文章
- 数据分析06 /pandas高级操作相关案例:人口案例分析、2012美国大选献金项目数据分析
数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 目录 数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 1. ...
- 06、action操作开发实战
1.reduce: 2.collect: 3.count: 4.take: 5.saveAsTextFile: 6.countByKey: 7.foreach: package sparkcore.j ...
- 06 jumpserver登录操作
1.4.使用创建的 liuchang 用户登录jump server: 0.安全-MFA登陆验证说明: (1)简单的用户名密码就能登陆,太危险了,加一个MFA随机验证码这种黑科技限制一下. (2)Mu ...
- Python学习06——列表的操作(2)
笨办法学Python第39节 之前用的第三版的书,昨天发现内容不对,八块腹肌又给我下了第四版,这次的内容才对上.本节的代码如下: ten_things = "Apples Oranges C ...
- ms_sql 触发器记录表字段数据变化的日志 -针对一张表操作
create table sto (id int not null, -- 主键字段 de datetime -- 被跟踪的字段 constraint pk_sto primary key(id)) ...
- S3C2440上RTC时钟驱动开发实例讲解(转载)
嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...
- sql深入理解
我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我们还能保证下一段时间系统还能流畅的运行吗?我们还 ...
- SQL语言逻辑执行顺序
SQL语言逻辑执行顺序 2012-12-18 16:18:13 分类: 数据库开发技术 查询的逻辑执行顺序 FROM < left_table> ON < join_conditio ...
- vim常用指令
命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...
随机推荐
- 17、lnmp_php编译安装
17.1.FastCGI介绍: 1.什么是CGI: CGI的全称为"通用网关接口",为http服务器与其他机器上的程序服务通信交流的一种工具,CGI程序 必须运行在网络服务器上:传 ...
- 我用段子讲.NET之依赖注入其二
<我用段子讲.NET之依赖注入其二> "随着我们将业务代码抽象化成接口和实现两部分,这也使得对象生命周期的统一管理成为可能.这就引发了第二个问题,.NET Core中的依赖注入框 ...
- Go:go程序报错Cannot run program "C:\Users\dell\AppData\Local\Temp\___go_build_hello_go.exe" (in directory "…………"):该版本的 %1 与你运行的 Windows 版本不兼容。
问题截图 在go语言编译的时候,如果只是单单编译一个文件的话,package必须是main,意味着是可以单独编译的. 解决办法 修改为 package main 就可以 再次运行就可以啦. 文章转载至 ...
- 13 shell while循环与until循环
while 循环是 Shell 脚本中最简单的一种循环,当条件满足时,while 重复地执行一组语句,当条件不满足时,就退出 while 循环. unti 循环和 while 循环恰好相反,当判断条件 ...
- FastTunnel-开源内网穿透框架
FastTunnel - 打造人人都能搭建的内网穿透工具 FastTunnel是用.net core开发的一款跨平台内网穿透工具,它可以实现将内网服务暴露到公网供自己或任何人访问. 与其他穿透工具不同 ...
- Adaptive AUTOSAR 学习笔记 4 - 架构
本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本 AUTOSAR_EXP_PlatformDesign.pdf 缩写 AP:AUTOSAR Adap ...
- ESP32-使用ADC笔记
基于ESP-IDF4.1 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include "freertos/FreeRT ...
- C语言:监听键盘
所谓键盘监听,就是用户按下某个键时系统做出相应的处理,本章讲到的输入输出函数也是键盘监听函数的一种,例如 getchar().getche().getch() 等.下面的代码演示了 getche() ...
- MySQL全面瓦解26:代码评审中的MySQL(团队使用)
数据库对象命名规范 数据库对象 数据库对象是数据库的组成部分,常见的有以下几种: 表(Table ).索引(Index).视图(View).图表(Diagram).缺省值(Default).规则(Ru ...
- YARN调度器(Scheduler)详解
理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源.在Yarn中,负责给应用分配资 ...