zoukankan      html  css  js  c++  java
  • 06.文件(流)IO

    参考文章

    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类,FileFileInfo类位于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为静态函数,一个是实例类,一个是公用的静态类

    两者是为不同的使用场景准备的,directoryinfodirectory的函数内部有一些是相同的处理函数,而且某些directoryinfo的函数甚至就直接调用了directory函数;如果多次使用某个对象一般使用前者(directoryinfo),如果仅执行某一个操作则使用后者(directory)提供的静态方法效率更高一些

    Directory类获取父目录,使用时需要注意,目录之间以为分界点

    Console.WriteLine(Directory.GetParent(@"X:今日安排").Name);    // X:
    Console.WriteLine(Directory.GetParent(@"X:今日安排").Name);   // 今日安排
    

    DirectoryDirectoryInfo移动目录,移动操作只能在同一盘符内(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;
    
    到达胜利之前无法回头!
  • 相关阅读:
    SGU 205. Quantization Problem
    BZOJ1009: [HNOI2008]GT考试
    SGU 204. Little Jumper
    Spring Aspect 获取请求参数
    springboot 是用拦截器Interceptor获取请求的控制器和请求的方法名
    spring boot Filter过滤器的简单使用
    Java 使用Query动态拼接SQl
    java 传入list集合 返回树形菜单,for循环遍历
    spring data jpa 的简单使用
    vue项目引入element
  • 原文地址:https://www.cnblogs.com/weiyongguang/p/15141585.html
Copyright © 2011-2022 走看看