1、File类(下)
string[] File.ReadAllLines( 文件, 编码格式)以行的形式读取文本文件。由于读取出来的是一个数组,所以如果要对每行都进行操作时使用此方法。string File.ReadAllText( 文件, 编码格式)以字符串的形式读取文本文件。因为返回值是一整个字符串,因此对其编辑比较麻烦,但是在只想要读取文字的情况下比较简便。File.WriteAllLines( 文件, string[])以行的形式写入文本文件。File.WriteAllText( 文件, string)将字符串直接写入文本文件。File.AppendAllText( 文件, string)将字符串加入到文本文件后面- 缺点:只能读小文件,因为一次性全部读取,很费内存。在读取大文件的时候使用文件流。
2、绝对路径和相对路径
- 绝对路径:通过给定的这个路径直接能在我的电脑中找到这个文件。
- 相对路径:文件相对于应用程序的路径。这样在调用文件的时候就不需要写前面那一串,只写文件名即调用同一目录下的文件。
- 在开发中,尽量使用相对路径
3、List泛型集合
List<数据类型> 集合名 = new List<数据类型>();创建泛型集合- 方法和其他集合的方法大同小异,但是值类型,避免了ArrayList的麻烦引用问题
int[] nums = list.ToArray();List泛型集合可以转换为数组,但是类型要相同List<char> lishChar = chs.ToList();数组也可以转成List
4、装箱和拆箱
1. 概念
- 装箱:将值类型转换成引用类型
- 拆箱:将引用类型转换成值类型
- 解释:将int转换成object就是一次装箱操作。判断是否装箱主要就是看转换的地方有没有发生类型转换成引用类型。
2. 值类型
- 基本数据类型:int, long, float, char, bool
- 枚举类型:enum
- 结构类型:struct
3. 引用类型
- 类:System.Object, string, class
- 接口:interface
- 数组:int[], string[]
4. 装箱拆箱效率很低,因此我们在写代码的时候要尽量避免装箱和拆箱
5. 值类型和引用类型的区别就是值类型是存在堆上,而引用类型是存在栈上
5、Dictionary字典集合
- 举例
Dictionary<int, string> dic = new Dictionary<int, string>();- 大部分方法和其他集合相同,没有Hashtable的引用问题。
- 独特的遍历方法:
foreach (KeyValuePair<int,string> kv in dic)
{
Console.WriteLine("{0}-----{1}", kv.Key, kv.Value);
}6、FileStream文件流
1. 区别
- 和File的区别:File一次性读取所有,而FileStream不是一次性读取,对内存压力较小。
- 和SteamReader & StreamWriter的区别:FileStream操作字节(可以操作任何类型文件),而SteamReader & StreamWriter操作字符(只能操作文本文件)。
2. 用法
- 使用FileStream来读取一次数据,举例:
//文件路径,针对文件怎么做(Open\Creat\Append),针对数据怎么做
FileStream fsRead = new FileStream(@"C:\Users\crg88\Desktop\抽象类特点.txt", FileMode.OpenOrCreate, FileAccess.Read);
//内存中开辟一个5M字节数组
byte[] buffer = new byte[1024 * 1024 * 5];
//读取文件一定长度,放在字节数组里面,返回实际读取的有效字节数
int r = fsRead.Read(buffer, 0, buffer.Length);
//将字节数组中的每一个元素按照指定的编码格式解码成字符串,从0开始,长度为r
string s = Encoding.Default.GetString(buffer, 0, r);
//关闭流
fsRead.Close();
//释放流所占用的资源
fsRead.Dispose();
Console.WriteLine(s);
Console.ReadKey();- 写入一次文本,举例:
using(FileStream fsWrite=new FileStream(@"C:\Users\crg88\Desktop\new.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
string str = "看我有木有把你覆盖掉";
byte[] buffer = Encoding.Default.GetBytes(str);
fsWrite.Write(buffer, 0, buffer.Length);
}
Console.WriteLine("写入成功");
Console.ReadKey(); 注意1:这里的覆盖规则是一个个字符覆盖,不是全部删除然后只剩下了新字符
注意2:由于用的是using,因此无需手动释放资源
- 使用文件流来复制文件,举例:
static void Main(string[] args)
{
string source = @"C:\Users\crg88\Desktop\1、复习.avi";
string target = @"C:\Users\crg88\Desktop\new.avi";
CopyFile(source, target);
Console.ReadKey();
}
/// <summary>
/// 复制文件
/// </summary>
/// <param name="source">要复制的文件的路径</param>
/// <param name="target">目标路径</param>
public static void CopyFile(string source, string target)
{
//创建一个用来读取的流
using (FileStream fsRead = new FileStream(source, FileMode.Open, FileAccess.Read))
{
//创建一个用来写入的流
using (FileStream fsWrite = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] buffer = new byte[1024 * 1024 * 5];
//文件可能超出一次读取的量,需要多次读取
while (true)
{
//返回本次读取实际读取到的字节数
int r = fsRead.Read(buffer, 0, buffer.Length);
//如果返回的是一个0,说明全部读取完毕
if (r == 0)
{
break;
}
//每次写入r个字节
fsWrite.Write(buffer, 0, r);
}
}
}
}7、SteamReader & StreamWriter文件流
- 使用SteamReader读取文本文件,例子:
//可以选择读取的编码
using(StreamReader sr=new StreamReader(@"C:\Users\crg88\Desktop\抽象类特点.txt", Encoding.Default))
{
//一次只能读一行,因此需要多次读取
//循环条件是还没读到流尾
while (!sr.EndOfStream)
{
//打印读出来的一行文本
Console.WriteLine(sr.ReadLine());
}
}
Console.ReadKey();- 使用StreamWriter写入文本文件。例子:
//如果选择在源文件尾部追加则填入true
using (StreamWriter sw = new StreamWriter(@"C:\Users\crg88\Desktop\new.txt", true))
{
sw.WriteLine("看我有木有把你覆盖掉");
}
Console.ReadKey();8、多态
1. 实现多态的三种手段:
- 虚方法
- 抽象类
- 接口
2. 虚方法:
- 使用方法:先将父类的方法标记为虚方法,在public后使用关键字
virtual;然后在子类的同名方法前的public后使用关键字override。将子类赋给父类之后,点出来虚方法即可跳回。 - 原理:仍然调用的是父类的方法(表现出来的类型是父类的因此只能调用父类的函数),但是由于是虚方法,所以转而调用子类的方法,具体调用哪个方法与对象是属于哪个类的有关。因此如果里面装的就是父类的对象,虽然父类的是虚方法,仍然会执行。
- 提示:在使用虚方法的时候,虚方法本身也有意义,不要将方法写成空实现(大括号里面没有内容)。 当虚方法没有意义的时候,或者说当父类中的方法(虚方法)不知道如何实现的时候,可以考虑把父类写成抽象类,将方法写成抽象方法。
3. 抽象类:
- 使用方法:在 类和方法 的public后使用关键字
abstract,不写, 不打大括号 ,在括号后面直接分号结束;然后在子类的同名方法前的public后使用关键字virtualoverride。将子类赋给父类之后,点出来抽象方法即可跳回。 - 抽象成员必须标记为abstract,并且不能有任何实现
- 抽象成员必须在抽象类中, 抽象成员可以是字段、属性、方法 。
- 子类继承抽象类后,必须把父类中的所有抽象成员重写(除非子类也是抽象类)
- 抽象类不能被实例化,也就是抽象类不允许创建自己的对象,需要创建子类对象赋值给父类。
- 抽象成员的访问修饰符不能是private
- 实例成员可以在抽象类中,但是父类不能调用,子类可以调用,也可以不调用。
- 抽象类是有构造函数的,虽然不能被实例化
- 如果父类的抽象方法中有参数或者返回值,那么继承这个父类的子类在重写父类的方法的时候必须有对应的参数和返回值
- 因此,如果父类中的方法有默认的实现,并且父类需要被实例化,那么定义为一个普通类,用虚方法。如果父类中的方法没有默认实现,父类也不需要被实例化,则可以定义为抽象类。
9、 获取其他类成员的方法
- 传参:在方法的括号里面直接声明其他类的变量
- 声明字段:声明其他类的字段和属性
- 构造函数:在构造函数中声明其他类的变量
评论