• C#要点补充


     1字符串与时间的互转

    DateTime.TryParse将空字符串、为null或格式不正确,则转换为的DateTime所代表的值为:0001/1/1 0:00:00,此为DateTime.MinValue的值。

    使用public static DateTime ParseExact(string s, string format, IFormatProvider provider);实例方法转换时间,可以指定转换的格式。其中format为输入字符s的格式。若指定的格式与输入字符格式不一样,会抛异常

    例如:

    //dateTime ="2017-11-18 17:25:53";会抛异常,这种类型对应格式为:yyyy-MM-dd HH:mm:ss

    string dateTime = "20171118172553";

    IFormatProvider yyyymmddFormat = new CultureInfo(String.Empty, false);

    DateTime time = DateTime.ParseExact(dateTime, "yyyyMMddHHmmss", yyyymmddFormat);

    2比较时间先后

     使用DateTimepublic int CompareTo(DateTime value);实例方法。

    示例:

    string dateTime = "2017-11-28 12:57:30";

                DateTime dt;

                DateTime.TryParse(dateTime, out dt);

                int cr = dt.CompareTo(DateTime.Now);

    如果cr大于0,dt时间晚于(当前时间)DateTime.Now,即时间的整数值大于DateTime.Now的整数值。

    如果cr等于0,dt时间等于(当前时间)DateTime.Now,即时间的整数值等于DateTime.Now的整数值。

    如果cr小于0,dt时间早于(当前时间)DateTime.Now,即时间的整数值小于DateTime.Now的整数值。

     

    3 StreamWriter

    将文件所在的目录传给StreamWriter的构造函数,而不是传递文件的全路径,那么会抛出如下的异常,看上去似乎是对文件目录没有访问权限,其实是错将文件目录传递给了StreamWriter构造函数。

    4Sream中的数据写入文件

    错误的做法一:

    获取流的长度然后转型为int,容易造成数据截断,导致未能读取流的全部内容。

            //读取
            long length = 0;
                using (Stream fs = new FileStream("D:\命令行安装MySQL.docx", FileMode.Open))
                {
                    length = fs.Length;
                }
                byte[] bytes = new byte[length];
    
                using (Stream fs = new FileStream("D:\命令行安装MySQL.docx", FileMode.Open))
                {
                    int countIn = fs.Read(bytes, 0, (int)length);
                }
            //写入
                using (Stream fs = new FileStream("D:\命令行安装MySQLnew.docx", FileMode.OpenOrCreate))
                {
                    fs.Write(bytes, 0, (int)length);
                }

    错误做法二:

    貌似不会发生错误类型一那样的情况,但还是会出现数据截断的现象。调用FileStreamRead实例方法:Read(byte[] buffer, int offset, int count)offset这个参数的类型是int型,这里将numBytesRead 转型为int,一旦这个偏移量超过这个值,那么读取的数据有一部分就是重复的。

            /读取
             using (Stream fs = new FileStream("D:\命令行安装MySQL.docx", FileMode.Open))
                {
                    int c = 10000;
                    long numBytesRead = 0;
                    long numBytesToRead = fs.Length;
                    while (numBytesToRead>0)
                    {
                        if (fs.Length - numBytesRead <= c)
                        {
                            c = (int)(fs.Length - numBytesRead);
                        }
                        int n = fs.Read(bytes, (int)numBytesRead, c);
                        numBytesRead += n;
                        numBytesToRead -= n;
                    }
                }
            //写入
                using (Stream fs = new FileStream("D:\命令行安装MySQLnew.docx", FileMode.OpenOrCreate))
                {
                    fs.Write(bytes, 0, (int)length);
                }

    正确的做法一:

    确保上述错误做法中的源数据长度不超过int32的最大值。此外也可使用下面的方法,但同样要保证源数据长度不超过int32的最大值:

            //读取
            using (Stream fs = new FileStream("D:\命令行安装MySQL.docx", FileMode.Open))
                {                
                    int c = 10000;
                    long position = 0;
                    while (true)
                    {
                        position = fs.Seek(position, SeekOrigin.Begin);
                        if (position == fs.Length)
                        {
                            break;
                        }
    
                        if (position + c > fs.Length)
                        {
                            c = (int)(fs.Length - position);
                        }
                        int n = fs.Read(bytes, (int)position, c);
                        position += n;
                    }
                }
             //写入
                using (Stream fs = new FileStream("D:\命令行安装MySQLnew.docx", FileMode.OpenOrCreate))
                {
                    fs.Write(bytes, 0, (int)length);
                }

    正确的做法二:

    使用CopyTo(Stream destination)

    CopyTo(Stream destination, int bufferSize)

    使用第一个方法默认缓冲区大小为4096,现在看下源码片段:

         public void CopyTo(Stream destination)
            {
                ......
     
                InternalCopyTo(destination, _DefaultCopyBufferSize);
            }

    CopyTo方法中调用了InternalCopyTo方法,来看下InternalCopyTo方法的源码片段:

          private void InternalCopyTo(Stream destination, int bufferSize)
            {
                ......
                
                byte[] buffer = new byte[bufferSize];
                int read;
                while ((read = Read(buffer, 0, buffer.Length)) != 0)
                    destination.Write(buffer, 0, read);
            }

    InternalCopyTo方法内部调用了Read方法,下面来看一下Read方法源码片段:

    然而在Stream这个类中并没有Read方法的具体实现,只有一个抽象方法:

    public abstract int Read([In, Out] byte[] buffer, int offset, int count);

    到这里已经可以看出CopyTo方法中的参数bufferSize的作用了,即设置内存缓冲区的大小,每次从流中读取长度为bufferSize的数据,放入缓冲区,然后写入目标流,重复这个过程直到所有的流都拷贝完成。那么在内存允许的范围内,bufferSize设置的越大效率越高。

            using (Stream fs = new FileStream("D:\命令行安装MySQL.docx", FileMode.Open))
            {
                 using(Stream fss = new FileStream("D:\命令行安装MySQLnew.docx", FileMode.OpenOrCreate))
                 {
                     fs.CopyTo(fss);
                 }
            }

    5文件读写效率与对象频繁开关的影响

    写文件方式一:

          public static void W()
             {
                 for (int i = 0; i < 1000;i++ )
                 {
                     string s = "sdfrgyjefgyhjdsfdfgfghgew"+i;
                     using (StreamWriter sw = new StreamWriter(@"D:g.txt", true))
                     {
                         sw.Write(s);
                     }
                 }
             }

    方式二:

          public static void WT()
             {
                 using (StreamWriter sw = new StreamWriter(@"D:gT.txt", true))
                 {
                     for (int i = 0; i < 1000; i++)
                     {
                         string s = "sdfrgyjefgyhjdsfdfgfghgew" + i;
                         sw.Write(s);
                     }
                 }
             }

    分析:

    方式一每写一次文件,开关一次StreamWriter对象,而方式二将所有的字符串都写入文件后才关闭StreamWriter实例。统计数据如下:

    循环次数

    方式一

    方式二

    100万

    21861ms

    260ms

    1000

    231ms

    13ms

  • 相关阅读:
    MongoDB 连接
    MongoDB 概念解析
    Linux平台安装MongoDB
    window平台安装MongoDB
    MongoDB 简介
    NoSQL 简介
    Docker有用的资源
    Docker常见仓库Redis
    Docker常见仓库MongoDB
    微信小程序
  • 原文地址:https://www.cnblogs.com/hdwgxz/p/8010797.html
Copyright © 2020-2023  润新知