C#中的IO
本文环境为:
Win 10
VS 2015
.net Framework 版本 4.0
File 类
File 类是一个工具类,可以用来判断文件是否存在和方便的创建文件, 读取、写入等操作,但是因为他是全部读取的方式,因此该类的读取和写入不适合大文件。如果是小文件的处理用
File
类是非常方便的。
Function 1: 判断文件是否存在
bool flag = File.Exists("temp.txt");
if (flag)
{
MessageBox.Show("temp.txt文件存在");
}
else
{
MessageBox.Show("temp.txt文件不存在");
}
Function 2: 创建和删除文件
//不可重复创建,如果创建一个已经存在的文件那么就会报错
File.Create("temp.txt");
//删除文件
if (File.Exists("temp.txt"))
{
File.Delete("temp.txt");
MessageBox.Show("删除成功!");
}
else
{
MessageBox.Show("文件不存在!");
}
Function 3: 写入数据
//通过字节流的方式写入
byte[] bytes = Encoding.Default.GetBytes("通过字节流的方式写入的内容!");
File.WriteAllBytes("temp.txt", bytes);
//通过文本的方式写入
File.WriteAllText("temp.txt", "通过文本的方式写入的内容!", Encoding.Default);
//行写入
string[] strs = { "第一行", "第二行" };
File.WriteAllLines("temp.txt", strs, Encoding.Default);
Function 4:追加数据
//直接追加文本
File.AppendAllText("temp.txt", "我是追加的内容", Encoding.Default);
//追加行
string[] strs = { "追加的第一行", "追加的第二行" };
File.AppendAllLines("temp.txt", strs, Encoding.Default);
Function 5: 读取数据
//将文件读取为字节流
byte[] bytes = File.ReadAllBytes("temp.txt");
string content1 = Encoding.Default.GetString(bytes);
//读取全部的文本
string content2 = File.ReadAllText("temp.txt", Encoding.Default);
//读取所有行
string[] strs = File.ReadAllLines("temp.txt", Encoding.Default);
FileStream类
FIleStrema 类 是以流的方式读取和写入文件的一个类,如果要读取或者写入大文件的时候那么必须要使用和这个类。
Function 1:FileStream 写入文件
//创建一个temp.txt文件的文件流,temp.txt 处理的方式 如果存在就打开否则就创建文件, 对文件执行什么操作 写入
FileStream fs = new FileStream("temp.txt", FileMode.OpenOrCreate, FileAccess.Write);
byte[] bytes = Encoding.Default.GetBytes("我是要写入的内容");
//写入流文件 bytes 开始写入的位置,写入多长
fs.Write(bytes, 0, bytes.Length);
//进行一次流操作以后必须要释放资源,因为GC是不会回收IO资源的
//清除缓存区
fs.Flush();
//关闭流
fs.Close();
//清除占用的资源
fs.Dispose();
//简化写法,using关键字处理可以引用命令空间之外还可以用来清除资源
using (FileStream fs = new FileStream("temp.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] bytes = Encoding.Default.GetBytes("我是要写入的内容");
//写入流文件 bytes 开始写入的位置,写入多长
fs.Write(bytes, 0, bytes.Length);
}
Function 2: FileStream 读取文件
using (FileStream fs = new FileStream("temp.txt", FileMode.OpenOrCreate, FileAccess.Read))
{
//间隙一个1M 的缓存区
byte[] buffer = new byte[1024 * 1024];
int length = fs.Read(buffer, 0, buffer.Length);
string content = Encoding.Default.GetString(buffer, 0, length);
Console.WriteLine(content);
}
Function 3: Demo FileStream 实现大文件的复制
该Demo的主要功能实现一个大文件的复制操作,因为该文件比较大所以我们要读取一点然后写入一点,不可以全部读取并写入
string filePath = @"F:VideoAndroid11-20151014-安卓基础第11天.rar";
string copyPath = @"F:VideoAndroid11-20151014-安卓基础第11天(copy).rar";
private void btnCopy_Click(object sender, EventArgs e)
{
/*
因为比较懒所以只实现了核心的功能,没有搞让选择文件的功能和另开线程的方式
路径就直接写死了: F:VideoAndroid11-20151014-安卓基础第11天.rar 文件 复制到中目录下 F:VideoAndroid11-20151014-安卓基础第11天(copy).rar
*/
using (FileStream fsRead = new FileStream(this.filePath, FileMode.Open, FileAccess.Read))
{
using (FileStream fsWrite = new FileStream(this.copyPath, FileMode.OpenOrCreate, FileAccess.Write))
{
while (true)
{
//建立一个5M的缓存区
byte[] buffer = new byte[1024 * 1024 * 5];
//fsRead方法会将 流数据读取到缓存区中 返回真正的长度
int length = fsRead.Read(buffer, 0, buffer.Length);
//没有读取到内容,就证明已经复制完成了,结束循环
if (length <= 0)
break;
fsWrite.Write(buffer, 0, length);
}
}
}
MessageBox.Show("复制完成!");
}
Function 4: 更快的获取FileStream
在上面我们提到了 File 这个工具类,同样我们也可以使用这个强大的类 来获取文件流。
//我们可以看到跟我 FileStream fs = new FileStream(,,,)的方式的参数是一样的
FileStream fsWrite = File.Open(this.copyPath, FileMode.OpenOrCreate, FileAccess.Write);
//我们来看看反编译的代码,只是把我们 new 的操作帮我们封装好了
public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
{
return new FileStream(path, mode, access, share);
}
StreamReader
using (StreamReader sReader = new StreamReader("temp.txt", Encoding.Default))
{
string content = null;
//第一种读取方式,占用的资源少
//循环按照行来读取,结束条件是内容读取完了
while ((content = sReader.ReadLine()) != null)
{
Console.WriteLine(content);
}
//第二种读取方式 ,占用资源多
//一次读完
string content2 = sReader.ReadToEnd();
Console.WriteLine(content);
}
StreamWriter
//参数: 需要写入的文件的路径,是否追加,编码方式
using (StreamWriter sWriter = new StreamWriter("temp.txt", false, Encoding.Default))
{
//第一种写入方式,两种方式用一种即可
//直接写入
sWriter.Write("我是要写入的内容");
//第二种写入方式
//按行写入
sWriter.WriteLine("111");
}
Directory和Path 类
Directory用来处理目录的工具类,Path用来处理路径的工具类,用法介绍的太多了请大家移步百度。
下面将做一个小的Demo来介绍这两个类-《树图资源管理器》
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StudyIO
{
public partial class frmDirectory : Form
{
public frmDirectory()
{
InitializeComponent();
Init();
}
/// <summary>
/// 初始化树图的根节点
/// </summary>
void Init()
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (var item in drives)
{
if (item.IsReady)
{
AddRootNode(item.Name);
}
}
}
/// <summary>
/// 实例化树图的根节点并添加到treeview上
/// </summary>
/// <param name="name"></param>
void AddRootNode(string name)
{
TreeNode rootNode = new TreeNode()
{
Text = name,
Tag = name,
//添加节点的照片
ImageIndex = 0,
//被选中的时候的照片,如果不设置此属性只是设置了 【ImageIndex】属性的话就会有一些小bug
SelectedImageIndex = 0
};
this.tvDirectory.Nodes.Add(rootNode);
}
/// <summary>
/// 实例化文件夹节点并且添加到指定的节点下面
/// </summary>
/// <param name="parent"></param>
/// <param name="name"></param>
void AddFolderNode(TreeNode parent, string name)
{
TreeNode rootNode = new TreeNode()
{
Text = Path.GetFileName(name),
Tag = name,
//添加节点的照片
ImageIndex = 1,
//被选中的时候的照片,如果不设置此属性只是设置了 【ImageIndex】属性的话就会有一些小bug
SelectedImageIndex = 1
};
parent.Nodes.Add(rootNode);
}
/// <summary>
/// 实例化文件节点并添加到指定的节点下
/// </summary>
/// <param name="parent"></param>
/// <param name="name"></param>
void AddFileNode(TreeNode parent, string name)
{
TreeNode rootNode = new TreeNode()
{
Text = Path.GetFileName(name),
Tag = name,
//添加节点的照片
ImageIndex = 2,
//被选中的时候的照片,如果不设置此属性只是设置了 【ImageIndex】属性的话就会有一些小bug
SelectedImageIndex = 2
};
parent.Nodes.Add(rootNode);
}
/// <summary>
/// 点击节点时出发的事件
/// <p>当点击节点的时候才加载位于该节点下面的节点,是一种简单的延迟加载机制</p>
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tvDirectory_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
return;
}
try
{
//清空选中节点下的所有节点下的节点
e.Node.Nodes.Clear();
string directory = e.Node.Tag.ToString();
string[] directorys = Directory.GetDirectories(directory);
//先加载文件夹
foreach (var item in directorys)
{
this.AddFolderNode(e.Node, item);
}
//加载文件
string[] files = Directory.GetFiles(directory);
foreach (string item in files)
{
this.AddFileNode(e.Node, item);
}
//判断节点是否展开了如果没有展开那么就展开节点
if (!e.Node.IsExpanded)
e.Node.Expand();
//如果树图节点是展开的那么久关闭节点
else
e.Node.Collapse();
}
catch (Exception)
{
Console.WriteLine("权限问题报错!");
}
}
}
}
源码下载
本文总结了一些常用的IO的操作,但是肯定有遗漏,只好请大家集百家之所长了。因为本人很懒,所以代码实在不敢恭维..哈。