菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
203
0

.net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、拷贝大文件、序列化和反序列化

原创
05/13 14:22
阅读数 69441

.net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、拷贝大文件、序列化和反序列化

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;
            }
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public object this[int i]
        {
            get
            {
                return objArray[i];
            }
            set
            {
                objArray[i] = value;
            }
        }
复制代码

 

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;
            }
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        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;
        /// <summary>
        /// 保存的是当前读到的第几个元素,默认-1
        /// </summary>
        int index = -1;
        /// <summary>
        /// 存储在数组中元素的个数
        /// </summary>
        int count;
        public MyIEnumerator(object[] obj,int count)
        {
            this.objArr = obj;
            this.count = count;
        }

        /// <summary>
        /// 返回当前指针指向的元素的值
        /// </summary>
        public object Current
        {
            get { return objArr[index]; }
        }

        /// <summary>
        /// 将指针向前移动一位并判断当前元素有没有元素
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            index++;
            if (index<count)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Reset()
        {
            throw new NotImplementedException();
        }
    }
foreach 遍历实际上是这样的
    IEnumerator tor = list.GetEnumerator();
    while (tor.MoveNext())
    {
        Console.WriteLine(tor.Current);
    }
复制代码

 

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++;

这个程序返回的值为1
Student s = new Student();
s.ID = 1;
try
{

return s;
}
finally
{
s.ID++;

这个程序返回的值为s.ID=2

5.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-8

9.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.using
被using管理的对象一出usin块就会自动调用这个对象的Dispose方法
如果类的对象要被using管理,这个对象的类必须实现IDisposable接口
using的本质就是一个try finally,将using中的代码生成在了try中,调用该对象的Dispose()写在了finally中

13.序列化和反序列化
序列化:将对象的状态持久化到某一种设备上(磁盘)
要将类标记为Serializable,这个类的对象才可以被序列化
以二进制的方式序列化,而不是文本文档
反序列化:将之前序列化的文件还原为对象

 
 
分类: ASP.NET

发表评论

0/200
203 点赞
0 评论
收藏
为你推荐 换一批