using IOSerialize.IO;
using IOSerialize.Serialize;
using System;
using System.Collections.Generic;
using System.IO;
namespace IOSerialize
{
class Program
{
static void Main(string[] args)
{
#region 句柄的概念
//什么是句柄?
//Windows编程中,程序需要访问各种各样的资源,如文件、网络、窗口、图标和线程等。不同类型的资源被系统封装成不同的数据结构,当需要使用这些资源时,程序需要依据这些数据结构创建出不同的对象,当操作完毕并不再需要这些对象时,程序应当及时释放它们。在Windows中,应用程序不能直接在内存中操作这些对象,而是通过一系列公开的Windows API由对象管理器(Object Manager)来创建、访问、跟踪和销毁这些对象。当调用这些API创建对象时,它们并不直接返回指向对象的指针,而是会返回一个32位或64位的整数值,这个在进程或系统范围内唯一的整数值就是句柄(Handle)。随后程序再次访问对象,或者删除对象,都将句柄作为Windows API的参数来间接对这些对象进行操作。在这个过程中,句柄作为系统中对象的标识来使用。
//对象管理器是系统提供的用来统一管理所有Windows内部对象的系统组件。这里所说的内部对象,不同于高级编程语言如C#中“对象”的概念,而是由Windows内核或各个组件实现和使用的对象。这些对象及其结构,要么不对用户代码公开,要么只能使用句柄由封装好的Windows API进行操作。C#编程中,多数情况下,我们并不需要与这些Windows API打交道,这是因为.NET类库对这些API又进行了封装,但我们的托管程序仍然会间接创建出很多Windows内部对象,并持有它们的句柄。
//如上所说,句柄是一个32位或64位的整数值(取决于操作系统),所以在32位系统中,C#完全可以用int来表示一个句柄。但.NET提供了一个结构体System.IntPtr专门用来代表句柄或指针,在需要表示句柄,或者要在unsafe代码中使用指针时,应当使用IntPtr类型。
#endregion
//string logpath = Constant.LogPath;
//Console.WriteLine(logpath);
//var arr1 = new List<DirectoryInfo>();
//Recursion.GetAllDirectory("C:/Users/王晨/source/repos/IOSerialize/IOSerialize/bin/Debug/netcoreapp3.1", arr1);
#region 文件夹和文件操作
//MyIO.Show();
//MyIO.Show2();
#endregion
#region 序列化
Student student = new Student() { Id = 1, Name = "小王" };
//二进制序列化 要序列话的类必须加[Serializable]特性
var strBinarySer = SerializeHelper.BinarySerialize(student);
var objBinarySer = SerializeHelper.BinaryDeserialize<Student>();
//XML反序列化对数据要求不是很严格,有些标签确实也可以正常解析
var strXmlSer = SerializeHelper.XmlSerialize(student);
var objXmlSer = SerializeHelper.XmlDeserialize<Student>();
var strJsonSer = JsonSerializeHelper.ObjToJson(student);
var objJsonSer = JsonSerializeHelper.JsonToObj<Student>(strJsonSer);
var strJsonSer1 = JsonSerializeHelper.ToJson(student);
var objJsonSer1 = JsonSerializeHelper.ToObj<Student>(strJsonSer);
var strXml = XmlSerializeHelper.ToXml(student, "body");
var objXml = XmlSerializeHelper.ToObj<Student>(strXml);
#endregion
#region 图片操作
//生成二维码用 QRcode
//现在图片已经不用缩略图了,就是只有一张原图,前端请求时传入图片参数,按参数对图片缩放
//ImageHelper.Drawing();
//ImageHelper.VerificationCode();
//ImageHelper.CompressPercent(Path.Combine(Constant.ImagePath, "002.JPG"), Path.Combine(Constant.ImagePath, "003.JPG"), 1000, 1000);
ImageHelper.CompressBySize(Path.Combine(Constant.ImagePath, "001.JPG"), Path.Combine(Constant.ImagePath, "004.JPG"), 500, 500);
#endregion
}
}
[Serializable]
public class Student
{
public int Id { set; get; }
public string Name { set; get; }
}
}
读配置的简单工厂
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IOSerialize
{
/// <summary>
/// 读配置的简单工厂
/// </summary>
public class ReadConfigureFactory
{
public static string GetStr(string str)
{
try
{
var configuration = new ConfigurationBuilder().AddJsonFile("appSettings.json").Build();
return configuration[str];
}
catch (Exception e)
{
return null;
}
}
}
}
配置都写在这里
using System;
using System.Collections.Generic;
using System.Text;
namespace IOSerialize
{
/// <summary>
/// 推荐把项目所有配置信息都写在一个类,方便管理
/// </summary>
public class Constant
{
/// <summary>
/// 配置的日志地址
/// </summary>
public static string LogPath = ReadConfigureFactory.GetStr("LogPath");
/// <summary>
/// 日志移动地址
/// </summary>
public static string LogMovePath = ReadConfigureFactory.GetStr("LogMovePath");
public static string ImagePath = ReadConfigureFactory.GetStr("ImagePath");
}
}
IO
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace IOSerialize.IO
{
public class MyIO
{
///路径文件操作
public static void Show()
{
//判断文件夹是否存在推荐用静态类Directory,不要用实例化的DirectoryInfo,即使路径不存在,依然可以实例化DirectoryInfo
if (!Directory.Exists(Constant.LogPath))
{
Directory.CreateDirectory(Constant.LogPath);//增
Directory.Move(Constant.LogPath, Constant.LogMovePath);//移动并且重命名
Directory.Delete(Constant.LogMovePath);//删
Directory.CreateDirectory(Constant.LogPath);//增
Directory.CreateDirectory(Constant.LogMovePath);//增
}
//DirectoryInfo directoryInfo = new DirectoryInfo(Constant.LogPath);
//var isExist = directoryInfo.Exists;//虽然仍然可以判断,但是不推荐用DirectoryInfo
//创建文件,必须文件夹要提前存在
string FilePath = Path.Combine(Constant.LogPath, "log.txt");
string FileMovePath = Path.Combine(Constant.LogMovePath, "logmove.txt");
if (!File.Exists(FilePath))
{
#region 写入
using (FileStream fileStream = File.Create(FilePath))//创建文件并写入
{
string str = "000000000000000000";
byte[] byteArr = Encoding.Default.GetBytes(str);
fileStream.Write(byteArr, 0, byteArr.Length);
fileStream.Flush();
};
using (FileStream fileStream = File.Create(FilePath))//创建文件(会覆盖)并写入
{
StreamWriter streamWriter = new StreamWriter(fileStream);//写入流
streamWriter.WriteLine("111111111111111");
streamWriter.Flush();
};
using (StreamWriter streamWriter = File.AppendText(FilePath))//添加内容
{
streamWriter.WriteLine("22222222222222222");
streamWriter.Flush();
};
using (StreamWriter streamWriter = File.AppendText(FilePath))//添加内容
{
string str = "333333333333333333";
byte[] byteArr = Encoding.Default.GetBytes(str);
streamWriter.BaseStream.Write(byteArr, 0, byteArr.Length);
streamWriter.Flush();
};
#endregion
#region 读
// File.ReadAllLines 按行读成数组
foreach (string str in File.ReadAllLines(FilePath))
{
Console.WriteLine(str);
}
string txt = File.ReadAllText(FilePath);//读成一个字符串
Console.WriteLine(txt);
byte[] byteArr1 = File.ReadAllBytes(FilePath);//读成字节数组
string txt1 = Encoding.UTF8.GetString(byteArr1, 0, byteArr1.Length);
Console.WriteLine(txt1);
//分批读
using (FileStream fs = File.OpenRead(FilePath))
{
int len = 10;
int rst = 0;
do
{
byte[] bytes = new byte[10];
rst = fs.Read(bytes, 0, 5);
foreach (var item in bytes)
{
Console.WriteLine(item.ToString());
}
} while (len == rst);
};
#endregion
Console.WriteLine(Path.GetDirectoryName(FilePath));//返回目录名,需注意结尾是否带有反斜杠或者斜杠对结果是有影响的,如下
Console.WriteLine(Path.GetDirectoryName("C:/abc"));//结果返回C:\
Console.WriteLine(Path.GetDirectoryName("C:/abc/"));//结果返回C:\abc
Console.WriteLine(Path.GetRandomFileName());//返回随机文件名
Console.WriteLine(Path.GetFileNameWithoutExtension("C:/abc/123.txt"));//返回文件名不包含后缀
Console.WriteLine(Path.GetInvalidPathChars());//返回不能在路径中使用的字符
Console.WriteLine(Path.GetInvalidFileNameChars());//返回不能在文件中使用的字符
File.Create(FilePath).Close();//创建完先关闭文件流,否则文件占用不能move
File.Move(FilePath, FileMovePath);
File.Copy(FileMovePath, FilePath);
File.Delete(FileMovePath);
}
}
///硬盘信息
public static void Show2()
{
DriveInfo[] driveInfos = DriveInfo.GetDrives();
foreach (var drive in driveInfos)
{
if (drive.IsReady)
{
Console.WriteLine($"类型:{drive.DriveType},卷标:{drive.VolumeLabel},名称:{drive.Name},总空间:{drive.TotalSize},剩余空间:{drive.AvailableFreeSpace}");
}
else
Console.WriteLine($"类型:{drive.DriveType} is not ready");
}
}
/// <summary>
/// 写日志
/// </summary>
/// <param name="msg"></param>
public static void Log(string msg)
{
StreamWriter sw = null;
try
{
string LogPath = Path.Combine(Constant.LogPath, "Log.txt");
if (!Directory.Exists(Constant.LogPath))
{
Directory.CreateDirectory(Constant.LogPath);
}
sw = File.AppendText(LogPath);
sw.WriteLine($"{DateTime.Now}:{msg}");
}
catch (Exception e)
{
throw e;
}
finally
{
sw.Flush();
sw.Close();
sw.Dispose();
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace IOSerialize.IO
{
/// <summary>
/// 递归获取所有子文件夹
/// </summary>
//递归比较占用内存
//第一层调用未结束,调用第二层
//第二层未结束调用第三层---资源一直被占用
public class Recursion
{
public static void GetAllDirectory(string rootpath, List<DirectoryInfo> dirList)
{
if (!Directory.Exists(rootpath))
return;
dirList.Add(new DirectoryInfo(rootpath));
var childArr = Directory.GetDirectories(rootpath);
if (childArr != null || childArr.Length > 0)
{
foreach (var item in childArr)
{
GetAllDirectory(item, dirList);
}
}
}
}
}
图片
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace IOSerialize.IO
{
public class ImageHelper
{
//绘图原理:Bitmap就是画布,Graphics就是手,把pen或者Brush等绘图对象画在Bitmap这张画布上
/// <summary>
/// 画验证码
/// </summary>
public static void Drawing()
{
Bitmap bitmap = new Bitmap(500, 500);
Graphics graphics = Graphics.FromImage(bitmap);
Pen redPen = new Pen(Color.Red, 8);
graphics.Clear(Color.White);
//graphics.DrawLine(redPen, 50, 20, 500, 20);
graphics.DrawEllipse(Pens.Black, new Rectangle(0, 0, 200, 100));//画椭圆
graphics.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 60, 180);//画弧线
graphics.DrawLine(Pens.Black, 10, 10, 100, 100);//画直线
graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, 100, 200));//画矩形
graphics.DrawString("茜茜", new Font("微软雅黑", 12), new SolidBrush(Color.Red), new PointF(10, 10));//画字符串
if (!Directory.Exists(Constant.ImagePath))
Directory.CreateDirectory(Constant.ImagePath);
bitmap.Save(Path.Combine(Constant.ImagePath, "pic.jpg"), ImageFormat.Jpeg);
bitmap.Dispose();
graphics.Dispose();
}
/// <summary>
/// 画验证码
/// </summary>
public static void VerificationCode()
{
Bitmap bitmap = new Bitmap(300, 300);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.White);//先用颜色清理下画布,否则画布颜色不可控
graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, 100, 200));
graphics.FillRectangle(Brushes.Blue, new Rectangle(10, 10, 90, 190));
graphics.DrawArc(Pens.Yellow, new Rectangle(10, 10, 140, 40), 150, 90);
string[] strArr = new[] { "我", "们", "孝", "行", "白", "到", "国", "中", "来", "真" };
string str = "我撒都很符合法定";
var cArr = str.ToCharArray();
Random random = new Random();
int i;
for (int j = 0; j < 4; j++)
{
i = random.Next(10);
graphics.DrawString(strArr[i], new Font("微软雅黑", 15), Brushes.Red, new PointF(j * 30, 10));
}
bitmap.Save(Path.Combine(Constant.ImagePath, "verif.jpg"), ImageFormat.Jpeg);
bitmap.Dispose();
graphics.Dispose();
}
/// <summary>
/// 等比缩放 技术比较老
/// </summary>
/// <param name="oldPath"></param>
/// <param name="newPath"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
public static void CompressPercent(string oldPath, string newPath, int maxWidth, int maxHeight)
{
Image sourceImg = Image.FromFile(oldPath);
如果长宽都大于图片实际,直接返回原图
//if (maxWidth >= (double)sourceImg.Width && maxHeight >= (double)sourceImg.Height)
//{
// File.Copy(oldPath, newPath);
// return;
//}
double newW = Convert.ToDouble(maxWidth);
double newH = Convert.ToDouble(maxHeight);
double percentWidth = (double)sourceImg.Width > newW ? newW : (double)sourceImg.Width;//如果给定的宽度太大,那么宽度缩放比例等于100%
//double percentHeight = (double)sourceImg.Height > newH ? newH : (double)sourceImg.Height;
//如果宽度的缩放比例大于高度的缩放比例,那就应该按照高度比例来缩放
if ((double)sourceImg.Height * percentWidth / (double)sourceImg.Width > newH)
{
newW = newH / (double)sourceImg.Height * (double)sourceImg.Width;
}
else
{
newW = percentWidth;
newH = percentWidth / (double)sourceImg.Width * (double)sourceImg.Height;
}
Image bitmap = new Bitmap((int)newW, (int)newH);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.Clear(Color.Transparent);
graphics.DrawImage(sourceImg, new Rectangle(0, 0, (int)newW, (int)newH), new
Rectangle(0, 0, sourceImg.Width, sourceImg.Height), GraphicsUnit.Pixel);
sourceImg.Dispose();
graphics.Dispose();
bitmap.Save(newPath, ImageFormat.Jpeg);
bitmap.Dispose();
}
/// <summary>
/// 指定大小缩放
/// </summary>
/// <param name="oldPath"></param>
/// <param name="newPath"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
public static void CompressBySize(string oldPath, string newPath, int newWidth, int newHeight)
{
Image image = Image.FromFile(oldPath);
Bitmap bitmap = new Bitmap(newWidth, newHeight);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.Clear(Color.Transparent);
graphics.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight),new Rectangle(0,0,image.Width,image.Height),GraphicsUnit.Pixel);
image.Dispose();
bitmap.Save(newPath, ImageFormat.Jpeg);
bitmap.Dispose();
graphics.Dispose();
}
}
}
序列化
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
//Soap序列化要引用这个包,但是在core下报错
//using System.Runtime.Serialization.Formatters.Soap;
namespace IOSerialize.Serialize
{
public class SerializeHelper
{
/// <summary>
/// 二进制序列化 序列化的类上必须加[Serializable]特性才能被序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string BinarySerialize<T>(T obj)
{
string filepath = Path.Combine(Constant.LogPath, "Serialize.txt");
using (Stream stream = new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, obj);
stream.Position = 0;
StreamReader streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}
}
/// <summary>
/// 二进制反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T BinaryDeserialize<T>()
{
string filepath = Path.Combine(Constant.LogPath, "Serialize.txt");
using (Stream stream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
stream.Position = 0;//重置流位置
return (T)binaryFormatter.Deserialize(stream);
}
}
//找到的包只支持.netframework 不支持core
//public static void SoapSerialize(List<Student> obj)
//{
// string filepath = Path.Combine(Constant.LogPath, "Serialize.txt");
// using (Stream stream = new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite))
// {
// SoapFormatter sf = new SoapFormatter();
// sf.Serialize(stream, obj);//报错 Soap 不能序列化泛型对象
// sf.Serialize(stream, obj.ToArray());
// }
// using (Stream stream = new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite))
// {
// SoapFormatter sf = new SoapFormatter();
// stream.Position = 0;
// var rst = (Student[])sf.Deserialize(stream).ToList();
// }
//}
/// <summary>
/// XML序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string XmlSerialize<T>(T obj)
{
string filepath = Path.Combine(Constant.LogPath, "Serialize.txt");
using (Stream stream = new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite))
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(stream, obj);
stream.Position = 0;
StreamReader streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}
}
public static T XmlDeserialize<T>()
{
string filepath = Path.Combine(Constant.LogPath, "Serialize.txt");
using (Stream stream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xml = new XmlSerializer(typeof(T));
stream.Position = 0;//重置流位置
return (T)xml.Deserialize(stream);
}
}
}
}
Json序列化 两种
using Nancy.Json;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace IOSerialize.Serialize
{
public class JsonSerializeHelper
{
/// <summary>
/// JavaScriptSerializer
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string ObjToJson<T>(T obj)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(obj);
}
/// <summary>
/// JavaScriptSerializer
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="str"></param>
/// <returns></returns>
public static T JsonToObj<T>(string str)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Deserialize<T>(str);
}
/// <summary>
/// 一般用这个 性能高
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJson<T>(T obj)
{
return JsonConvert.SerializeObject(obj);
}
public static T ToObj<T>(string str)
{
return JsonConvert.DeserializeObject<T>(str);
}
}
}
自己尝试封个XML序列化方法
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Linq;
namespace IOSerialize.Serialize
{
public class XmlSerializeHelper
{
/// <summary>
/// 模仿封装一个Xml序列化方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <param name="FatherNodName"></param>
/// <returns></returns>
public static string ToXml<T>(T t, string FatherNodName)
{
XmlDocument xmldoc = new XmlDocument();
var ModelNode = xmldoc.CreateElement(FatherNodName);
xmldoc.AppendChild(ModelNode);
if (t != null)
{
foreach (var property in t.GetType().GetProperties())
{
var ChildNode = xmldoc.CreateElement(property.Name);
ChildNode.InnerText = property.GetValue(t, null)?.ToString();
ModelNode.AppendChild(ChildNode);
}
}
return xmldoc.OuterXml;
}
public static T ToObj<T>(string strXml, string FatherNodName = "body") where T : class, new()
{
if (string.IsNullOrEmpty(strXml))
return default(T);
XmlDocument xml = new XmlDocument();
xml.LoadXml(strXml);
T model = new T();
var ChildNodeList = xml.SelectSingleNode(FatherNodName).ChildNodes;
foreach (XmlNode childNode in ChildNodeList)
{
foreach (var property in model.GetType().GetProperties())
{
if (childNode.Name.Equals(property.Name) && !string.IsNullOrEmpty(childNode.InnerText))
{
property.SetValue(model, property.PropertyType == typeof(Guid)
? new Guid(childNode.InnerText)
: Convert.ChangeType(childNode.InnerText, property.PropertyType));
}
}
}
return model;
}
}
}