当前位置: 首页 > news >正文

(12)C#传智:File类,泛型,字典,FileStream,StreamReader,多态

内容有点多,重点:泛型、字典,流与多态。

    
    继续深入学习内容:List、Dictionary、using语句、FileStream
    
一、File类的继续学心

    File.ReadAllLines(string path,Encoding,encoding)指定编码读取返回行字串数组
    File.WriteAllText(string path,Encoding encoding)
    File.AppendAllText(string path,string contents) 追加文本
    File.ReadAllTexT(string path,Encoding encoding) 指定编码返回文本内所有内容
    File.WriteAllLines(string path,string[] contents) 将字串数组按行写入
    File.AppendAllLines(string path,string[] contents) 追加多行
    

    string p = @"E:\1.txt";string[] s = File.ReadAllLines(p, Encoding.UTF8);foreach (string item in s){ Console.WriteLine(item); }string s1 = File.ReadAllText(p, Encoding.UTF8);Console.WriteLine(s1);


    
    注意:1)若操作文本文件用ReadAllText或ReadAllLines;
            若操作音频等二进制文件,用ReadAllbytes。
          2)若文本文件需精准定到行字串用ReadAllLines,反之用ReadAllText.
    
    由于File类基本上是一次性读出或写入文件,易造成内存溢出(内部byte[]大小
    固定了),所以它适用于读写小的文件。大的文件应使用FileStream
    
    


二、绝对路径与相对路径

    绝对路径:通过给定的路径,直接便可在电脑中找到该文件。
    相对路径:文件相对于应用程序或目录的路径。
    
    程序中不带路径时,直接用文件名时,用的是相对路径,即本程序当前目录。
    
    string str=File.ReadAllText(@"1.txt");//虽未指定,但与程序本身同目录
    
    相对路径更具优势,应尽量用相对路径。
    


    
三、List泛型集合

    由于ArrayList加入元素类型任意,在处理时非常不方便。
    泛型就是利用ArrayList的增加元素方便,容量自动扩展优点,但同时规定了
    加入元素的类型,以方便输出时的处理。
    
    泛型:Generic通用的,广泛的,一般的.即适用一切,专业上需指定一个特殊
    的类型。所以定义后面用<T>来指明这个广泛类型中的一个特殊的类型(Type):
    List<T>  T-Type类型   使用时需导入 using System.Collections.Generic;
    
    创建(构造):  List<int> list=new List<int>();//将List<int>整体当作类型
    
    方法:List.Add(T item)   单个元素,声明时限定了T
          List.Add(IEnumerable<T> collection)   添加集合
    
    基本上学会了ArrayList,就可以在List同样使用。
          

        List<int> lst = new List<int>() { 1, 2 };lst.Add(4); lst.AddRange(new int[] { 5, 6 });lst.AddRange(lst);//1,2,4,5,6,1,2,4,5,6Console.WriteLine(string.Join(",", lst.ToArray()));


    
    数组<-->List  可以相互转换。注意,类型须一致.
    ToArray()可以将List转换成一个数组,返回的类型与泛型规定的类型一致.
    ToList() 将数组转为List.
    

        int[] n = { 1, 2, 3, 4, 5, 6, 7, 8 };List<int> lst = n.ToList();Console.WriteLine(lst[2]);//3int[] m = lst.ToArray();Console.WriteLine(m[7]);//8


    
    为什么ArrayList与HashTable用得比较少,基本不用呢?
    
    

    
四、装箱与拆箱

    装箱:把值类型转换成引用类型。
    拆箱:将引用类型转换成值类型
    装箱与拆箱不停进行类型转换,所以影响速度,应尽量避免装箱或拆箱操作。
    
    注意:是否装箱或拆箱,两者没有继承关系,可能没有发生装箱或拆箱;
          若两者没有继承判断,那一定没有装箱或拆箱。
    
    以I开头的变量,是接口类型。接口类型也是引用类型
    

    int n = 0;object o = (object)n;//装箱int n1 = (int)o;//拆箱IComparable ic = n;//装箱string s = "123";int n2 = Convert.ToInt32(s);//没有拆箱,无继承


    //--------------------------------

    ArrayList alst = new ArrayList();Stopwatch sw = Stopwatch.StartNew();for (int i = 0; i < 1000000; i++){ alst.Add(i); }sw.Stop();Console.WriteLine(sw.Elapsed);//00:00:00.0942953List<int> lst = new List<int>();sw.Restart();for (int i = 0; i < 1000000; i++){ lst.Add(i); }sw.Stop();Console.WriteLine(sw.Elapsed);//00:00:00.0234275int[] n3 = new int[1000000];sw.Restart();for (int i = 0; i < 1000000; i++){ n3[i] = i; }sw.Stop();Console.WriteLine(sw.Elapsed);//00:00:00.0152354


    
    
五、字典Dictionary(对应前面Hashtable)

    类似List,固定了Hashtable中key与value的特殊类型.
    声明:Dictionary<Tkey,Tvalue> 
    
    在循环取值时,此时可以用键值对: KeyValuePair<Tkey,Tvalue>
       分别用点号取得对应的key与value,如:kv.key,kv.value
       

    Dictionary<int, string> dic = new Dictionary<int, string>();dic.Add(1, "张三");dic.Add(2, "李四");dic[3] = "王五";//dic.Add(1,"郑六";//错误key重复。用上句或ContainsKey判断foreach (string item in dic.Values){ Console.WriteLine(item); }foreach (KeyValuePair<int, string> kv in dic){ Console.WriteLine("{0}:{1}", kv.Key, kv.Value); }


    
    实例1:将一个数组中的奇数放到一个集合中,再将偶数放到另一个集合中;
          最终将两集合合并为一个集合,并且奇数显示在左边偶数显示在右边。
          

    int[] n = { 1, 2, 3, 4, 5, 22, 23, 45, 23 };List<int> lst1 = new List<int>();//奇List<int> lst2 = new List<int>();//偶foreach (int item in n){if (item % 2 == 0) lst2.Add(item);else lst1.Add(item);}lst1.AddRange(lst2);foreach (int item in lst1){ Console.Write(item + ","); }//1,3,5,23,45,23,2,4,22,


    
    实例2:提示用户输入一个字符串,通过foreach循环将用户输入的字符串赋值
           给一个字符数组
    

    Console.WriteLine("请输入一字符串:");string s = Console.ReadLine();while (s == null){Console.WriteLine("字串不能为空,请重新输入");s = Console.ReadLine();}char[] c = new char[s.Length];int i = 0;foreach (char item in s){c[i] = item;i++;}Console.WriteLine(c);//取首字符,一样显示全字串


    
    
    实例3:统计Welcome to china中每个字符出现的次数,不考虑大小写。
    

    string s = "Welcome to china";Dictionary<char, int> dic = new Dictionary<char, int>();char c1;foreach (char c in s){if (c == ' ') continue;c1 = char.ToUpper(c);if (dic.ContainsKey(c1)) dic[char.ToUpper(c)] += 1;else dic[c1] = 1;}foreach (KeyValuePair<char, int> kv in dic){ Console.WriteLine("字母{0}:{1}", kv.Key, kv.Value); }


    
    
    ArraryList与List<T>的区别:
    最主要的:泛型效率较高,操作不是装箱拆箱,也不涉及Object类型转换。
              ArrayList是Object类型,面对不同的类型,涉及到装箱与拆箱,效率低。
    System.Collections和System.Collections.Generic提供了很多列表、集合和数组。
    例如:List<T>、数组(int[],string[]...)、Dictionary<T,T>等,但这些列表、集合
    和数组都不是安全的,不能接受并发请求。
    1)数组。
        优点:连续存储,索引速度快,赋值修改简单方便;
        缺点:a.定义指定长度易浪费内存,或索引超限。
              b.插入、删除元素效率低且麻烦。
        不清楚数组长度时很尴尬。故C#提供ArrayList来解决此类问题。
    2)ArrayList
        优点:长度动态增加;实现Ilist接口,方便添加、插入、删除等。
        缺点:元素是object,处理操作可能出现类型不匹配,是非类型安全对象;
              处理对象时,要进行类型转换,涉及装箱拆箱,损耗性能。
        为了提高ArrayList的效率,C#又引出了泛型。
    3)List<T>
        具有ArrayList的大部分方法和优点。
        同时:List是强类型,编译器会验证类型安全,避免了类型的不安全,
              以及数组强制转换导致装箱拆箱损耗性能。
    

    
六、FileStream文件流

    将水缸A的满水,倒入到水缸B的空缸中,有两种方法:
    1)扛起整个水缸A,然后象霸王一样倒入到水缸B:痛快干脆,但得力气大。
    2)牵一水管由水缸A导流到水缸B中:   温柔便巧,不需要费大力。
    
    File类读写文件,犹如方法1,全部搬运倾泄,耗费内存。只适合小文件操作。
    FileStream类读写文件,犹如方法2,小量多次便捷高效,适宜大小文件操作。
    
    下面都适合操作大文件(几百k的文件直接用File类)
    1)FileStream :操作字节,适合任意类型的文件(因为都是字节).
    2)StreamReader和StreamWriter:操作字符,所以适合文本文件。
    
    所谓大牛,会的类肯定多,熟悉掌握多种类,也就是大牛了。
    
    FileStream类 : using System.IO;
    1、用FileStream读取文件.
    

    //初始化对象.指明路径、打开方式,访问权限FileStream fsread = new FileStream(@"E:\1.txt", FileMode.OpenOrCreate, FileAccess.Read);//创建缓冲字节数组,用来指读取。指定最大缓冲5Mbyte[] buffer = new byte[1024 * 1024 * 5];//read指定开始位置(0),及长度(b.length),内容返回到缓冲数组.//尽管指定是5M,但可能实际读取的只有2M,则下句的n就是2M.int n = fsread.Read(buffer, 0, buffer.Length);//n是实际返回的字节数//解码:按编码格式进行解码。需指明缓冲数组的起始及长度,否则解码所有含空的数组string s = Encoding.UTF8.GetString(buffer, 0, n);Console.WriteLine(s);//关闭文件流fsread.Close();//释放流所占用的资源fsread.Dispose(); 

   
    
    2、用FileStream写入文件
    1)using(声明变量)
      {
         执行语句;
      }

      .NET中,托管的资源都由.NET的垃圾回收机制GC来释放;而一些非托管的资源,则需要
      手动进行释放。.NET提供了主动和被动两种释放非托管资源的方式:
          第一种:IDisposable接口的Dispose方法;
          第二种:类型自己的Finalize方法。
      任何带有非托管资源的类型,都有必要实现IDisposable的Dispose方法,并且在使用完
      这些类型后,需要手动地调用对象的Dispose方法来释放对象中的非托管资源。
      若类型正确地实现了Finalize方法,那么即使不调用Dispose方法,非托管资源也最终会
      被释放,但到那时资源已经被很长时间无畏地占据了。
      
      using语句的作用就是提供了一个高效的调用对象Dispose方法的方式。
      对于任何IDisposable接口的类型,都可以使用using语句;
      而对于那些没有实现IDisposable接口的类型,使用using语句会导致一个编译错误。
      因此,应在using外面套用try-catch。
      
      简单地说,using能有效地释放资源。
      
    2)使用流写入文件
    

    using (FileStream fsw = new FileStream(@"E:\1.txt", FileMode.OpenOrCreate, FileAccess.Write)){string s = "遥远的救世主,浮生六记";byte[] buffer = Encoding.Default.GetBytes(s);fsw.Write(buffer, 0, buffer.Length);//仅覆盖数组数组长度的位置,其它可能乱码.}//无须手动释放,using语句自动释放    


    
    注:出现乱码,是读取与写入的编码不一致,应该注意统一。
    
    3、使用文件流实现多媒体文件的复制。
      将一个大文件复制到另一个地方
    

    string scr = @"E:\八段锦.mp4";string des = @"E:\New.mp4";using (FileStream fsr = new FileStream(scr, FileMode.OpenOrCreate, FileAccess.Read)){using (FileStream fsw = new FileStream(des, FileMode.OpenOrCreate, FileAccess.Write)){byte[] buffer = new byte[1024 * 1024 * 5];//缓冲5Mwhile (true){int n = fsr.Read(buffer, 0, buffer.Length);//预读5Mif (n == 0) break;//读取返回0字节,说明结束fsw.Write(buffer, 0, n);//应写入实际n长度}}}


    
    注意:.Net使用流读写文件时,可以将流视为一组连续的一维数据,包含开头和结尾。
          其中的游标指示了流的当前位置,所以读写都自动从游标处进行继续操作。
    
    
七、StreamReader与StreamWriter

    StreamReader与StreamWriter是操作字符的,与FileStream操作字节是有区别的。
    
    1、StreamReader
    

    StreamReader sr = new StreamReader(@"E:\1.txt", Encoding.Default);while (!sr.EndOfStream) Console.WriteLine(sr.ReadLine());sr.Close();//也可用using来省略这两句sr.Dispose();


    
    2、SteamWriter
    

    //编码方式只能在前面,这样方便后面不再进入编码方式设置StreamWriter sw = new StreamWriter(@"E:\1.txt", true, Encoding.Default);//sw.WriteLine("我是一行.");//后加行结束写入字串,即行写入sw.Write("只是字串写入");sw.Close(); sw.Dispose();


八、多态

    定义:让一个对象能够表现出多种的状态(类型)
    相同的消息给予不同的对象会引发不同的动作。
    
    
    实现多态的三种手段1、虚方法;2抽象类;3、接口。
    
    1、问题抛出:
        有一父类Person,下面三子类China,Japan,Korea.

        public class Person{private string _name;public string Name{ get { return _name; } set { _name = value; } }public Person(string name){ this._name = name; }public void SayHello(){ Console.WriteLine("我是人类"); }}public class China : Person{public China(string name) : base(name){ }public void SayHello(){ Console.WriteLine("中国人:{0}", this.Name); }}public class Japan : Person{public Japan(string name) : base(name){ }public void SayHello(){ Console.WriteLine("日本人:{0}", this.Name); }}public class Korea : Person{public Korea(string name) : base(name){ }public void SayHello(){ Console.WriteLine("韩国人:{0}", this.Name); }}


    
        使用父类数组调用子类同名方法,只能通过判断。
        

        China c1 = new China("张三"), c2 = new China("李四");Japan j1 = new Japan("井边"), j2 = new Japan("村下");Korea k1 = new Korea("思密达"), k2 = new Korea("朴真");Person[] p = new Person[6] { c1, c2, j1, j2, k1, k2 };for (int i = 0; i < p.Length; i++){ p[i].SayHello(); }//显示六个“我是人类",无法显示对应国家.for (int i = 0; i < p.Length; i++){if (p[i] is China) ((China)p[i]).SayHello();else if (p[i] is Japan) ((Japan)p[i]).SayHello();else ((Korea)p[i]).SayHello();}//必须分别判断类型,才能显示国家


    
        这样调用同名方法显得臃肿。下面用虚方法
    
    2、虚方法
       在父类同名方法前面加Virtual,在子类同名方法前面加Override(重写)
        
        执行顺序,用父类方法调用同名方法时,将根据内装类型去具体调用对应方法。
        
        调用的方法取决于父类里真实装的是什么对象。内部装的是父类,则调用的是父类。
    内部装的子类,则调用的是子类。
    
        虚方法,避免的类别的判断,让一个类型表现出多种类型的状态(多态),由此写出
    通用代码(精减代码,减少冗余),最大取消它们之间的差异性(屏蔽子类间的差异性)。
    后面若需加入新子类,    只须重写一次同名方法即可。
    
    实现步骤:
        1)在父类同名方法前加入Virtual
 

        public class Person{private string _name;public string Name{ get { return _name; } set { _name = value; } }public Person(string name){ this._name = name; }public virtual void SayHello(){ Console.WriteLine("我是人类"); }}


    
        2)在子类同名方法前加入Override,同时再加一个英国人类
 

        public class China : Person{public China(string name) : base(name){ }public override void SayHello(){ Console.WriteLine("中国人:{0}", this.Name); }}public class Japan : Person{public Japan(string name) : base(name){ }public override void SayHello(){ Console.WriteLine("日本人:{0}", this.Name); }}public class Korea : Person{public Korea(string name) : base(name){ }public override void SayHello(){ Console.WriteLine("韩国人:{0}", this.Name); }}public class English : Person{public English(string name) : base(name){ }public override void SayHello(){ Console.WriteLine("英国人:{0}", this.Name); }}


        
        3)调用方法,用父类方法调用,将根据实际装的对象,调用对应方法
 

        China c1 = new China("张三"), c2 = new China("李四");Japan j1 = new Japan("井边"), j2 = new Japan("村下");Korea k1 = new Korea("思密达"), k2 = new Korea("朴真");English e1 = new English("汤姆"), e2 = new English("迈克");Person[] p = new Person[8] { c1, c2, j1, j2, k1, k2, e1, e2 };for (int i = 0; i < p.Length; i++){ p[i].SayHello(); }//不再显示“我是人类"。而显示对应国家.//由此,通过父类调用一种方法,显示不同状态


        
        练习题1:真的鸭子嘎嘎叫 木头鸭子吱叫 橡皮鸭子唧唧叫
        先定义虚方法

        public class ZSDuck{public virtual void Quark(){ Console.WriteLine("真实鸭子嘎嘎叫"); }}public class MTDuck : ZSDuck{public override void Quark(){ Console.WriteLine("木头鸭子吱吱叫"); }}public class XPDuck : ZSDuck{public override void Quark(){ Console.WriteLine("橡皮鸭子唧唧叫"); }}


        在主函数中调用:

        ZSDuck zS = new ZSDuck();MTDuck mT = new MTDuck();XPDuck xP = new XPDuck();ZSDuck[] z = { zS, mT, xP };for (int i = 0; i < z.Length; i++){ z[i].Quark(); }


    
        练习题2:经理十一点打卡 员工9点打卡 程序不打卡
        添加一父类两子类:

        public class Employee{public virtual void ClockIn(){ Console.WriteLine("员工9点打卡"); }}public class Manager : Employee{public override void ClockIn(){ Console.WriteLine("经理11点打卡"); }}public class Programmer : Employee{public override void ClockIn(){ Console.WriteLine("程序员不打卡"); }}


        在主程序中调用:

        Employee em = new Employee();Manager mg = new Manager();Programmer pg = new Programmer();Employee[] ems = { em, mg, pg };foreach (Employee item in ems){ item.ClockIn(); }


    
    3、抽象类
        上面很容易找到父类(添加virtual),定位子类同名重写(override)
        若题为"狗狗会叫,猫咪会叫",dog与cat都不宜作父类,
        应从两种中抽象出一种父类,但叫的动作却不知道具体实现,
        它只有在针对到具体的子类时才能具体的表现出来。
    
        定义:当父类中的方法不知道如何实现时,可以将父类写成抽象类,其方法写成抽象方法.
        因此上面可以写一个“动物”的抽象类,里面包含一个“叫”的抽象方法。
    
        语法:1)抽象类的前面用abstract限定,其内的抽象方法用abstract限定
              2)抽象方法不允许有方法体方法,声明仅以分号结尾,且签名后没有大括号。
              注意:没有花括号(无方法体)与有花括号但无语句(空实现),两者是有区别的。
              3)子类同名方法前加override。
              4)抽象方法是隐式的虚拟方法。在抽象方法中使用static或virtual是错误的。
              
        重要:抽象类与接口是不允许创建对象的。
        
        抽象类的特点:
        1)抽象成员必须标记为abstract,并且不能有任何买现。
        2)抽象成员必须在抽象类中;
        3)抽象类不能被例化(虽然有构造函数);
        4)子类继承抽象类后,必须把父类的所有抽象成员都复写。(除非子类也为抽象类)
        5)抽象成员的访问修饰符不能是private,因为要通过这个桥梁访问各重写的子类。
        6)在抽象类中可以包含实例成员。并且抽象类的实例成员可以不被子类实现。
        7)抽象类是有构造函数的,虽然不能被实例化。
        8)如果父类的抽象方法中有参数,那么,继承这个抽象父类的子类在重写父类方法时候,
           必须传入对应的参数。
           如果抽象父类的抽象方法中的返回值,那么子类在重写这个抽象方法的时候,也必须
           要传入返回值。
           一句话:抽象父类的抽象方法的签名必须与子类重写的方法签名一致。
        如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成
        普通类,可以用虚方法来实现。
        
        如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类。
                
        抽象类可以包括抽象方法,这是普通类所不能的。
        抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
        普通类是具体实现抽象方法的类,是有构造函数的,能实例化,不能有抽象方法。
        
        抽象类父类Animal中有抽象方法Bark(无方法体)

        public abstract class Animal{public abstract void Bark();//必须末尾有分号}


        两子类具体实现,重写抽象方法

        public class Cat : Animal{public override void Bark(){ Console.WriteLine("小猫咪咪叫"); }}public class Dog : Animal{public override void Bark(){ Console.WriteLine("小狗旺旺叫"); }}


        主方法中实现

        //Animal a = new aninal();//错误,抽象类无构造函数不能自己初始化Animal a = new Cat();//但可以用子类来赋值a.Bark();//虽然调用的是父类bark,但仍取决内装的对象(cat)Animal a1 = new Dog();a1.Bark();


    
    虚方法与抽象类的区别:
        虚方法自身有实现,自身方法可用;所以可以被子类覆盖,也可以不覆盖。
        抽象类自身无实现,自身方法不可用;所以必须一定被子类覆盖,与接口类似。
    
    抽象类中可以拥有虚方法。因为抽象类可以包含实例成员,虚方法也是实例成员一种。
    一般使用较多的是抽象类。
    
    证明抽象类的存在构造函数

        internal class Program{private static void Main(string[] args){Student s = new Student();//此处下断点,可看到s构造前进入抽象类中构造Console.WriteLine(s.ID);Console.ReadKey();}}public abstract class Person{private Guid _id;public Person()//构造函数{ this._id = Guid.NewGuid(); }public Guid ID{ get { return this._id; } }}public class Student : Person{public Student(){ }}


    
    
    4、多态的练习题
    技巧:a.要实现抽象父类方法的子类时,写完“:子类名”时,在vs2022中按Alt+Shift+F10,
            选择实现抽象类,可以快速实现抽象方法的重写
          b.对于类中的属性,当输入完毕属性名,如:public double Width时,按下
            Ctrl+R,再按Ctr+E,可以快速形成属性代码
    1)使用多态求矩形的面积和周长,以及圆形的面积和周长。
        方法相同,形状不同,构造抽象类形状。至于参数,各找各妈自己构造。

        public abstract class Shape{public abstract double GetArea();public abstract double GetPerimeter();}public class Circle : Shape{private double _r;public double R { get => _r; set => _r = value; }public Circle(double r){ this.R = r; }public override double GetArea(){ return Math.PI * this.R * this.R; }public override double GetPerimeter(){ return 2 * Math.PI * this.R; }}public class Rectangle : Shape{private double _width;private double _height;public double Width { get => _width; set => _width = value; }public double Height { get => _height; set => _height = value; }public Rectangle(double width, double height){this.Width = width;this.Height = height;}public override double GetArea(){ return this.Width * this.Height; }public override double GetPerimeter(){ return 2 * (this.Width + this.Height); }}


        主程序中:

        Shape sc = new Circle(3);Shape sr = new Rectangle(3, 5);Console.WriteLine("圆{0},{1}", sc.GetPerimeter(), sc.GetArea());Console.WriteLine("矩形{0},{1}", sr.GetPerimeter(), sc.GetArea());


    
    2)用多态实现:将移动硬盘,或者U盘,或者Mp3,插到电脑上进行读写数据。
        移动介质抽象类,子类三个。电脑读取类一个

        public abstract class Shape{public abstract double GetArea();public abstract double GetPerimeter();}public abstract class MobileStorage{public abstract void Read();public abstract void Write();}public class MobileDisk : MobileStorage{public override void Read(){ Console.WriteLine("移动硬盘在读取..."); }public override void Write(){ Console.WriteLine("移动硬盘在写入..."); }}public class Mp3 : MobileStorage{public override void Read(){ Console.WriteLine("Mp3在读取..."); }public override void Write(){ Console.WriteLine("Mp3在写入..."); }public void Play(){ Console.WriteLine("MP3在播放音乐"); }}public class Udisk : MobileStorage{public override void Read(){ Console.WriteLine("U盘在读取..."); }public override void Write(){ Console.WriteLine("U盘在写入..."); }}public class Computer{public void CpuRead(MobileStorage ms){ ms.Read(); }public void CpuWrite(MobileStorage ms){ ms.Write(); }}


        主程序中实现:

        MobileDisk md = new MobileDisk();Udisk ud = new Udisk();Mp3 mp = new Mp3();Computer cp = new Computer();cp.CpuRead(md); cp.CpuRead(ud); cp.CpuRead(mp);cp.CpuWrite(md); cp.CpuWrite(ud); cp.CpuWrite(mp);MobileStorage ms1 = new Mp3();Computer cpu = new Computer();cpu.CpuRead(ms1);cpu.CpuWrite(ms1);


    
    

相关文章:

(12)C#传智:File类,泛型,字典,FileStream,StreamReader,多态

内容有点多&#xff0c;重点:泛型、字典&#xff0c;流与多态。 继续深入学习内容&#xff1a;List、Dictionary、using语句、FileStream 一、File类的继续学心 File.ReadAllLines(string path,Encoding,encoding)指定编码读取返回行字串数组 File.WriteAllText(string…...

Dubbo的服务暴漏与服务发现源码详解

服务暴漏 如果配置需要刷新则根据配置优先级刷新服务配置 如果服务已经导出&#xff0c;则直接返回 是否异步导出&#xff08;全局或者服务级别配置了异步&#xff0c;则需要异步导出服务&#xff09; 服务暴漏入口DefaultModuleDeployer#exportServices private void exp…...

Python 的IDE——PyCharm

IDE介绍与安装 介绍 集成开发环境&#xff08;IDE&#xff09; 集成开发环境(IDE,integrated Development Environment) —— 集成开发软件需要的所有工具&#xff0c;一般包括以下工具&#xff1a; 图形用户界面 代码编辑器(支持代码补全、自动缩进) 编译器/解释器 调试器…...

01 C语言使用链表实现队列(Queue、FIFO)模块

01 C语言使用链表实现队列&#xff08;Queue、FIFO&#xff09;模块 作者将狼才鲸创建日期2023-03-08Gitee源码仓库地址&#xff1a;C语言使用链表实现队列&#xff08;Queue、FIFO&#xff09;模块 Linux原生的队列KFIFO一次只能操作一个队列&#xff0c;操作变长元素时&…...

2.2操作系统-进程管理:前趋图、前趋图与PV操作

2.1操作系统-进程管理&#xff1a;前趋图\前趋图与PV操作前趋图前趋图与PV操作练习前趋图与PV操作&#xff0c;一般出现了&#xff0c;分值在2~3分左右&#xff0c;技巧性很强。 前趋图 前趋图是为了描述一个程序的各部分间的依赖关系&#xff0c;或者是一个大的计算的各个子…...

凤凰游攻略

凤凰游攻略1 装备&#x1f4e6;1.1 证件1.2 日常用品1.3 药品1.4 衣物1.5 洗漱用品2 交通&#x1f697;3 住宿&#x1f3e0;4 美食&#x1f355;5 拍照&#x1f4f7;5.1 租苗族服5.1.1 单租服装5.1.2 服装化妆5.2 一条龙旅拍6 路线&#x1f5fa;️景点&#x1f3d9;️7 注意⚠️…...

Nginx 高可用方案

准备工作 10.10.4.5 10.10.4.6 VIP&#xff1a;10.10.4.10 两台虚拟机。安装好Nginx 安装Nginx 更新yum源文件&#xff1a; rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm wget -O /etc/yum.repos.d/CentOS-Ba…...

Linux基本指令

文章目录 常用Linux命令常见Linux指令 1、ls指令 语法&#xff1a;ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。常用选项&#xff1a; -a 列出目录下的所有文件&#xf…...

Linux系统基础命令(二)

一、浏览和切换目录 ls命令&#xff1a;列出文件和目录&#xff0c;主要用于列出文件和目录 CentOS的终端默认是有颜色标注的。一般来说&#xff1a;蓝色--->目录&#xff1b;绿色-->可执行文件&#xff1b;红色--->压缩文件&#xff1b;浅蓝色--->链接文件&#…...

【C++】C++11——简介|列表初始|简化声明|nullptr与范围for|STL中的变化

文章目录一、C11简介二、列表初始化三、简化声明四、nullptr与范围for五、STL中一些变化一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于TC1主要是对C98标准中的漏洞进行修复…...

Python -- 函数

文章目录1、一个简单的函数2、多参数函数3、返回值3.1、简单的返回3.2、返回列表和字典4、传入列表5、传入任意数量的实参5.1、以元组和字典的形式5.2、形参的排列顺序6、将函数储存在模块中1、一个简单的函数 函数用关键字def来定义&#xff0c;传参时不用指定参数类型 para&…...

Pytorch中utils.data 与torchvision简介

Pytorch中utils.data 与torchvision简介1 数据处理工具概述2 utils.data简介3 torchvision简介3.1 transforms3.2 ImageFolder1 数据处理工具概述 Pytorch涉及数据处理&#xff08;数据装载、数据预处理、数据增强等&#xff09;主要工具包及相互关系如下图所示&#xff0c;主…...

学习 Python 之 Pygame 开发魂斗罗(十)

学习 Python 之 Pygame 开发魂斗罗&#xff08;十&#xff09;继续编写魂斗罗1. 解决敌人不开火的问题2. 创建爆炸效果类3. 为敌人跳入河中增加爆炸效果4. 玩家击中敌人继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗&#xff08;九&#xff09;中&#xff0c;…...

Keepalive+LVS群集部署

KeepaliveLVS群集部署一、Keepalive概述1、什么是Keepalive2、Keepalive工作原理3、Keepalive主要模块及作用4、Keepalived 服务重要功能&#xff08;1&#xff09;管理 LVS 负载均衡软件&#xff08;2&#xff09;支持故障自动切换&#xff08;3&#xff09;实现 LVS 负载调度…...

数组、指针总结【面试题】

文章目录0. 补充知识数组笔试题1. 一维数组1.1 字符数组1.1.1 sizeof1.1.2 strlen1.2 二维数组2. 指针笔试题0. 补充知识 在进入数组与指针的练习时&#xff0c;我们先来复习以下以下的知识点&#xff0c;这可以帮助我们更好的理解下面练习 数组是一组能存放相同类型的类型的元…...

七色电子标签

机种名 电子会议桌牌 型号 ESL_7color_7.3_D 外观尺寸 176.2x137.15x80mm 产品重量 268g 可视区域 163.297.92mm 外观颜色 银色 供电方式 锂电池供电2300mAh&#xff08;Type-C 接口可充电&#xff09; 显示技术 E-INK电子纸&#xff0c;双屏 像素 800x480 像…...

大数据是什么?发展前景怎么样

关于大数据的解释&#xff0c;比较官方的定义是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。简单来说&#xff0c;大数据就是结构化…...

MYSQL必知必会 | 查询相关

汇总数据 聚集函数 有时只需要汇总数据&#xff0c;并不需要把数据实际检索出来&#xff0c;所以MySql提供了专门的函数 聚集函数&#xff1a;运行在行组上&#xff0c;计算和返回单个值的函数 函数说明AVG()返回某列平均值COUNT()返回某列的行数MAX()返回某列最大值MIN()返…...

Java学习环境一站说明(保姆级详细教学)

1.Java开发环境搭建官网下载www.oracle.com2.安装注意&#xff1a;1.选择安装位置时尽量不要安装到C盘&#xff0c;路径中不要有空格以及中文的存在2.开发人员安装的jdk中包含了jre&#xff0c;所以不需要单独安装jre3.环境变量配置打开高级系统设置2.点击环境变量3.在系统变量…...

05-Oracle中的对象(视图,索引,同义词,系列)

本章主要内容&#xff1a; 1.视图管理&#xff1a;视图新增&#xff0c;修改&#xff0c;删除&#xff1b; 2.索引管理&#xff1a;索引目的&#xff0c;创建&#xff0c;修改&#xff0c;删除&#xff1b; 3.同义词管理&#xff1a;同义词的作用&#xff0c;创建&#xff0…...

如何通过websoket实现即时通讯+断线重连?

本篇博客只是一个demo&#xff0c;具体应用还要结合项目实际情况&#xff0c;以下是目录结构&#xff1a; 1.首先通过express搭建一个本地服务器 npm install express 2.在serve.js中自定义测试数据 const express require(express); const app express(); const http req…...

爽,我终于掌握了selenium图片滑块验证码

因为种种原因没能实现愿景的目标&#xff0c;在这里记录一下中间结果&#xff0c;也算是一个收场吧。这篇文章主要是用selenium解决滑块验证码的个别案列。 思路&#xff1a; 用selenium打开浏览器指定网站 将残缺块图片和背景图片下载到本地 对比两张图片的相似地方&#x…...

二、SpringMVC注解式开发

1. RequestMapping注解 此注解就是来映射服务器访问的路径 可加在方法上,是为此方法注册一个可以访问的名称(路径) 可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称 可区分get请求和post请求 package com.powernode.controller;import org.springframe…...

Java容器面试知识点总结

容器 java容器有哪些&#xff1f; String&#xff0c;数组以及Java.util 下面的集合类 List&#xff1a;存放有序&#xff0c;列表存储&#xff0c;元素可重复 ArrayList LinkedList Vector Set:无序&#xff0c;元素不可重复 HashSet TreeSet Map: 无序&#xff0c;元素可重复…...

增长:2023 IT运维发展趋势前瞻

根据IDC和智研咨询数据等平台公开数据显示&#xff0c;从2018年至2022年&#xff0c;全球ITOM行业市场规模以8.58%的年均复合增长率高速增长。其中&#xff0c;中国ITOM市场在2020-2023年的年复合增长率为10.7%&#xff0c;到2023年市场规模将达到165.7亿元。012022中国IT运维解…...

自己定义typescript的类型声明文件xx.d.ts

****内容预警***菜鸟新手内容&#xff0c;大佬请绕道&#xff0c;不对的请指出我们在使用typescript的使用&#xff0c;如果安装一个包没有相应的类型声明文件&#xff0c;ts的类型检查就会报错&#xff0c;所以我们经常会安装npm包对应的types类型声明包&#xff0c;比如uuid …...

数据分析方法及名词解释总结_(面试2)

1、用户画像 1.1、什么是用户画像&#xff1f;如何构建用户画像&#xff1f; - 知乎提到用户画像&#xff0c; 很多人都可能存在的错误认知&#xff0c;即把用户画像简单理解成用户各种特征&#xff0c;比如说姓名、性别、…https://www.zhihu.com/question/372802348/answer/2…...

【FLY】Java知识点总结

目录认识Java概念图名词解释历史版本基础知识编程规范关键字数据类型运算符数组Stringequals与流程控制引用数据结构常用数据结构HashMapLinkedHashMapWeakHashMapIdentityHashMapEnumMapTreeMapCopyOnWriteArrayList面向对象类反射注解IO异常线程EffectiveJava8JVM运行时数据区…...

SpringMVC-0307

三、RequestMapping注解1、RequestMapping注解的功能从注解名称上我们可以看到&#xff0c;RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来&#xff0c;建立映射关系。SpringMVC 接收到指定的请求&#xff0c;就会来找到在映射关系中对应的控制器方法来处理…...

华为OD机试 - 九宫格按键输入(C 语言解题)【独家】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:九宫格按…...