zoukankan      html  css  js  c++  java
  • 文件和流(序列化)

           可以借助另一项技术把数据保存到文件--序列化。序列化是一个基于 .NET 流的高层模型。就本质而言,序列化允许你把整个活动的对象转换为一系列字节,并把这些字节写入 FileStream 之类的流对象中。以后,你可以重新读取这些字节从而重建原对象。

           你的类必须符合下列条件才能使用序列化:

    • 在类的声明前必须有 Serializable 特性
    • 类的所有公有和私有变量必须是可序列化的
    • 如果该类从其他类继承,所有的父类都必须可序列化

           如果你违反任一规则,在你序列化对象时会得到一个 SerializationException 异常。

           下面是一个可用于保存日志信息的可序列化类:

    [Serializable]
    public class LogEntry
    {
        public string Message { get; set; }
     
        public DateTime Date { get; set; }
     
        public LogEntry(string message)
        {
            this.Message = message;
            this.Date = DateTime.Now;
        }
    }

    提示:

           类使可以包含不需要序列的数据的,例如某个大型字段可以很方便的重建或者出于安全性的考虑。遇到这些情况,在恰当的变量前加入 NonSerialized 特性即可。反序列化数据以创建原对象的副本时,不可序列化的变量会返回它们的默认值。

           要把可序列化对象转换为字节流,必须使用一个实现 IFormatter 接口的类。

           .NET Framework 包含两个这样的类:

    • BinaryFormatter:把对象序列化成压缩的二进制格式。(位于 System.Runtime.Serialization.Formatters.Binary 命名空间)
    • SoapFormatter:使用 SOAP XML 格式产生一个相对长一些的基于文本的信息。(位于 System.Runtime.Serialization.Formatters.Soap 命名空间,同时还需要先引用程序集 System.Runtime.Serialization.Formatters.Soap.dll )

    以先前的示例为基础加以修改,看一下怎么序列化对象:

    private void Log(string message)
    {
        FileMode mode;
        if (ViewState["LogFile"] == null)
        {
            ViewState["LogFile"] = GetFileName();
            mode = FileMode.Create;
        }
        else
        {
            mode = FileMode.Append;
        }
     
        string fileName = ViewState["LogFile"].ToString();
        using (FileStream fs = new FileStream(fileName, mode))
        {
            LogEntry entry = new LogEntry(message);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(fs, entry);
        }
    }

    不再读取原始数据,现在反序列化每个保存的实例:

    protected void btnRead_Click(object sender, EventArgs e)
    {
        if (ViewState["LogFile"] != null)
        {
            StringBuilder log = new StringBuilder();
     
            string fileName = ViewState["LogFile"].ToString();
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                BinaryFormatter formatter = new BinaryFormatter();
     
                // 文件中被序列化的对象有多个,因此要用循环
                while (fs.Position < fs.Length)
                {
                    // 每一次反序列化出一个对象,流中的位置(Position)都会前进到下一个对象前
                    LogEntry entry = (LogEntry)formatter.Deserialize(fs);
                    log.Append(entry.Date.ToString());
                    log.Append("<br />");
                    log.Append(entry.Message);
                    log.Append("<br /><br />");
                }
            }
            lblInfo.Text = log.ToString();
        }
        else
        {
            lblInfo.Text = "There is no log file";
        }
    }

    总结:

           至此,文件和流这一部分讲述了如何利用 .NET 类来获取文件系统信息,如何使用文件和序列化对象,还讲述了数据绑定如何与文件类一起工作,如何用 Path 类弥补安全漏洞,如何处理多用户场景里对文件资源的争夺,最后,还说了使用 GZIP 的数据压缩。

  • 相关阅读:
    数据结构和算法
    Java Zip工具类(全)
    Java Zip压缩文件返回前端并下载
    Java 通过URL进行远程文件下载
    最通俗易懂的JavaScript实用案例
    通俗易懂的JavaScript进阶教程
    最通俗易懂的JavaScript入门教程
    Git和Github详细入门教程(别再跟我说你不会Git和Github)
    HTML入门详细总结
    你好,我是梦阳辰!
  • 原文地址:https://www.cnblogs.com/SkySoot/p/2648689.html
Copyright © 2011-2022 走看看