评论

收藏

[C++] .Net中的IO

编程语言 编程语言 发布于:2021-08-03 10:37 | 阅读数:311 | 评论:0

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:\Video\Android\11-20151014-安卓基础第11天.rar";
string copyPath = @"F:\Video\Android\11-20151014-安卓基础第11天(copy).rar";
private void btnCopy_Click(object sender, EventArgs e)
{
  /*
   因为比较懒所以只实现了核心的功能,没有搞让选择文件的功能和另开线程的方式
     路径就直接写死了: F:\Video\Android\11-20151014-安卓基础第11天.rar 文件 复制到中目录下 F:\Video\Android\11-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来介绍这两个类-《树图资源管理器》
DSC0000.gif
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的操作,但是肯定有遗漏,只好请大家集百家之所长了。因为本人很懒,所以代码实在不敢恭维..哈。

除非特殊声明否则,本博客文章均属 鲁迅认识的那只猹 原创,未经许可禁止转载,否则将保留追究法律责任的权利。
如果本博客损害了您的相关权益,请及时联系我,我将妥善处理。


关注下面的标签,发现更多相似文章