CSharpe中的IO+NPOI+序列化

  • CSharpe中的IO+NPOI+序列化已关闭评论
  • 22 次浏览
  • A+
所属分类:.NET技术
摘要

学习一下常见的文件、文件夹的操作。什么是IO流?
I:就是input O:就是output,故称:输入输出流


CSharpe中的IO+NPOI+序列化

文件文件夹操作

学习一下常见的文件、文件夹的操作。

什么是IO流?
I:就是input O:就是output,故称:输入输出流

将数据读入内存或者内存输出的过程。
常见的IO流操作,一般说的是[内存]与[磁盘]之间的输入输出。

作用
持久化数据,保证数据不再丢失!
文件操作流程:打开文件、读写数据、关闭文件。

常见的文件IO操作

  //这是操作文件、文件夹必备   if (!Directory.Exists(LogPath))//检测文件夹是否存在   {    }    DirectoryInfo directory = new DirectoryInfo(LogPath);//对文件夹、文件的描述对象、不存在不报错  注意exists属性    Console.WriteLine($"全名称:{directory.FullName} || 创建时间:{directory.CreationTime} || 最后写入时间:{directory.LastWriteTime}");    //路径拼接,得到一个完整的路径   string filePath = Path.Combine(LogPath, "info.txt");   if (!File.Exists(filePath))   {    }   FileInfo fileInfo = new FileInfo(filePath);   Console.WriteLine($"全名称:{fileInfo.FullName} || 创建时间:{fileInfo.CreationTime} || 最后写入时间:{fileInfo.LastWriteTime}");  

常见的文件夹操作

 {      if (!Directory.Exists(LogPath))      {          DirectoryInfo directoryInfo = Directory.CreateDirectory(LogPath);//一次性创建全部的子路径          Directory.Move(LogPath, LogMovePath);//移动  原文件夹就不在了          Directory.Delete(LogMovePath);//删除      }  }  

常见的文件读写 操作

 string fileName = Path.Combine(LogPath, "log.txt");  string fileNameCopy = Path.Combine(LogPath, "logCopy.txt");  string fileNameMove = Path.Combine(LogPath, "logMove.txt");  bool isExists = File.Exists(fileName);  if (!isExists)  {      Directory.CreateDirectory(LogPath);//创建了文件夹之后,才能创建里面的文件      using (FileStream fileStream = File.Create(fileName))//打开文件流 (创建文件并写入)      {          string name = "12345567778890";          byte[] bytes = Encoding.Default.GetBytes(name);          fileStream.Write(bytes, 0, bytes.Length);          fileStream.Flush();      }      using (FileStream fileStream = File.Create(fileName))//打开文件流 (创建文件并写入)      {          StreamWriter sw = new StreamWriter(fileStream);          sw.WriteLine("1234567890");          sw.Flush();      }      using (StreamWriter sw = File.AppendText(fileName))//流写入器(创建/打开文件并写入)      {          string msg = "大家好,我是Richard老师!!";          sw.WriteLine(msg);          sw.Flush();      }      using (StreamWriter sw = File.AppendText(fileName))//流写入器(创建/打开文件并写入)      {          string name = "0987654321";          byte[] bytes = Encoding.Default.GetBytes(name);          sw.BaseStream.Write(bytes, 0, bytes.Length);          sw.Flush();      }       //文件的读取       foreach (string result in File.ReadAllLines(fileName))//读取文件中所有的行信息      {          Console.WriteLine(result);      }      string sResult = File.ReadAllText(fileName);      Byte[] byteContent = File.ReadAllBytes(fileName);      string sResultByte = System.Text.Encoding.UTF8.GetString(byteContent);       //建议大家不要去做多线程读取,即使要多线程读取,也要加锁,加锁----反多线程;      //你们有没有遇到过大文件Txt---10G      using (FileStream stream = File.OpenRead(fileName))//分批读取      {          int length = 5;          int result = 0;          do          {              byte[] bytes = new byte[length];              result = stream.Read(bytes, 0, 5);              for (int i = 0; i < result; i++)              {                  Console.WriteLine(bytes[i].ToString());              }          }          while (length == result);      }       File.Copy(fileName, fileNameCopy);      File.Move(fileName, fileNameMove);      File.Delete(fileNameCopy);      File.Delete(fileNameMove);//尽量不要delete  } 

常见的盘符操作

{//DriveInfo     DriveInfo[] drives = DriveInfo.GetDrives();//获取当前计算机所有盘符      foreach (DriveInfo drive in drives)     {         if (drive.IsReady)             Console.WriteLine($"类型:{drive.DriveType} 卷标:{drive.VolumeLabel} 名称:{drive.Name} 总空间:{drive.TotalSize} 剩余空间:{drive.TotalFreeSpace}");         else             Console.WriteLine("类型:{drive.DriveType}  is not ready");     } } {     Console.WriteLine(Path.GetDirectoryName(LogPath));  //返回目录名,需要注意路径末尾是否有反斜杠对结果是有影响的     Console.WriteLine(Path.GetDirectoryName(@"d:\abc")); //将返回 d:     Console.WriteLine(Path.GetDirectoryName(@"d:\abc"));// 将返回 d:abc     Console.WriteLine(Path.GetRandomFileName());//将返回随机的文件名     Console.WriteLine(Path.GetFileNameWithoutExtension("d:\abc.txt"));// 将返回abc     Console.WriteLine(Path.GetInvalidPathChars());// 将返回禁止在路径中使用的字符     Console.WriteLine(Path.GetInvalidFileNameChars());//将返回禁止在文件名中使用的字符      Console.WriteLine(Path.Combine(LogPath, "log.txt"));//合并两个路径 } 

递归获取所有的文件

 public static List<DirectoryInfo> GetAllDirectory(string rootPath)  {      if (!Directory.Exists(rootPath))            return new List<DirectoryInfo>();       List<DirectoryInfo> directoryList = new List<DirectoryInfo>();//容器      DirectoryInfo directory = new DirectoryInfo(rootPath);//root文件夹      directoryList.Add(directory);       return GetChild(directoryList, directory);   }   /// <summary>  /// 完成 文件夹--子目录--放入集合  /// </summary>  /// <param name="directoryList"></param>  /// <param name="directoryCurrent"></param>  /// <returns></returns>  private static List<DirectoryInfo> GetChild(List<DirectoryInfo> directoryList, DirectoryInfo directoryCurrent)  {      var childArray = directoryCurrent.GetDirectories();      if (childArray != null && childArray.Length > 0)      {          directoryList.AddRange(childArray);          foreach (var child in childArray)          {               GetChild(directoryList, child);          }      }      return directoryList;  } 

NPOI操作Excel

NPOI背景

Apache Poi是一种流行的API,它允许程序员使用java程序创建,修改和显示MS Office文件。这由Apche软件基金会开发使用java分布式设计或修改该Microsoft Office文件的开源库,它包含类和方法对用户输入数据或文件到Ms Office文档进行解码;

NPOI是什么呢?顾名思义就是POI的.NET版本,可以通过.NET来操作Office文档。

使用NPOI

名词解释

整个Excel:工作簿
Sheet页:页签,一个工作簿客户可以包含多个Sheet页。
表格:对应一个Sheet
行、列、单元格

C#中的常规操作:
导出一个Excel:其实就是要生成一个Excel文件,Excel文件对应的文件流。
导入一个Excel:读取一个文件,读取文件流,需要从文件流中读取我们需要的各种数据,解析Excel的数据。

创建一个Excel文件:

 public class ExcelOperationHelper  {      public static IWorkbook CreateExcelWorkbook(string filePath)      {          IWorkbook workbook = null;          if (filePath.EndsWith(".xls"))          {              workbook = new NPOI.HSSF.UserModel.HSSFWorkbook();          }          else if (filePath.EndsWith(".xlsx"))          {              workbook = new NPOI.XSSF.UserModel.XSSFWorkbook();          }          ISheet sheet = workbook.CreateSheet("Sheet1");          {              IRow row = sheet.CreateRow(0);              ICell cell = row.CreateCell(0);              cell.SetCellValue("学生姓名");              ICell cell1 = row.CreateCell(1);              cell1.SetCellValue("数学成绩");              ICell cell2 = row.CreateCell(2);              cell2.SetCellValue("语文成绩");          }           {              IRow row = sheet.CreateRow(1);              ICell cell = row.CreateCell(0);              cell.SetCellValue("JJ鹏");              ICell cell1 = row.CreateCell(1);              cell1.SetCellValue("100");              ICell cell2 = row.CreateCell(2);              cell2.SetCellValue("150");          }           return workbook;      }  }  

Programs.cs

     IWorkbook work = ExcelOperationHelper.CreateExcelWorkbook(path);     using (FileStream file=new FileStream(path,FileMode.Create))     {         work.Write(file);          file.Close();     } 

数据实体设置

需要考虑的问题

  1. 数据写道工作簿中的哪个sheet页中
  2. 生成的Excel---考虑表头放在哪个位置
  3. 直接集合中的某一个对象来直接生成---如果对象是一个实体---实体中有多少个属性;就表示多少个列;
    最终的目标:做到业务系统不需要考虑其他,只需要按照规则来给定数据即可,就可以生成Excel出来。

数据实体

public class ExcelDataResource {     /// <summary>     /// 保存到Sheet的名称     /// </summary>     public string SheetName { get; set; }     /// <summary>     /// 标题所在行     /// </summary>     public int TitleIndex { get; set; }     /// <summary>     /// 每一个sheet的数据     /// </summary>     public List<object> SheetDataResource { get; set; } } 

添加一个新的特性

 public class TitleAttribute:Attribute  {      public string Title { get; set; }      public TitleAttribute(string title)      {          Title = title;      }  } 

用户的信息

    public class UserInfo     {         [Title("用户ID")]         public int UserId { get; set; }         [Title("用户名称")]         public string UserName { get; set; }         [Title("用户年龄")]         public int UserAge { get; set; }         [Title("用户类型")]         public string UserType { get; set; }         [Title("描述")]         public string Description { get; set; }     } } 

根据固定格式生成IWorkBook

生成我们需要的excel的数据

static List<ExcelDataResource> GetExcelDataList() {     List<object> objlist = new List<object>();     for (int i = 0; i < 100; i++)     {         objlist.Add(new UserInfo()         {             UserId = i + 1,             UserName = $"名称-{i}",             UserAge = i + i + 1,             UserType = i + 1,             Description = $"描述_描述_描述_描述_描述_描述_描述_描述_描述_描述_{i}"         });     }      List<object> Classobjlist = new List<object>();     for (int i = 0; i < 200; i++)     {         Classobjlist.Add(new ClassInfo()         {             UserId = i + 1,             UserName = $"名称-{i}",             Age = i + i + 1,             UserType = i + 1,             Description1 = $"描述_描述_描述_描述_描述_描述_描述_描述_描述_描述_{i}",             Description2 = $"描述_描述_描述_描述_描述_描述_描述_描述_描述_描述_{i}",             Description3 = $"描述_描述_描述_描述_描述_描述_描述_描述_描述_描述_{i}",             Description4 = $"描述_描述_描述_描述_描述_描述_描述_描述_描述_描述_{i}"         });     }     return new List<ExcelDataResource>()                     {                          new ExcelDataResource(){                                 SheetName="页签1",                                 TitleIndex=1,                                 SheetDataResource=objlist                          },                          new ExcelDataResource(){                                 SheetName="页签2",                                 TitleIndex=1,                                 SheetDataResource=Classobjlist                          }                     }; } 

生成DataToXSSFWorkbook工作簿

public static IWorkbook DataToXSSFWorkbook(List<ExcelDataResource> dataResources) {     XSSFWorkbook _Workbook = new XSSFWorkbook();     if (dataResources == null && dataResources.Count == 0)     {         return _Workbook;     }     foreach (var sheetResource in dataResources)     {         if (sheetResource.SheetDataResource != null && sheetResource.SheetDataResource.Count == 0)         {             break;         }         ISheet sheet = _Workbook.CreateSheet(sheetResource.SheetName);         object obj = sheetResource.SheetDataResource[0];          Type type = obj.GetType();         List<PropertyInfo> propList = type.GetProperties().Where(c => c.IsDefined(typeof(TitleAttribute), true)).ToList();          IRow titleRow = sheet.CreateRow(0);          ICellStyle style = _Workbook.CreateCellStyle();         style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;         style.FillPattern = FillPattern.SolidForeground;         style.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Automatic.Index;          style.Alignment = HorizontalAlignment.CenterSelection;         style.VerticalAlignment = VerticalAlignment.Center;         titleRow.Height = 100 * 4;          for (int i = 0; i < propList.Count(); i++)         {             TitleAttribute propertyAttribute = propList[i].GetCustomAttribute<TitleAttribute>();             ICell cell = titleRow.CreateCell(i);             cell.SetCellValue(propertyAttribute.Title);             cell.CellStyle = style;         }          for (int i = 0; i < sheetResource.SheetDataResource.Count(); i++)         {             IRow row = sheet.CreateRow(i + 1);             object objInstance = sheetResource.SheetDataResource[i];             for (int j = 0; j < propList.Count; j++)             {                 ICell cell = row.CreateCell(j);                 cell.SetCellValue(propList[j].GetValue(objInstance).ToString());             }         }     }     return _Workbook; } 

对应的使用的例子为:

 List<ExcelDataResource> excelDataList = GetExcelDataList();  IWorkbook workbook1 = ExcelOperationHelper.DataToXSSFWorkbook(excelDataList);  using (FileStream file=new FileStream(path,FileMode.Create))  {      workbook1.Write(file);       file.Close();  } 

开发中的各种应用场景

  1. 写入Response二进制流
 public void ImportExcelFileOnWriteResponse(int id)  {       ///设置ContentType      HttpContext.Response.ContentType = "application/vnd.ms-excel";      ///生成文件名      string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffffff");      ///设置Excel文件名      HttpContext.Response.Headers.Add("Content-Disposition", $"attachment;filename={fileName}.xls");       // 获取导出Excel需要的数据源      List<ExcelDataResource> excelDataResources = GetExcelSheetData(id);      byte[] bt = ExcelOperationHelper.ToExcelByteArray(excelDataResources);      HttpContext.Response.BodyWriter.WriteAsync(bt);   } 
  1. 调用框架的file方法
 public IActionResult ImportExcelFileOnFileMethod(int id)  {       List<ExcelDataResource> excelDataResources = GetExcelSheetData(id);      byte[] bt = ExcelOperationHelper.ToExcelByteArray(excelDataResources);      string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffffff");      return File(bt, "application/vnd.ms-excel", $"{fileName}.xls");  } 
  1. 扩展IActionResult方法 ExcelResult方法
  public IActionResult ImportExcelFileOnActionResultExtend(int id)   {       // 获取导出Excel需要的数据源       List<ExcelDataResource> list = GetExcelSheetData(id);       return new ExcelResult(list);  //调用IActionResult的扩展返回Excel   } 

对应IActionResult的实现

 public class ExcelResult : IActionResult  {      private string _ExcelName;      private List<ExcelDataResource> _ExcelDataResources;       /// <summary>      /// 如果没有时间就默认以当前时间为文件名称      /// </summary>      /// <param name="excelDataResources"></param>      public ExcelResult(List<ExcelDataResource> excelDataResources) : this(DateTime.Now.ToString("yyyyMMddHHmmssffffff"), excelDataResources)      {      }       /// <summary>      /// 构造函数      /// </summary>      /// <param name="excelName">文件名称</param>      /// <param name="excelDataResources">数据源</param>      public ExcelResult(string excelName, List<ExcelDataResource> excelDataResources)      {          this._ExcelName = excelName;          this._ExcelDataResources = excelDataResources;      }       public Task ExecuteResultAsync(ActionContext context)      {          return Task.Run(() =>          {                              context.HttpContext.Response.ContentType = "application/vnd.ms-excel";              context.HttpContext.Response.Headers.Add("Content-Disposition", $"attachment;filename={_ExcelName}.xls");               byte[] bt = ExcelOperationHelper.ToExcelByteArray(_ExcelDataResources);              context.HttpContext.Response.BodyWriter.WriteAsync(bt);           });      }  } 

excel导入

本质:目的是把Excel文件提交到服务器,然后把Excel文件中的数据信息读取出来,然后要处理的就是数据信息,
Excel文件的解析

  1. Excel文件---文件流 fileStream MemoryStream Byte[]----->IWorkbook,如果得到了一个IWorkbook就可以使用Npoi来进行解析.

转换为DataTable

  public static List<DataTable> ToExcelDateTable(IWorkbook hSSFWorkbook)   {       List<DataTable> datatableList = new List<DataTable>();       for (int sheetIndex = 0; sheetIndex < hSSFWorkbook.NumberOfSheets; sheetIndex++)       {           ISheet sheet = hSSFWorkbook.GetSheetAt(sheetIndex);           //获取表头 FirstRowNum 第一行索引 0           IRow header = sheet.GetRow(sheet.FirstRowNum);//获取第一行           if (header == null)           {               break;           }           int startRow = 0;//数据的第一行索引            DataTable dtNpoi = new DataTable();           startRow = sheet.FirstRowNum + 1;           for (int i = header.FirstCellNum; i < header.LastCellNum; i++)           {               ICell cell = header.GetCell(i);               if (cell != null)               {                   string cellValue = $"Column{i + 1}_{cell.ToString()}";                   if (cellValue != null)                   {                       DataColumn col = new DataColumn(cellValue);                       dtNpoi.Columns.Add(col);                   }                   else                   {                       DataColumn col = new DataColumn();                       dtNpoi.Columns.Add(col);                   }               }            }           //数据    LastRowNum 最后一行的索引 如第九行---索引 8           for (int i = startRow; i <= sheet.LastRowNum; i++)           {               IRow row = sheet.GetRow(i);//获取第i行               if (row == null)               {                   continue;               }               DataRow dr = dtNpoi.NewRow();               //遍历每行的单元格               for (int j = row.FirstCellNum; j < row.LastCellNum; j++)               {                   if (row.GetCell(j) != null)                       dr[j] = row.GetCell(j).ToString();               }               dtNpoi.Rows.Add(dr);           }            datatableList.Add(dtNpoi);       }       return datatableList;   } 

Excel文件导入的多种场景demo

 public IActionResult ImportExcelOnFormSubmit()  {      //获取上传的Excel文件      IFormFile file = Request.Form.Files["file"];      if (file != null && file.Length > 0)      {          string suffixName = Path.GetExtension(file.FileName).ToLower();          if (suffixName != ".xls" && suffixName != ".xlsx")          {              return Content("请导入文件为Excel格式");          }          XSSFWorkbook hSSFWorkbook = new XSSFWorkbook(file.OpenReadStream());          List<DataTable> datatableList = ExcelOperationHelper.ToExcelDateTable(hSSFWorkbook);          ViewBag.Info = Newtonsoft.Json.JsonConvert.SerializeObject(datatableList);      }      else      {          ViewBag.Info = "请上传文件";      }      return View();  } 

序列化和反序列化

序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或永久性存储区。以后,可以通过存储区中读取或反序列化对象的状态,重新创建该对象。

序列化之前:对象

序列化之后:把一个对象转换成另外一种形式来存储。

原始数据:

  public class DataFactory   {       /// <summary>       /// 初始化数据的       /// </summary>       /// <returns></returns>       public static List<Programmer> BuildProgrammerList()       {           #region data prepare           List<Programmer> list = new List<Programmer>();           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "SoWhat",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "day",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "领悟",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "Sam",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "AlphaGo",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "折腾",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "Me860",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "打兔子的猎人",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "Nine",               Sex = "女"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "望",               Sex = "女"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "微笑刺客",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "waltz",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "爱在昨天",               Sex = "男"           });           list.Add(new Programmer()           {               Id = 1,               Description = "Richard老师的学员",               Name = "waltz",               Sex = "男"           });           #endregion            return list;       }   }     [Serializable]  //必须添加序列化特性   public class Person   {       [NonSerialized]       public int Id = 1;        public string Name { get; set; }        public string Sex { get; set; }   }    [Serializable]  //必须添加序列化特性   public class Programmer : Person   {       private string Language { get; set; }//编程语言       public string Description { get; set; }   } 

XML序列化

  public class XmlHelper   {       /// <summary>       /// XmlSerializer序列化实体为字符串       /// </summary>       /// <typeparam name="T"></typeparam>       /// <param name="t"></param>       /// <returns></returns>       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;       }        /// <summary>       /// 字符串序列化成XML       /// </summary>       /// <typeparam name="T"></typeparam>       /// <param name="content"></param>       /// <returns></returns>       public static T ToObject<T>(string content) where T : new()       {           using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(content)))           {               XmlSerializer xmlFormat = new XmlSerializer(typeof(T));               return (T)xmlFormat.Deserialize(stream);           }       }        /// <summary>       /// 文件反序列化成实体       /// </summary>       /// <typeparam name="T"></typeparam>       /// <param name="fileName"></param>       /// <returns></returns>       public static T FileToObject<T>(string fileName) where T : new()       {            fileName = Path.Combine(Constant.basePath, "File", @"Student.xml");           using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))           {               XmlSerializer xmlFormat = new XmlSerializer(typeof(T));               return (T)xmlFormat.Deserialize(fStream);           }       }   } 

jSON序列化

 public class JsonHelper  {      #region Json      /// <summary>      /// JavaScriptSerializer      /// </summary>      /// <typeparam name="T"></typeparam>      /// <param name="obj"></param>      /// <returns></returns>      public static string ObjectToString<T>(T obj)      {          JavaScriptSerializer jss = new JavaScriptSerializer();          return jss.Serialize(obj);      }       /// <summary>      /// JavaScriptSerializer      /// </summary>      /// <typeparam name="T"></typeparam>      /// <param name="content"></param>      /// <returns></returns>      public static T StringToObject<T>(string content)      {          JavaScriptSerializer jss = new JavaScriptSerializer();          return jss.Deserialize<T>(content);      }       /// <summary>      /// JsonConvert.SerializeObject      /// </summary>      /// <typeparam name="T"></typeparam>      /// <param name="obj"></param>      /// <returns></returns>      public static string ToJson<T>(T obj)      {          return JsonConvert.SerializeObject(obj);      }       /// <summary>      /// JsonConvert.DeserializeObject      /// </summary>      /// <typeparam name="T"></typeparam>      /// <param name="content"></param>      /// <returns></returns>      public static T ToObject<T>(string content)      {          try          {              return JsonConvert.DeserializeObject<T>(content);          }          catch (Exception)          {               throw;          }        }      #endregion Json  } 

调用的实例

 /// <summary>  /// XML序列化器  /// </summary>  public static void XmlSerialize()  {      //使用XML序列化对象       string fileName = Path.Combine(Constant.basePath, "File", "Student.xml"); ;//文件名称与路径       List<Programmer> pList = DataFactory.BuildProgrammerList();       using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))      {           XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>));//创建XML序列化器,需要指定对象的类型          xmlFormat.Serialize(fStream, pList);      }        List<Programmer> resultList = null;      using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))      {          XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>));//创建XML序列化器,需要指定对象的类型          //使用XML反序列化对象          fStream.Position = 0;//重置流位置          resultList = pList = (List<Programmer>)xmlFormat.Deserialize(fStream);      }  }    /// <summary>  /// json也可以的  /// </summary>  public static void Json()  {      List<Programmer> pList = DataFactory.BuildProgrammerList();      string result = JsonHelper.ObjectToString<List<Programmer>>(pList);      List<Programmer> pList1 = JsonHelper.StringToObject<List<Programmer>>(result);  }