1.集合
(1)ArrayList内部存储数据的是一个object数组,创建这个类的对象的时候,这个对象里的数组的长度为0(2)调用Add方法加元素的时候,如果第一次增加元神,就会将数组的长度变为4往里面加(3)如果存储数据的数组满了,就会新建一个数组长度是原来的数组的两倍,这个数组被原来的数组的变量所引用比如自己实现简单的ArrayList Add方法public class MyArrayList { private object[] objArray=new object[2]; int index = 0; public void Add(object obj) { if (index>=objArray.Length-1) { object[] newObjArray = new object[objArray.Length*2]; Array.Copy(objArray, newObjArray, objArray.Length); objArray = newObjArray; } objArray[index] = obj; index++; } public int Count { get { return index + 1; } } ////// 索引器 /// /// ///public object this[int i] { get { return objArray[i]; } set { objArray[i] = value; } }
(4)常用集合
“类似数组”集合:ArrayList、List<T>“键值对”集合(“哈希表”集合):Hashtable、Dictionary<K,V>“堆栈”集合:Stack、Stack<T>(LIFO)“队列”集合:Queue、Queue<T>(FIFO)“可排序键值对”集合:(插入、检索没有“哈希表”集合高效)
SortedList、SortedList<K,V> (占用内存更少,可以通过索引访问)SortedDictionary<K,V> (占用内存更多,没有索引,但插入、删除元素的速度比SortedList快)Set 集合:无序、不重复。HashSet<T>,可以将 HashSet类视为不包含值的 Dictionary集合。与List<T>类似。SortedSet<T>(.net4.0支持,有序无重复集合)“双向链表”集合:LinkedList<T>,增删速度快。SortedList sortedList = new SortedList(); sortedList.Add("a", "A"); sortedList.Add("x", "X"); sortedList.Add("w", "W"); sortedList.Add("b", "B"); foreach (DictionaryEntry item in sortedList) { Console.WriteLine(item.Key + " " + item.Value); } for (int i = 0; i < sortedList.Count; i++) { Console.WriteLine(sortedList[sortedList.GetKey(i)]); }
ArrayList (非泛型)→ List<T>(泛型)
Hashtable(非泛型) → Dictionary<K,V>(泛型)2.foreach原理
如果一个类要被foreach遍历,就要实现IEnumerable接口比如:public class MyArrayList:IEnumerable { private object[] objArray=new object[2]; int index = 0; public void Add(object obj) { if (index>=objArray.Length-1) { object[] newObjArray = new object[objArray.Length*2]; Array.Copy(objArray, newObjArray, objArray.Length); objArray = newObjArray; } objArray[index] = obj; index++; } public int Count { get { return index + 1; } } ////// 索引器 /// /// ///public object this[int i] { get { return objArray[i]; } set { objArray[i] = value; } } public IEnumerator GetEnumerator() { return new MyIEnumerator(objArray, Count); } } public class MyIEnumerator : IEnumerator { private object[] objArr; /// /// 保存的是当前读到的第几个元素,默认-1 /// int index = -1; ////// 存储在数组中元素的个数 /// int count; public MyIEnumerator(object[] obj,int count) { this.objArr = obj; this.count = count; } ////// 返回当前指针指向的元素的值 /// public object Current { get { return objArr[index]; } } ////// 将指针向前移动一位并判断当前元素有没有元素 /// ///public bool MoveNext() { index++; if (index
3.Hashtable
键值对是以键的hash值算出其所对应的下标,存的时候算一下下标,然后存储在下标所对应的位置,取的时候也是一样Hashtable中的值是存储在bucket[] buckets这个结构数组中bucket b = new bucket();b.Key="1";b.Value="2";b.hash_coll=b.Key.GetHashCode();int index = b.hash_coll%buckets.Lenth;buckets[index]=b存储的值的顺序是根据键的hash值算出4.异常处理
int i = 1; try{return i;
}finally{ i++;} 这个程序返回的值为1Student s = new Student();s.ID = 1;try{return s;
}finally{ s.ID++;} 这个程序返回的值为s.ID=25.Path类
string path = @"d\a\1.txt";string newPath = Path.ChangeExtension(@"d\1.txt","avi");更改路径字符串的后缀名newPath = Path.Combine(@"d\12","12.txt");合并多个字符串路径,如果没有"\",自动加上newPath = Path.GetDirectoryName(path);得到文件路径所在的目录,如果本身就是一个目录,就直接返回这个目录字符串newPath = Path.GetExtension(path);得到指定文件路径的后缀名,如果不是一个文件路径,返回空字符串newPath = Path.GetFileName(path);得到指定路径的文件名(带后缀名)newPath = Path.GetFileNameWithoutExtension(path);得到指定路径的文件名(不带后缀名)newPath = Path.GetFullPath(path);得到绝对路径newPath = Path.GetTempPath();得到系统的临时目录newPath = Path.GetTempFileName();得到一个刚刚创建的临时的文件名newPath = Assembly.GetExecutingAssembly().Location得到当前运行程序集的路径6.File类
string path = @"d\a\1.txt";File.Create(path);创建指定的文件,如果文件已存在,则覆盖File.AppendAllText(path,"aaaa");向已有的文本文件中追加字符,如果文件不存在,则创建一个新的文件File.Copy(“source”, “targetFileName”, true);//文件拷贝,true表示当文件存在时“覆盖”,如果不加true,则文件存在报异常。File.Delete(path);File.Exists(path);File.Move(原路径,目标路径);string str = File.ReadAllText(path,Encoding.Default);读取的文件用什么编码存储就用什么编码读取,有的时候必须指定的编码格式string[] lines = File.ReadAllLines(path,Encoding.Default);读取文本文档,返回字符串数组7.Directory类
Delete(string path) 删除目录,如果要递归删除 调用Delete(string path,bool recursive)Exists(string) 指定目录是否存在Move(string oldDir,string newDir) 移动目录 ----改名原理一致 CreateDiectory() 创建目录string[] GetDirectories() 得到指定目录下的所有的子目录 返回string数组string[] GetDirectories(string path,string searchPattern,SearchOption opton) 可以按统配符查找子目录GetFiles() 得到指定目录下的所有的文件8.字符编码
字符编码就是字符以什么样的二进制排序存入到电脑的硬盘,并按照什么样的规则读取出来并还原.ASCII码 GB2312 Unicode UTF-89.DirectoryInfo类
是1个操作目录的实例类,提供了与静态类Directory类相同的方法 但是做了少部分扩展 当需要对目录进行多次操作的时候 最好是将该目录封装到实例对象中 以便多次操作10.FileInfo类
是1个操作文件的实例类 提供了静态File相同的方法 但是做了扩展 比如可以得到文件的大小.....等当需要对同1个文件进行多次操作的时候 最好是将该文件封装到改对象中操作11.FileStream类
文件的读取: //1.创建一个文件流对象,并给这个文件流对象指定操作的文件(路径)还有指定操作方式 FileStream fs = new FileStream(@"e:\1.txt", FileMode.Open); //2.准备一个byte数组,以供文件流对象读取数据并放到这个数组里面 byte[] bytes = new byte[1024 * 1024]; //3.调用文件流的读数据方法,将读出来的字节放入到bytes数组中 fs.Read(bytes, 0, bytes.Length); //4.将字节数组以指定的编码转换为字符串 string content = Encoding.Default.GetString(bytes); //5.关闭文件流 fs.Dispose(); 推荐使用using关键字释放文件的写入: //1.创建一个文件流对象,并给这个文件流对象指定操作的文件(路径)还有指定操作方式 FileStream fs = new FileStream(@"e:\1.txt", FileMode.Create); //2.将要写人的文字转换为字节数组 byte[] bytes = Encoding.Default.GetBytes("我是要写入的文字"); //3.调用文件流的写入数据方法 fs.Write(bytes, 0, bytes.Length); //4.关闭文件流 fs.Dispose();拷贝大文件 using (FileStream fsRead = new FileStream(@"e:\1.wmv",FileMode.Open)) { using (FileStream fsWrite = new FileStream(@"e:\2.wmv", FileMode.Create)) { byte[] bytes = new byte[1024 * 1024]; int length; do { length = fsRead.Read(bytes, 0, bytes.Length);//length表示读取的真实的字节数,bytes.Length表示一次预读取的 //字节数 fsWrite.Write(bytes, 0, length); } while (length == bytes.Length);}
12.压缩流GZipStream
压缩原理:1.图片2.文本文件3.电影4.字符串
1>压缩:1.创建读取流File.OpenRead()2.创建写入流File.OpenWrite();3.创建压缩流new GZipStream();将写入流作为参数与。4.每次通过读取流读取一部分数据,通过压缩流写入。2>解压1.创建读取流:File.OpenRead()2.创建压缩流:new GZipStream();将读取流作为参数3.创建写入流File.OpenWrite();4.每次通过压缩流读取数据,通过写入流写入数据。//GZipStream就是对FileStream的又一个包装 //将文本文件1.txt压缩 //1.创建读取文本文件的流 using (FileStream fsRead = File.OpenRead("1.txt")) { //2.创建写入文本文件的流 using (FileStream fsWrite = File.OpenWrite("yasuo.txt")) { //3.创建压缩流 using (GZipStream zipStream = new GZipStream(fsWrite, CompressionMode.Compress)) { //4.每次读取1024byte byte[] byts = new byte[1024]; int len = 0; while ((len = fsRead.Read(byts, 0, byts.Length)) > 0) { //通过压缩流写入文件 zipStream.Write(byts, 0, len); } } } } Console.WriteLine("ok"); Console.ReadKey(); using (FileStream fsRead = File.OpenRead("yasuo.txt")) { using (GZipStream gzipStream = new GZipStream(fsRead, CompressionMode.Decompress)) { using (FileStream fsWrite = File.OpenWrite("jieya.txt")) { byte[] byts = new byte[1024]; int len = 0; while ((len = gzipStream.Read(byts, 0, byts.Length)) > 0) { fsWrite.Write(byts, 0, len); } } } } Console.WriteLine("ok"); Console.ReadKey();
13.using
被using管理的对象一出usin块就会自动调用这个对象的Dispose方法如果类的对象要被using管理,这个对象的类必须实现IDisposable接口using的本质就是一个try finally,将using中的代码生成在了try中,调用该对象的Dispose()写在了finally中14.序列化和反序列化
序列化:将对象的状态持久化到某一种设备上(磁盘)要将类标记为Serializable,这个类的对象才可以被序列化以二进制的方式序列化,而不是文本文档反序列化:将之前序列化的文件还原为对象