26.C# 文件系统

1.流的含义

流是一系列具有方向性的字节序列,比如水管中的水流,只不过现在管道中装的不是水,而是字节序列。当流是用于向外部目标比如磁盘输出数据时称为输出流,当流是用于把数据从外部目标读入程序称为输入流。

2.文件读写

写入

            string fileName = Server.MapPath("log.txt");
            FileStream fs = File.Open(fileName, FileMode.OpenOrCreate,FileAccess.ReadWrite);
            string strData = "Hello to you";
            byte[] byteData = Encoding.UTF8.GetBytes(strData);
            fs.Write(byteData, 0, byteData.Length);

读取

            string fileName = Server.MapPath("log.txt");
            FileStream fs = File.Open(fileName, FileMode.Open,FileAccess.Read);
            
            byte[] buffer = new byte[1024];
            int count =0;
            MemoryStream ms = new MemoryStream();
            while ((count = fs.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, buffer.Length);
            }
            string strData= Encoding.UTF8.GetString(ms.ToArray());

注:File.Open方法不传FileAccess参数时,默认FileAcross.ReadWrite

3.StreamReader/StreamWriter流读写器

FileStream读写文件是直接对字节流进行操作的并不能对字符直接进行输入输出,使用StreamReader/StreamWriter可以方便的对字符/字符串进行操作。通常情况下都会把FileStream等其他流包装在StreamReader/StreamWriter中,因为这些类更容易对流进行处理。

3.1读写文本文件

写入

            string fileName = Server.MapPath("log.txt");
            FileStream fs = File.Open(fileName, FileMode.Open,FileAccess.Read);

            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine("Hello to you");
            sw.Write("It‘s now {0}", DateTime.Now.ToString());//格式化字符串

            sw.Close();
            fs.Close();

读取

            string fileName = Server.MapPath("log.txt");
            FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);
            string lines="";
            string line = sr.ReadLine();
            lines += line;
            while (line!=null)
            {
                line = sr.ReadLine();
                lines += line;
            }
            txtContent.Text = lines;
            sr.Close();
            fs.Close();

注:StreamReader/StreamWriter本身不能对文件进行FileMode,FileAccess等权限控制,如果要控制需要在包装的流中进行

StreamReader读取二进制文件

            string fileName = Server.MapPath("img\\中文Begrüßung.png");
            StreamReader sr = new StreamReader(File.OpenRead(fileName));
            byte[] buffer = new byte[1024];
            int count;
            MemoryStream ms = new MemoryStream();
            while ((count = sr.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, count);
            }

            string fileName2 = Server.MapPath("img\\中文2.png");
            FileStream fs = File.Open(fileName2, FileMode.OpenOrCreate);
            ms.WriteTo(fs);
            fs.Close();
            sr.Close();

StreamReader读取二进制文件需要用到BaseStream,不能像读写文本文件那样,否则保存的文件不能用。

4.对象序列化为二进制数据

程序一般保存的数据都不是像一般的文本文件那样直接写入文本逐行保存的,而是以二进制数据的形式保存的,使用System.Runtime.Serialization.Formatters.Binary.BinaryFormatter可以把对象序列化为二进制数据,或者把二进制数据序列化为对象。

[Serializable]
    public class Product
    {
        public long Id;
        public string Name;
        public double Price;

        [NonSerialized]
        string Notes;

        public Product(long id, string name, double price, string notes)
        {
            this.Id = id;
            this.Name = name;
            this.Price = price;
            this.Notes = notes;
        }

        public override string ToString()
        {
           return string.Format("{0},{1},${2:F2},{3}",Id,Name ,Price ,Notes);
        }
    }

序列化/反序列化

            List<Product> products = new List<Product>();
            products.Add(new Product(1, "poky", 10.2, "pokys"));
            products.Add(new Product(2, "kuti", 2.34, "第四方"));

            //序列化对象保存到文件
            string fileName = Server.MapPath("ser.txt");
            FileStream fs = File.Open(fileName, FileMode.OpenOrCreate);
            BinaryFormatter serializer = new BinaryFormatter();
            serializer.Serialize(fs, products);
            fs.Close();

            //反序列化
            FileStream ls = File.Open(fileName, FileMode.OpenOrCreate);
            List<Product> ps = serializer.Deserialize(ls) as List<Product>;
            ls.Close();

注:这里是序列化为二进制数据,所以和序列化为Json/xml是不一样的。

5.压缩/解压数据

如果要保存的数据比较大,还可以对数据进行压缩再保存,但是这里的压缩是单纯压缩数据,不是压缩文件,所以和常用的压缩解压工具是不一样的。

    public class CompressDAL
    {
        /// <summary>
        /// 创建一个压缩文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="data"></param>
        public static void SaveCompressFile(string fileName, string data)
        {
            FileStream fs = File.Open(fileName, FileMode.Create,FileAccess.Write);
            GZipStream gs = new GZipStream(fs, CompressionMode.Compress);
            StreamWriter sw = new StreamWriter(gs);//向压缩流写入数据
            sw.Write(data);
            sw.Close();
        }

        public static string LoadeCompressFile(string fileName)
        {
            FileStream fs = File.Open(fileName, FileMode.Open,FileAccess.Read);
            GZipStream gs = new GZipStream(fs, CompressionMode.Decompress);
            StreamReader sr = new StreamReader(gs);
            string lines = sr.ReadToEnd();
            return lines;
        }

    }
 string data = "叫爸爸\n叫爸爸\n";

            string fileName = Server.MapPath("gzFile.txt");
            CompressDAL.SaveCompressFile(fileName, data);
            string content = CompressDAL.LoadeCompressFile(fileName);

 

26.C# 文件系统

上一篇:【转载】 C#使用Math.PI常量来表示圆周率


下一篇:C#跨窗体传值的几种方法分析(很详细)