.NET Framework

 
回忆一下:CLR(动态语言运行时)的优点:
         跨语言集成
         跨语言异处理
         增强的安全性
         版本控制
         部署支持
         简化的组件交互模型
         调试和分析服务
1、 . NET Framework的内存管理面试):
      .NET Framework的垃圾回收器管理应用程序的内存分配和释放,当使用new运算符创建对象时,运行库(CLR)都从托管堆中为该对象分配内存,只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间直到内存不够分配了,垃圾回收器才会执行回收释放一些内存。
   
   实例化新对象的过程:
         (1)计算字段所需空间
         (2)对象所需空间:包括两部分,一部分是字段、另一部分是同步块索引和类型对象指针
         (3)分配物理内存,新对象指针指向下一个可用内存区域
  
   垃圾回收过程:
         (1)标记阶段:从根标记遍历到的对象。
         (2)压缩阶段:释放没有标记的对象内存,调整存在对象的位置
 
垃圾回收过程图如下:

   代(Generation)是CLR垃圾收集器的一种机制,它存在的惟一目的就是提高应用程序性能,代表示的是对象在内存中的时间长短。        
             CLR支持3代内存(并不是应用程序的大小)
             第0代对象预算容量为256k
             第1代对象预算容量为2M
             第2代对象预算容量为10M
 
        说明:(1)CLR初始化时,托管堆中没有任何对象,此时添加对象是,为第0代对象;
              (2)当在内存(托管堆)中一直放应用程序,直到内存大于256K,这时候就触发回收,将剩下的放入0代,把新进入程序的放入1代, 同理其他的。
 
垃圾回收过程如下图:

 问题:垃圾回收器如何判断什么时候能知道是否可以回收某块内存区域?
 
     解释:当使用new关键字创建对象的时候,运行库(CLR)都从托管堆中为该对象分配内存,同时线程堆栈中也有它的一个链接(压入),当程序执行完毕(线程堆栈先进后出),就会从堆栈中出去,此时相应标记托管堆中该对象所分配的内存空间可以回收,当为对象分配内存时,如果如果内存中(托管堆)中没有对象称为0代,当往托管堆中存放的对象所占的内存空间大于0代对象的预算容量(即256k),就会默认启动垃圾回收器将不用的内存释放出去,将剩下的放入1代,把新进入的对象分配的内存放入0代,同理其他的也是如此。
 
2、文件:是一些具有永久存储及特定顺序的字节组成的一个有序的、具有名称的集合;
   流:提供一种向后备存储写入字节和从后备存储读取字节的方式,后备存储可以为多种存储媒介之一。正如除磁盘外存在多种后备存储一样,除文件流之外也存在多种流。例如,还存在网络流、内存流和磁带流等。
 
回忆一下:
以下情况要定义实例化类:
1)需要传递参数或当类型用的时候
2)对象要定义数组或集合的时候
 
文件操作
Directory类:用于公开创建、移动和枚举目录的 静态方法,此类不能被继承,用时需要实例化,然后用对象访问,使用时直接类名加点访问。
DirectoryInfo类:用于公开创建、移动和枚举目录的 实例方法,此类不能被继承用时需要实例化,然后用对象访问。
FileInfo类 :(先实例化然后用对象调用):提供创建、复制、删除和打开文件的 实例方法,此类不能被继承,需要先实例化再使用。
File类:(先实例化然后用对象调用):提供创建、复制、删除和打开文件的 静态方法,此类不能被继承,直接用类调用方法。
Path类(静态类):对包含文件或目录路径信息的实例化操作。
 
string path = @"D:\a.txt";           
File.AppendAllText(path, DateTime.Now.ToString() + "\r\n");//向指定的路径的文件尾追加内容
File.WriteAllText(path, "saffh");//向指定路径的文件中添加内容覆盖原有的内容
Console.WriteLine( File.GetAttributes(path));//获得指定文件的属性(位枚举)
Console.WriteLine( Path.GetExtension(path));//获取指定文件的路径名
  foreach (string s in Directory.GetLogicalDrives())
            {
                Console.WriteLine(s);
                DriveInfo di = new DriveInfo(s);
                Console.WriteLine(di.DriveType);//获取盘符的类型
            }//获取某台电脑所有的盘符及类型            
            DirectoryInfo di1 = new DirectoryInfo(@"D:/a");
            di1.Create();//在盘创建一个文件夹D
            di1.Delete();//删除刚创建的文件夹D
 
递归的要素:1递归必须要做一个方法
                        2递归必须有一个变化的参数
 
小练习:用递归的方法实现检索某个指定路径的所有文件夹中的文件
class Program
{     
  static void Main(string[] args)
        {
            string path = @"D:\暑期实训";
            DG(path );
        }
        static void DG(string path)
        {
            foreach (string str in Directory.GetDirectories(path))
            {
                DG(str);
            }//遍历指定路径下的所有文件夹并递归输出文件夹中的文件
            foreach (string str in Directory.GetFiles(path))
            {
                Console.WriteLine(str);
            }//遍历指定路径下的所有文件并输出
      
 }
    }
 
3、 IO-流:分为:文件流、网络流、内存流等,总是以字节数组的数据形式存储,
注:文件的读写编码要一致
     Stream:抽象化的类,本身不能实例化,需要靠子类实现它。
 
文件流的使用:
 
1)文件流写
FileStream fs = new FileStream(path, FileMode.Create,FileAccess.Write);
string con = "大家好!";
byte[] bytes = Encoding.Default.GetBytes(con);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
2)文件流读
FileStream readfs = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] bytes1 = new byte[readfs.Length];
readfs.Read(bytes1, 0, bytes1.Length);
readfs.Close();
Console.WriteLine(Encoding.Default.GetString(bytes1));
  
利用文件流实现文件的写入和读取操作
 string path = @"F:/ab.txt";
 StreamWriter sw = new StreamWriter(path);
 sw.Write("不错不错");
 sw.WriteLine("还行");
 sw.Close();
 
 StreamReader sr = new StreamReader(path, Encoding.Default);
 Console.WriteLine(sr.ReadToEnd());
 while (!sr.EndOfStream)
 {
      Console.WriteLine(sr.ReadLine());
 }          
 sr.Close();     
 
小练习:利用流操作实现名片管理数据的持久化,将数据保存在指定的文件中
namespace ConsoleApplication1
{
    class Card
    {
        public string Name
        {
            get;
            set;
        }
        public string Company
        {
            get;
            set;
        }
 
        public override string ToString()
        {
            return "姓名:" + Name + " 公司:" + Company;
        }
    }
    class Program
    {
        static void WriteCards(List<Card> list)
        {
            string[] cardes = new string[list.Count];
            int index = 0;
            foreach (Card card in list)
            {
                cardes[index++] = card.Name + "|" + card.Company;
            }
            File.WriteAllLines(@"F:/cards.txt", cardes);
        }
        static List<Card> ReadCards()
        {
            List<Card> list = new List<Card>();
            string[] cardes = File.ReadAllLines(@"F:/cards.txt");
            foreach (string cardstr in cardes)
            {
                Card card = new Card();
                card.Name = cardstr.Split('|')[0];
                card.Company = cardstr.Split('|')[1];
                list.Add(card);
            }
            return list;
        }
 
 
 
        static void Main(string[] args)
        {
            int count = 0;
           while (count < 17)
            {
                Console.WriteLine("明白吗?");
                count += int.Parse(Console.ReadLine());
            }
 
            foreach (Card card in ReadCards())
             {
                Console.WriteLine(card.ToString());
            }
 
            Card card1 = new Card();
            card1.Name = "dddd";
            card1.Company = "bbbb";
 
            Card card2 = new Card();
            card2.Name = "dfdddd";
            card2.Company = "bbdfbb";
 
            List<Card> list = new List<Card>();
            list.Add(card1);
            list.Add(card2);
 
            WriteCards(list);
           return;
      
       
        }
    }
}