C#学习笔记——I/O类及异常捕获
一、I/O类
System.IO 命名空间中有各种不同的类,用于执行各种文件操作,如创建和删除文件、读取或写入文件,关闭文件等。
1、Path类
该方法主要获取路径、文件夹名称等
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace LIST
{
class PathClass
{
static void Main()
{
//获取文件的扩展名
Console.WriteLine(Path.GetExtension(@"C:\Users\Administrator\Desktop\新建文本文档.txt"));
//更改文件的扩展名
Console.WriteLine(Path.ChangeExtension(@"C:\Users\Administrator\Desktop\新建文本文档.txt","jpg"));
//获得文所在文件夹的路径
string str = Path.GetDirectoryName(@"C:\Users\Administrator\Desktop\新建文本文档.txt");
Console.WriteLine(str);
//获取文件的名字
Console.WriteLine(Path.GetFileName(@"C:\Users\Administrator\Desktop\新建文本文档.txt"));
//活期文件的名字但不包含扩展名
Console.WriteLine(Path.GetFileNameWithoutExtension(@"C:\Users\Administrator\Desktop\新建文本文档.txt"));
//连接一个目录和一个文件
string str2 = Path.Combine(@"C:\Users\Administrator\Desktop", "新建文本文档.txt");
Console.WriteLine(str2);
//获取文件的全部路径
string str3= Path.GetFullPath(@"C:\Users\Administrator\Desktop\新建文本文档.txt");
Console.WriteLine(str3);
}
}
}
2、File类
1>编码
编码:将数据以怎样的形式保存为二进制
- 编码发展史
----ASC 128
----ASCII 256
----GB2312 简体字
----BIG 繁体字
----UniCode(解析慢)
----UTF-8(web)
乱码原因:保存文件采用的编码与打开文件采用的编码格式不一样
2>File类相关方法
- 基本操作
---- creat 创建文件
---- delete 删除文件
---- copy 复制文件
---- exists 文件是否存在
---- move 移动/剪切文件
---- ReadAllBytes、ReadAllLines、ReadAllText 文件读取的三种方式
---- WriteAllBytes 、WriteAllLines、WriteAllText 文件覆盖写入的的三种方式
---- AppendAllText、AppendAllLines
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace LIST
{
class Flies
{
static void Main()
{
//创建一个文件
File.Create(@"C:\Users\Administrator\Desktop\new.txt");
Console.WriteLine("创建成功");
//删除一个文件
File.Delete(@"C:\Users\Administrator\Desktop\new.txt");
Console.WriteLine("删除成功");
//复制一个文件
File.Copy(@"C:\Users\Administrator\Desktop\新建文本文档.txt", @"C:\Users\Administrator\Desktop\new.txt");
Console.WriteLine("复制成功");
//判存
bool b= File.Exists(@"C:\Users\Administrator\Desktop\new.txt");
Console.WriteLine(b);
//移动/剪切
File.Move(@"C:\Users\Administrator\Desktop\new.txt", @"C:\Users\x.txt");
//Console.WriteLine("剪切成功");
#region ReadAllBytes 按字节读取
byte[] buffer = File.ReadAllBytes(@"C:\Users\Administrator\Desktop\x.txt");
//将二进制转换为字符串
string str = Encoding.Default.GetString(buffer);
Console.WriteLine(str);
#endregion
#region ReadAllLines 按行读取
string[] str= File.ReadAllLines(@"C:\Users\Administrator\Desktop\x.txt",Encoding.Default);//出现乱码后面补上第二个参数,设置编码格式
for (int i = 0; i < str.Length; i++)
{
Console.WriteLine(str[i]);
}
#endregion
#region ReadAllText 以文本文档读取
string str = File.ReadAllText(@"C:\Users\Administrator\Desktop\x.txt");
Console.WriteLine(str);
#endregion
//string str = File.ReadAllText("x.txt",Encoding.Default);
//Console.WriteLine(str);
//覆盖写入,没有文件会自动创建文件
#region WriteAllBytes 按字节写入
string str = "圣诞节熬时间滴哦";
byte[] b = Encoding.Default.GetBytes(str);
File.WriteAllBytes(@"C:\Users\Administrator\Desktop\2.txt", b);
Console.WriteLine("写入成功");
#endregion
#region WriteAllLines 按行写入
string[] str = {
"张三", "李四", "王二", "麻子", "赵六" };
File.WriteAllLines(@"C:\Users\Administrator\Desktop\2.txt", str);
Console.WriteLine("写入成功");
#endregion
#region WriteAllText 按文本写入
string str = "设计的卢卡斯的了";
File.WriteAllText(@"C:\Users\Administrator\Desktop\2.txt", str);
Console.WriteLine("写入成功");
#endregion
//追加写入
File.AppendAllText(@"C:\Users\Administrator\Desktop\2.txt", "是就混空间");
Console.WriteLine("写入成功");
//视频文件写入:只能以字节形式写入,其他两中方式都是读写文本文档的
byte[] buffer = File.ReadAllBytes(@"C:\Users\Administrator\Desktop\2.wmv");
File.WriteAllBytes(@"C:\Users\Administrator\new.wmv", buffer);
Console.WriteLine("复制成功");
}
}
}
提示:除了对文本使用按行或者按文本文档读写外,其他格式的文件一般都以字节形式进行读写。
- 绝对路径:通过这个路径绝对的能够找到文件
相对路径:相对于用户的一个路径 - vc中添加文件的方法如下:选择需要添加的文件,并复制到剪切板,然后按如下操作完成
3、Directory类
- 用于对文件夹进行操作
- 基本方法
---- CreateDirectory 创建文件夹
---- Delete 删除文件夹
---- Exists 文件夹是否存在
---- Move 剪切
---- GetDirectories 获得一个给定目录下所有文件夹的名称
---- GetFiles 获取某个给定目录下所有文件的全路径
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace LIST
{
class Directorys
{
static void Main()
{
#region 创建文件夹,如果存在,不会创建
Directory.CreateDirectory(@"D:\VisualStudio2019\test");
Console.WriteLine("创建成功");
for (int i = 0; i < 10; i++)
{
Directory.CreateDirectory(@"D:\VisualStudio2019\test\" + i);
}
#endregion
#region 删除
Directory.Delete(@"D:\VisualStudio2019\test");//有子文件则不能删除
Directory.Delete(@"D:\VisualStudio2019\test",true);//不留子文件完全删除
Console.WriteLine("删除成功");
#endregion
#region 判断是否存在
if(!Directory.Exists(@"D:\VisualStudio2019\test"))
{
Directory.CreateDirectory(@"D:\VisualStudio2019\test");
}
else
{
Console.WriteLine("已经有文件夹了");
}
#endregion
#region 剪切
Directory.Move(@"D:\VisualStudio2019\test\a", @"D:\VisualStudio2019\b");
Console.WriteLine("剪切成功");
#endregion
#region 获得一个给定目录下所有文件夹的名称,文件名不可获得
string[] str = Directory.GetDirectories(@"D:\");
for (int i = 0; i < str.Length; i++)
{
Console.WriteLine(str[i]);
}
#endregion
#region 获取某个给定目录下所有文件的全路径
string[] str = Directory.GetFiles(@"E:\PLC\PLC配套课件\63522课件和习题答案\FX4版课件\","*.ppt");//只获得ppt文件
for (int i = 0; i < str.Length; i++)
{
//path方法
string str = Path.GetFileName(str[i]);
Console.WriteLine(str);
//substring方法
int index = str[i].LastIndexOf('\\');
string newStr = str[i].Substring(index + 1);
Console.WriteLine(newStr);
}
#endregion
}
}
}
4、Stream及FileStream类
- File与Stream的区别
---- File 只能操作小文件,Stream可操作大文件 - Stream与FileStream的区别
---- FileStream是操作字节的,Stream是操作字符的
1>FileStream方法
-
File.Mode包括
---- Append 追加写入
---- Creat 创建文件
---- Open 打开文件
---- OpenOrCreat 有则打开,无则创建 -
File.Access包括
---- Read 读文件
---- Write 写文件
- 读文件基本步骤
----1、创建文件File Stream对象
----2、创建缓冲区大小
----3、开始读取数据
----4、以哪种编码形式将读取的数据转换成目标形式输出 - 写文件基本操作
----1、创建文件File Stream对象
----2、创建缓冲区大小
----3、写入数据 - 注意:创建文件流时,一定要在结束后关闭流(FileClose())以及释放流(FileDispose())所占用的空间,如果使用Using创建的话文件流对象的话,系统会自动帮助我们完成关闭流的操作。
using System;
using System.IO;
using System.Text;
namespace FileStream类
{
class Program
{
static void Main(string[] args)
{
#region FileStream 读数据
创建FileStream对象
//FileStream fsRead = new FileStream(@"C:\Users\Administrator\Desktop\2.txt", FileMode.Open,FileAccess.Read);
创建缓存区的大小----缓冲区满了才读取一次
byte[] buffer = new byte[1024 * 1024 * 5];//大文件采用这种设置
//byte[] buffer = new byte[fsRead.Length];//小文件直接传入流的大小
//Console.WriteLine("流的长度为{0}",fsRead.Length);
开始读取数据----返回的是你这次实际读取到的字节数(小于等于流的长度)
//int read = fsRead.Read(buffer, 0, buffer.Length);//从头到尾读取缓存区的数据
//Console.WriteLine(read);
以默认编码形式将字节数组转换成字符串
//string str = Encoding.Default.GetString(buffer);
//Console.WriteLine(str);
//fsRead.Close();//关闭流
//fsRead.Dispose();//释放流占用的资源
//using可以自动的帮助我们关闭流和释放流所占用的资源
using (FileStream fsRead = new FileStream(@"C:\Users\Administrator\Desktop\2.txt", FileMode.Open, FileAccess.Read))
{
//创建缓存区的大小----缓冲区满了才读取一次
//byte[] buffer = new byte[1024 * 1024 * 5];//大文件采用这种设置
byte[] buffer = new byte[fsRead.Length];//小文件直接传入流的大小
Console.WriteLine("流的长度为{0}", fsRead.Length);
//开始读取数据----返回的是你这次实际读取到的字节数(小于等于流的长度)
int read = fsRead.Read(buffer, 0, buffer.Length);//从头到尾读取缓存区的数据
Console.WriteLine(read);
//以默认编码形式将字节数组转换成字符串
string str = Encoding.Default.GetString(buffer);
Console.WriteLine(str);
}
#endregion
#region FileStream 写数据
using (FileStream fsWrite = new FileStream(@"C:\Users\Administrator\Desktop\1.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
string str = "和数据库打算卡";
byte[] buffer = Encoding.Default.GetBytes(str);
fsWrite.Write(buffer, 0, buffer.Length);
}
Console.WriteLine("写入成功");
#endregion
}
}
}
- 用FileStream复制各种类型文件
using System;
using System.IO;
namespace Movie
{
class Program
{
static void Main(string[] args)
{
string source = @"E:\电梯模型\计量.sat";
string target = @"D:\VisualStudio2019\a.sat";
FileCopy(source, target);
Console.WriteLine("复制成功");
}
public static void FileCopy(string source,string target)
{
//读文件
using(FileStream fsRead = new FileStream(source,FileMode.Open,FileAccess.Read))//源文件肯定存在
{
//写文件
using (FileStream fsWrite = new FileStream (target,FileMode.OpenOrCreate,FileAccess.Write))//目标文件不存在则创建
{
//创建缓冲区 -- 4M
byte[] buffer = new byte[1024 * 1024 * 4];
while (true)
{
int r = fsRead.Read(buffer, 0, buffer.Length);//每次读取4M
if (r == 0)
return;
else
fsWrite.Write(buffer, 0, r);//读多少写多少
}
}
}
}
}
}
2>Stream方法
-
StreamReader类
-
StreamWriter类
using System;
using System.IO;
using System.Text;
namespace Stream类
{
class Program
{
static void Main(string[] args)
{
//使用FileStream和StreamReader读取数据
using (FileStream fsRead = new FileStream(@"C:\Users\Administrator\Desktop\2.txt", FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fsRead))
{
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
}
}
//使用StreamReader读取文件
using (StreamReader sr = new StreamReader(@"C:\Users\Administrator\Desktop\2.txt", Encoding.Default))
{
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
}
//使用FileStream和StreamWriter写入数据,会产生字符覆盖,有几个字符覆盖几个
using (FileStream fsWrite = new FileStream(@"C:\Users\Administrator\Desktop\3.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fsWrite, Encoding.Default))
{
sw.Write("今天天气好晴朗");
}
}
//使用StreamWriter写入数据,全覆盖写入,可选择追加写入
using (StreamWriter sw = new StreamWriter(@"C:\Users\Administrator\Desktop\3.txt"))
{
sw.Write("处处是阳光");
}
}
}
}
二、异常捕获
- 所有异常都是派生自System.Exception类型
- Bug、Error、Exception的区别:
1、bug是程序员所犯的错误,这些错误应该在用户程序前被修复;
2、exception是程序中可预见问题导致的结果,但无法阻止这些问题的发生,因为这些问题依赖于程序的外部环境。网络突然中断或者磁盘空间不足,这两个都是需要处理的异常的例子;
3、error是由用户行为所导致的。 - throw关键字用来抛出一个异常
一、try和catch语句
-
我们在程序中经常会出现各种各样的异常,你如果想让你的程序变得坚强一些,在你的代码中应该经常性的使用try-catch来进行异常捕获。
-
哪行代码可能出现异常,你就"踹"他一脚
语法:
try
{
~~~~~~ 可能会出现异常的代码;
}
catch
{
~~~~~~ 出现异常后要执行的代码;
} -
执行过程:
1、如果try中的代码没有出现异常,那么catch中的代码不会执行。
2、如果try中的代码出现了异常,哪怕这行代码出现异常的代码后面还有一百行代码都不会执行,而是直接跳到catch中执行代码,然后执行catch语句块下面的语句。 -
catch块支持一个额外的条件表达式。而不只是根据异常类型来匹配,现在可以添加when子句来提供一个boolean表达式,当条件为true时,catch块才处理异常。
int number=0;//声明
bool b = true;
try
{
number = Convert.ToInt32(Console.ReadLine());//赋值
//Console.WriteLine(number);上面的代码出现异常后,以下的代码都不执行
}
catch
{
Console.WriteLine("输入的内容不能够实现转换!");
b = false;
}
//我们如果需要执行下面这行代码,需要满足某些条件。
//让代码满足某些条件去执行的话,使用bool类型
if(b)
{
Console.WriteLine(number);//使用
}
- 为了对特定异常进行处理,在使用多个catch时应注意catch的顺序,应按照从具体到常规的顺序排列以避免编译错误。
2、finally语句
- 使用try语句时,一旦某行出现异常后,try中的语句将不在执行,但有些动作不论是否抛出异常都需要执行,那么有两种选择:
1、将可能发生危险的动作放在try语句块的大括号中,然后再catch和try语句块中都执行必要的动作(但会出现重复代码,容易产生错误);
2、使用finally语句。 - 注意:
---- 有或者没有catch语句块的情况下都能够创建finally语句块,但是finally语句块要求必须执行try语句块。使用break、continue、return或goto退出finally语句块都将产生错误。
3、自定义异常
- 自定义异常唯一的要求是必须从System.Exception或者它的某个子类派生,此外,使用自定义异常时应遵守如下规范:
1、所有异常都应该使用"Exception"后缀,彰显其用途
2、所有异常都应该包含以下三个构造函数:
----无参构造函数
----获取一个string参数的构造函数
----同时获取一个字符串和一个内部异常作为参数的构造函数,此外,由于异常通常在抛出它们的语句中构造,所以还应允许其他任何异常数据成为构造函数的一部分
3、避免使用深的继承层次结构(一般应小于5级)