1、IO操作相关的类
//静态类
-->File //操作文件,对文件整体进行操作,拷贝、删除、剪切等。
-->Directory //对目录(文件夹)进行操作。
-->Path //对文件或目录的路径进行操作。
//抽象类
-->Stream //流 下面是继承的子类
~FileStream //文件流
~StreamReader //快速读取文本文件
~streamWriter //快速写入文本文件
~MemoryStream //内存流
~NetworkStream //网络流
//实例类
-->DirectoryInfo //文件夹的“类”,用来描述一个文件夹对象(获取指定目录下的所有目录时返回一个DirectoryInfo数组)
-->FileInfo //文件类,用来描述一个文件对象。获取指定目录下的所有文件时,返回一个FileInfo数组。
其实IO操作就是操作一些API对文件进行读写,主要是对流的理解,下面分别对路径类(Path)、文件类(File)、目录类(Directory)和对应API进行使用操作。
1)Path类
//这里以文件C:\Users\liudengyan\Desktop\new.txt为例
//获得文件名(这里的文件指文件本身)
//1、获得包括扩展名的文件名(输出:new.txt)
Path.GetFileName(@"C:\Users\liudengyan\Desktop\new.txt");
//2、获取不包括扩展名的文件名(输出:new)
Path.GetFileNameWithoutExtension(@"C:\Users\liudengyan\Desktop\new.txt");
//获取扩展名(输出:.txt)
Path.GetExtension(@"C:\Users\liudengyan\Desktop\new.txt");
//获取文件所在文件夹路径(输出:C:\Users\liudengyan\Desktop)
Path.GetDirectoryName(@"C:\Users\liudengyan\Desktop\new.txt");
//获取文件夹的绝对路径(输出:C:\Users\liudengyan\Desktop\new.txt)
Path.GetFullPath();
//为了不重名 可以使用Guid==
其实上述Path类其实就是对一个已经知道文件进行查询操作,以便获取其路径和文件名称等文件信息,并不能去真正的去操作一个文件进行增删改查、复制、剪切、读写等操作,下面就是真正的运用这些操作来进行文件的读写等等功能。
2)File类
想进行文件的增删改查就必须使用另一个类:File类,这也是在System.IO中,是一个静态类
/// <summary>
/// 封装了对文件的操作
/// </summary>
class FileOperation
{
public void FO()
{
//判断文件是否存在
if (!File.Exists(""))
{
Directory.CreateDirectory("");
//在创建文件前要先创建文件夹
using (FileStream fileStream = File.Create(""))//创建文件
{
//二进制流文件写入
string name = "41684135416541";
byte[] bys = Encoding.Default.GetBytes(name);
fileStream.Write(bys, 0, bys.Length);
//将流中数据推入持久化
fileStream.Flush();
}
//第二种文件写入方法
using (FileStream fileStream = File.Create(""))//创建文件
{
//文件写入,数据会覆盖
StreamWriter sw = new StreamWriter(fileStream);
sw.WriteLine("163543");
sw.Flush();
}
using (StreamWriter sw = File.AppendText(""))//创建打开文件
{
sw.WriteLine("");
//写入文件的数据会追加,不会覆盖
sw.Flush();
}
using (StreamWriter sw = File.AppendText(""))//创建打开文件
{
byte[] bys = Encoding.Default.GetBytes("54351351");
sw.BaseStream.Write(bys, 0, bys.Length);
sw.Flush();
}
File.Copy("", "");
File.Move("", "");
//尽量不要使用删除,在web文件上传中断的时候。
File.Delete("");
// 文件的读取
foreach (var item in File.ReadAllLines(""))
{
Console.WriteLine(item);
}
string v = File.ReadAllText("");
byte[] v1 = File.ReadAllBytes("");
string v2 = Encoding.UTF8.GetString(v1);
// 当读大文件的时候,通常用分批读取的方式
using (FileStream stream = File.OpenRead(""))//分批读取
{
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);
}
}
}
}
3)Directory类
对文件夹进行创建、删除、移动等操作API
//文件夹操作
class DirectoryOperition
{
public void DO()
{
//查看当前文件路径是否有文件夹
if (!Directory.Exists(""))
{
//创建文件夹
DirectoryInfo directoryInfo = Directory.CreateDirectory("");
//移动文件夹
Directory.Move("", "");
//删除文件夹
Directory.Delete("");
}
//这里不要用实例化的方式检查文件夹是否存在,如果路径不存在,不会报错。
DirectoryInfo directoryInfo1 = new DirectoryInfo("");
}
}
4)Driver类
对磁盘进行操作,主要是查看信息。
//对硬盘文件信息获取
class DriverOpreation
{
// 获取所有硬盘信息(服务器的)
DriveInfo[] driveInfos = DriveInfo.GetDrives();
public void DO()
{
foreach (var item in driveInfos)
{
if (item.IsReady)
{
Console.WriteLine($"类型:{item.DriveType}-卷标:{item.VolumeLabel}-名称:{item.Name}-总空间:{item.TotalSize}-剩余空间:{item.AvailableFreeSpace}");
}
else
{
Console.WriteLine($"{item.Name} is not Ready");
}
}
}
}
2、序列化操作
1)二进制序列化
/// <summary>
/// 二进制序列化
/// </summary>
public void BinarySerialize()
{
// 使用二进制序列化对象(将对象转为二进制写入文件中)
string fileName = Path.Combine(@"D:\project\VS_pro\LearningProject\08_IOOpreation\Ser", "Binary.txt");
// 序列化
using (Stream stream = new FileStream(fileName,FileMode.Create,FileAccess.ReadWrite))
{
List<int> vs = new List<int>() {1,2,3,4};
BinaryFormatter binaryFormatter = new BinaryFormatter();//创建二进制序列化器
binaryFormatter.Serialize(stream, vs);//将对象序列化对象中
}
// 反序列化
using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
stream.Position = 0;//重置流的位置
List<int> vs = (List<int>)binaryFormatter.Deserialize(stream);
}
}
2)soap序列化
/// <summary>
/// soap序列化器
/// </summary>
public void SoapSerialize()
{
string fileName = Path.Combine(@"D:\project\VS_pro\LearningProject\08_IOOpreation\Ser", "Soap.txt");
// 序列化
using (Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
List<Student> vs = new List<Student>()
{
new Student{id=1,name="ls"},
new Student{id=2,name="ww"}
};
SoapFormatter soapFormatter = new SoapFormatter();
soapFormatter.Serialize(stream, vs.ToArray());
}
// 反序列化
using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
SoapFormatter soapFormatter = new SoapFormatter();
stream.Position = 0;
List<Student> vs = ((Student[])soapFormatter.Deserialize(stream)).ToList();
}
}
3)xml序列化
/// <summary>
/// xml序列化器
/// </summary>
public void XmlSerialize()
{
string fileName = Path.Combine(@"D:\project\VS_pro\LearningProject\08_IOOpreation\Ser", "Xml.xml");
// xml序列化
using (Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
List<Student> vs = new List<Student>()
{
new Student{id=1,name="ls"},
new Student{id=2,name="ww"}
};
XmlSerializer xml = new XmlSerializer(typeof(List<Student>));
xml.Serialize(stream, vs);
}
// xml反序列化
using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xml = new XmlSerializer(typeof(List<Student>));
stream.Position = 0;
List<Student> students = (List<Student>)xml.Deserialize(stream);
}
}
4)json序列化
这里使用了Newtonsoft这个包库,序列化性能较好。
/// <summary>
/// json序列化器
/// </summary>
public void JsonSerialize()
{
List<Student> vs = new List<Student>()
{
new Student{id=1,name="ls"},
new Student{id=2,name="ww"}
};
// 序列化
string x = JsonConvert.SerializeObject(vs);
// 反序列化
List<Student> v = (List<Student>)JsonConvert.DeserializeObject(x,typeof(List<Student>));
}
3、对配置文件读取
通常对配置文件读取需要用一个单独的工具类,字段为静态类读取,集中管理配置文件的读取。
// 用这样一个类来集中读取配置文件需要的字段,这样可以集中管理,以便更改,大多数的字段包括:图片路径,日志路径,数据库连接等路径信息与连接等需要的字符串配置。当然需要根据需求更改。
class PathManager
{
public static string ImagPath = ConfigurationManager.AppSettings["ImagePath"];
}
4、日志的读写
这里主要用Nlog,比较好用,因为log4不会用-__-!
配置文件:使用的时候注意,配置文件需要在启动项目的根目录配置。
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue"/>
<!--
注意:配置文件必须在运行项目的根目录中,不能在封装的Help中使用
-->
<targets>
<!-- 写入日志文件 -->
<!--fileName配置文件路径-->
<target name="error_file" xsi:type="File" maxArchiveFiles="30"
fileName="${basedir}/Logs/${shortdate}/error.txt"
layout="${longdate} | ${level:uppercase=false:padding=-5} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
<!-- 写入数据库 -->
<!--<target name="db" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="Database" dbProvider="mssql" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EFinance;Persist Security Info=True;User ID=sa;Password=123456;">
<commandText>
INSERT INTO Log(Timestamp,Level,Message,Action,Amount,StackTrace) VALUES(@time_stamp, @level, @message, @action, @amount, @stacktrace);
</commandText>
-->
<!-- database connection parameters -->
<!--
<parameter name="@time_stamp" layout="${date}" />
<parameter name="@level" layout="${level:uppercase=true}" />
<parameter name="@message" layout="${message}" />
<parameter name="@action" layout="${event-context:item=Action}" />
<parameter name="@amount" layout="${event-context:item=Amount}" />
<parameter name="@stacktrace" layout="${stacktrace}" />
</target>
</target>-->
<!--控制台输出-->
<target name="console" xsi:type="ColoredConsole"
layout="${date:format=HH\:mm\:ss}> ${message}"/>
<!--VS输出窗口-->
<target name="debugger" xsi:type="Debugger"
layout="${date:format=HH\:mm\:ss} | ${level:padding=-5} | ${message}" />
</targets>
<rules>
<!--TRACE<DEBUG<INFO<WARN<ERROR<FATAL-->
<!--向debug输出-->
<logger name="*" minlevel="Trace" writeTo="debugger" />
<!--向控制台输出-->
<logger name="*" writeTo="console" />
<!--INFO,WARN,ERROR,FATAL-->
<!--向数据库输出-->
<!--<logger name="*" minlevel="Info" writeTo="db" />-->
<!--ERROR,FATAL-->
<!--向文件输出error级别的日志消息-->
<logger name="*" minlevel="DEBUG" writeTo="error_file" />
</rules>
</nlog>
使用封装类:其中可以应对大多数场景需求,当然可以根据需求更改。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tools.Log
{
public class NLogHelp
{
//public static readonly ILog Log = LogManager.GetLogger("RollingLogFileAppender");
static NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
// log定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
//ALL 最低等级的,用于打开所有日志记录。
//DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
//INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,
//WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。
//ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
//FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
//TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。
//OFF 最高等级的,用于关闭所有日志记录。
//如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
#region DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
public static void debug(string write)
{
Log.Debug("日志记录:" + write);
}
public static void debug(string write, Exception ex)
{
Log.Debug("日志记录:" + write + "。错误记载:" + ex.ToString());
}
#endregion
#region INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,
/// <summary>
/// 1
/// </summary>
/// <param name="write"></param>
public static void Info(string write)
{
Log.Info("日志记录:" + write);
}
public static void Info(string write, Exception ex)
{
Log.Info("日志记录:" + write + "。错误记载:" + ex.ToString());
}
#endregion
#region WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。,可以使用这个级别。
public static void warn(string write)
{
Log.Warn("日志记录:" + write);
}
public static void warn(string write, Exception ex)
{
Log.Warn("日志记录:" + write + "。错误记载:" + ex.ToString());
}
#endregion
#region ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
public static void error(string write)
{
Log.Error("日志记录:" + write);
}
public static void error(string write, Exception ex)
{
Log.Error("日志记录:" + write + "。错误记载:" + ex.ToString());
}
#endregion
#region FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
public static void fatal(string write)
{
Log.Fatal("日志记录:" + write);
}
public static void fatal(string write, Exception ex)
{
Log.Fatal("日志记录:" + write + "。错误记载:" + ex.ToString());
}
#endregion
////定义输出的日志内容
//public static string logMessage(SysLogMsg logMessage)
//{
// StringBuilder strInfo = new StringBuilder();
// strInfo.Append("\r\n1. 错误: >> 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n");
// strInfo.Append("2. 类名: " + logMessage.Class + " \r\n");
// strInfo.Append("3. 内容: " + logMessage.Content + "\r\n");
// strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n");
// return strInfo.ToString();
//}
}
}