文件读写相关技术介绍,O常见操作汇总
分类:多线程

文件读写相关类介绍

问题10:如何获得计算机的所有逻辑驱动器;
解决方案:使用DriveInfo类(需要.NET 2.0)
DriveInfo.GetDrives():获得计算机的所有逻辑驱动器,返回类型为DriveInfo[];

一、文件操作

文件读写操作涉及的类主要是:

问题11:如何获取指定驱动器的信息;
解决方案:
DriveInfo.Name:获取驱动器的名称(如C:);
DriveInfo.DriveType:获取驱动器的类型(如Fixed,CDRom,Removable,Network等);
DriveInfo.DriveFormat:获取驱动器的格式(如NTFS,FAT32,CDFS,UDF等);
DriveInfo.IsReady:获取驱动器是否已准备好,比如CD是否已放入CD驱动器,如果驱动器没有准备好,访问其信息会引发IOException类型异常;
DriveInfo.AvailableFreeSpace:获取驱动器的可用空间;
DriveInfo.TotalFreeSpace:获取驱动器总的可用空间,它与AvailableFreeSpace的不同在于AvailableFreeSpace会磁盘配额的设置;
DriveInfo.TotalSize:获取驱动器总的空间;
DriveInfo.RootDirectory:获得驱动器的根目录(DirectoryInfo类型);

System.IO

向文件中追加文本 File.AppendText FileInfo.AppendText
重命名或移动文件 File.Move FileInfo.MoveTo
删除文件 File.Delete FileInfo.Delete
复制文件 File.Copy FileInfo.CopyTo
获取文件大小 FileInfo.Length
获取文件属性 File.GetAttributes
设置文件属性 File.SetAttributes
确定文件是否存在 File.Exists
检索文件扩展名 Path.GetExtension
检索文件的完全限定路径 Path.GetFullPath
检索路径中的文件名和扩展名 Path.GetFileName
更改文件扩展名 Path.ChangeExtension
  • MarshalByRefObject 类:允许在支持远程处理的应用程序中跨应用程序域边界访问对象;
  • BinaryReader 类:用特定的编码将基元数据类型读作二进制值。
  • BinaryWriter 类: 以二进制形式将基元类型写入流,并支持用特定的编码写入字符串。
  • Stream 类: 提供字节序列的一般视图。
  • FileStream类:公开以文件为主的 Stream,既支持同步读写操作,也支持异步读写操作。
  • MemoryStream 类:创建其支持存储区为内存的流。
  • BufferedStream 类:给另一流上的读写操作添加一个缓冲层。
  • TextReader 类:表示可读取连续字符系列的阅读器。
  • TextWriter 类:表示可以编写一个有序字符系列的编写器。
  • StreamReader 类:实现一个 TextReader,使其以一种特定的编码从字节流中读取字符。
  • StreamWriter 类:实现一个 TextWriter,使其以一种特定的编码向流中写入字符。
  • StringReader 类:实现从字符串进行读取的 TextReader。
  • StringWriter 类:实现一个用于将信息写入字符串的 TextWriter。该信息存储在基础 StringBuilder 中。

至此,我们已经了解了文件和目录相关的一些基本操作。

命名空间】

Stream//对字节的读写操作(包含对异步操作的支持)

在使用它们之前最好能了解它们的继承关系,有助于作出最合适的选择。

文件读写相关类介绍:
文件读写操作涉及的类主要是:
MarshalByRefObject 类:允许在支持远程处理的应用程序中跨应用程序域边界访问对象;
BinaryReader 类:用特定的编码将基元数据类型读作二进制值。
BinaryWriter 类: 以二进制形式将基元类型写入流,并支持用特定的编码写入字符串。
Stream 类: 提供字节序列的一般视图。
FileStream类:公开以文件为主的 Stream,既支持同步读写操作,也支持异步读写操作。
MemoryStream 类:创建其支持存储区为内存的流。
BufferedStream 类:给另一流上的读写操作添加一个缓冲层。
TextReader 类:表示可读取连续字符系列的阅读器。
TextWriter 类:表示可以编写一个有序字符系列的编写器。
StreamReader 类:实现一个 TextReader,使其以一种特定的编码从字节流中读取字符。
StreamWriter 类:实现一个 TextWriter,使其以一种特定的编码向流中写入字符。
StringReader 类:实现从字符串进行读取的 TextReader。
StringWriter 类:实现一个用于将信息写入字符串的 TextWriter。该信息存储在基础StringBuilder中。
在使用它们之前最好能了解它们的继承关系,有助于作出最合适的选择:

分类:

BinaryReader和BinaryWriter//从字符串或原始数据到各种流之间的读写操作 

另外还要注意一下 FileInfo 和 File 类的一些方法,如 Create,CreateText,Open 等,有时也会带来方便。这些类的内容比较繁多,更多内容还请参考MSDN。

另外还要注意一下FileInfo和File类的一些方法,如Create,CreateText,Open等,有时也会带来方便。
这些类的内容比较繁多,更多内容还请参考MSDN。

(1)用于

FileStream//文件流操作 

一些常见的问题及其解决方案

下面是一些常见的问题及其解决方案:
问题1:如何读写文本文件(并考虑不同的编码类型);
解决方案:
创建一个FileStream对象用以引用该文件。要写入文件,将FileStream对象封装在StreamWriter对象中,使用其重载了的Write方法;要读取文件,将FileStream对象封装在StreamReader对象中,使用其Read或ReadLine方法;
.NET Framework允许通过StreamWriter和StreamReader类操作任何流来读写文本文件。当使用StreamWriter类写入数据时,调用它的Write方法,该方法在重载后可以支持所有常见的C#数据类型,包括字符串、字符、整数、浮点数以及十进制数等。但Write方法总会将的得到的数据转换为文本,如果希望将这些文本转换回原来的数据类型,应使用WriteLine方法,以确保每个值都处于单独的一行上。
字符串的表现形式取决于你使用的编码,最常见的编码类型包括下面几种:ASCII,UTF-16,UTF-7,UTF-8。
.NET Framework在System.Text命名空间中为每种编码类型提供了一个类。在使用StreamWriter和StreamReader类时,可以指定需要的编码类型,或者使用默认的UTF-8。
而在读取文本文件时,则要使用StreamReader类的Read或ReadLine方法。Read方法读取单个字符或者指定个数的字符,返回类型为字符或字符数组;ReadLine方法则返回包含整行内容的字符串;ReadToEnd方法从当前位置读取至流的结尾。
(更多内容还请参考MSDN)
写入文本文件的示例:

I/O

StringReader和StringWriter//在字符串中读写字符 

问题 1:如何读写文本文件(并考虑不同的编码类型)

using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
// 创建一个StreamWriter对象,使用UTF-8编码格式
using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8))
{
// 分别写入十进制数,字符串和字符类型的数据
writer.WriteLine(123.45M);
writer.WriteLine("String Data");
writer.WriteLine('A');
}
}

文件的类:

StreamReader和StreamWriter//在流中读写字符 

解决方案:

读取文本文件的示例:

Directory

BufferedStream//为诸如网络流的其它流添加缓冲的一种流类型

创建一个 FileStream 对象用以引用该文件。要写入文件,将 FileStream 对象封装在 StreamWriter 对象中,使用其重载了的 Write 方法;要读取文件,将 FileStream 对象封装在 StreamReader 对象中,使用其 Read 或 ReadLine 方法;

// 以只读模式打开一个文本文件
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
using (StreamReader reader = new StreamReader(fs, Encoding.UTF8))
{
string text = string.Empty;

DirectoryInfo

MemoryStream//无缓冲的流 

.NET Framework 允许通过 StreamWriter 和 StreamReader 类操作任何流来读写文本文件。当使用 StreamWriter 类写入数据时,调用它的 Write 方法,该方法在重载后可以支持所有常见的 C# 数据类型,包括字符串、字符、整数、浮点数以及十进制数等。但 Write 方法总会将的得到的数据转换为文本,如果希望将这些文本转换回原来的数据类型,应使用 WriteLine 方法,以确保每个值都处于单独的一行上。

while(!reader.EndOfStream)
{
text = reader.ReadLine();
txtMessage.Text += text + Environment.NewLine;
}
}
}

File

NetworkStream//互联网络上的流 

字符串的表现形式取决于你使用的编码,最常见的编码类型包括下面几种:ASCII,UTF-16,UTF-7,UTF-8。

问题2:如何读写二进制文件(使用强数据类型);
解决方案:
创建一个FileStream对象用以引用该文件。要写入文件,将FileStream对象封装在BinaryWriter对象中,使用其重载了的Write方法;要读取文件,将FileStream对象封装在BinaryReader对象中,使用相应数据类型的Read方法。
.NET Framework允许通过BinaryWriter和BinaryReader类操作任何流来读写二进制数据。当使用BinaryWriter类写入数据时,调用它的Write方法,该方法在重载后可以支持所有常见的C#数据类型,包括字符串、字符、整数、浮点数以及十进制数等,然后数据会被编码为一系列字节写入文件,也可以配置该过程中的编码类型。
在使用二进制文件时,一定要特别注意其中的数据类型。当你读取数据时,一定要使用BinaryReader类的某种强类型的Read方法。例如,要读取字符串,要使用ReadString方法。(BinaryWriter在写入二进制文件时总会记录字符串的长度以避免任何可能的错误)
写入文件的示例:

FileInfo

//打开文件夹
System.Diagnostics.Process.Start(FilePath);
//打开文件夹中某个文件
System.Diagnostics.Process.Start(FilePath+"/"+FileName);
//打开文件夹并选中单个文件
System.Diagnostics.Process.Start("Explorer", "/select,"+ FilePath+""+FileName);
//或
System.Diagnostics.Process.Start("Explorer.exe", "/select,"+ FilePath+""+FileName);
//用IE打开文件
System.Diagnostics.Process.Start("Explorer",FilePath+""+FileName);
System.Diagnostics.Process.Start("Explorer.exe",FilePath+""+FileName);
//注:(explorer,explorer.exe,select,不区分大小写,"/selecet,"其中"/,"都不能少,FilePath为文件路径不包含文件名)
//打开文件夹并选中网页

.NET Framework 在 System.Text 命名空间中为每种编码类型提供了一个类。在使用 StreamWriter 和 StreamReader 类时,可以指定需要的编码类型,或者使用默认的 UTF-8。

using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
using (BinaryWriter writer = new BinaryWriter(fs))
{
// 写入十进制数,字符串和字符
writer.Write(234.56M);
writer.Write("String");
writer.Write('!');
}
}
读取文件的示例:

FileStream

System.Diagnostics.Process.Start("Explorer.exe", ”); 

而在读取文本文件时,则要使用 StreamReader 类的 Read 或 ReadLine 方法。Read 方法读取单个字符或者指定个数的字符,返回类型为字符或字符数组;ReadLine 方法则返回包含整行内容的字符串;ReadToEnd 方法从当前位置读取至流的结尾。

// 以只读模式打开一个二进制文件
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs))
{
MessageBox.Show("全部数据:" + sr.ReadToEnd());

(2)用于从流读取和写入流的类:

二、目录操作

写入文本文件的示例:

fs.Position = 0;
using (BinaryReader reader = new BinaryReader(fs))
{
// 选用合适的数据类型读取数据
string message = reader.ReadDecimal().ToString() + Environment.NewLine;
message += reader.ReadString() + Environment.NewLine;
message += reader.ReadChar().ToString();
MessageBox.Show(message);
}
}
}
问题3:如何异步读取文件;
解决方案:
有时你需要读取一个文件但又不希望影响程序的执行。常见的情况是读取一个存储在网络驱动器上的文件。
FileStream提供了对异步操作的基本支持,即它的BeginRead和EndRead方法。使用这些方法,可以在.NET Framework线程池提供的线程中读取一个数据块,而无须直接与System.Threading命名空间中的线程类打交道。
采用异步方式读取文件时,可以选择每次读取数据的大小。根据情况的不同,你可能会每次读取很小的数据(比如,你要将数据逐块拷贝至另一个文件),也可能是一个相对较大的数据(比如,在程序逻辑开始之前需要一定数量的数据)。在调用BeginRead时指定要读取数据块的大小,同时传入一个缓冲区(buffer)以存放数据。因为BeginRead和EndRead需要访问很多相同的信息,如FileStream,buffer,数据块大小等,因此将这些内容封装一个单独的类当中是一个好主意。
下面这个类就是一个简单的示例。AsyncProcessor类提供了StartProcess方法,调用它开始读取,每次读取操作结束,OnCompletedRead回调函数会被触发,此时可以处理数据,如果还有剩余数据,则开始一个新的读取操作。默认情况下,AsyncProcessor类每次读取2KB数据。

StreamReader

string[] drives = Directory.GetLogicalDrives();//本地驱动器名称
string path = Directory.GetCurrentDirectory();//获取应用程序的当前工作目录
string[] files = Directory.GetFiles(@"D:Projects");//获取指定目录中的文件名
string[] directories= Directory.GetDirectories(@"D:");//获取指定目录中的目录名
DirectoryInfo di = new DirectoryInfo(@"D:MyDir1");//构造函数创建目录
di.Create();
DirectoryInfo di1 = Directory.CreateDirectory(@"D:MyDir2");//创建对象并创建目录
DirectoryInfo di2 = di.CreateSubdirectory("SubDir");//以相对路径创建子目录

using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
    // 创建一个 StreamWriter 对象,使用 UTF-8 编码格式
    using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8))
    {
        // 分别写入十进制数,字符串和字符类型的数据
        writer.WriteLine(123.45M);
        writer.WriteLine("String Data");
        writer.WriteLine('A');
    }
}

class AsyncProcessor
{
private Stream inputStream;
// 每次读取块的大小
private int bufferSize = 2048;
public int BufferSize
{
get { return bufferSize; }
set { bufferSize = value; }
}
// 容纳接收数据的缓存
private byte[] buffer;
public AsyncProcessor(string fileName)
{
buffer = new byte[bufferSize];
// 打开文件,指定参数为true以提供对异步操作的支持
inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true);
}

StreamWriter

string[] str=Directory.GetFileSystemEntries(@"D:");//获取指定目录中的目录及文件名

读取文本文件的示例:

public void StartProcess()
{
// 开始异步读取文件,填充缓存区
inputStream.BeginRead(buffer, 0, buffer.Length, OnCompletedRead, null);
}
private void OnCompletedRead(IAsyncResult asyncResult)
{
// 已经异步读取一个 块 ,接收数据
int bytesRead = inputStream.EndRead(asyncResult);
// 如果没有读取任何字节,则流已达文件结尾
if (bytesRead > 0)
{
// 暂停以模拟对数据块的处理
Debug.WriteLine(" 异步线程:已读取一块");
Thread.Sleep(TimeSpan.FromMilliseconds(20));

BinaryReader

三、编码转换 

// 以只读模式打开一个文本文件
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
    using (StreamReader reader = new StreamReader(fs, Encoding.UTF8))
    {
        string text = string.Empty;
        
        while(!reader.EndOfStream)
        {
            text = reader.ReadLine();
            txtMessage.Text += text + Environment.NewLine;
        }
    }
}

// 开始读取下一块
inputStream.BeginRead(buffer, 0, buffer.Length, OnCompletedRead, null);
}
else
{
// 结束操作
Debug.WriteLine(" 异步线程:读取文件结束");
inputStream.Close();
}
}
}

BinaryWriter

Encoding e1 = Encoding.Default;//取得本页默认代码 
Byte[] bytes = e1.GetBytes("中国人民解放军"); //转为二进制

问题 2:如何读写二进制文件(使用强数据类型)

使用该类时可以这么写:

通用I/O流类

string str = Encoding.GetEncoding("UTF-8").GetString(bytes); //转回UTF-8编码 

解决方案:

// 开始在另一线程中异步读取文件
AsyncProcessor asyncIO = new AsyncProcessor("test.txt");
asyncIO.StartProcess();

BufferedStream

四、文本文件操作 

创建一个 FileStream 对象用以引用该文件。要写入文件,将 FileStream 对象封装在 BinaryWriter 对象中,使用其重载了的 Write 方法;要读取文件,将 FileStream 对象封装在 BinaryReader 对象中,使用相应数据类型的 Read 方法。

// 在主程序中,做其它事情,这里简单地循环10秒
DateTime startTime = DateTime.Now;
while (DateTime.Now.Subtract(startTime).TotalSeconds < 10)
{
Debug.WriteLine("主程序:正在进行");
// 暂停线程以模拟耗时的操作
Thread.Sleep(TimeSpan.FromMilliseconds(100));
}
Debug.WriteLine("主程序:已完成");

【导入System.IO】

string path = @"f:t.txt";
//创建并写入(将覆盖已有文件)
if (!File.Exists(path))
{
    using (StreamWriter sw = File.CreateText(path))
    {
        sw.WriteLine("Hello");
    }
}
//读取文件
using (StreamReader sr = File.OpenText(path))
{
    string s = "";
    while ((s = sr.ReadLine()) != null)
    {
        Console.WriteLine(s);
    }
}
//删除/拷贝
try
{
    File.Delete(path);
    File.Copy(path, @"f:tt.txt");
}
catch (Exception e)
{
    Console.WriteLine("The process failed: {0}", e.ToString());

.NET Framework 允许通过 BinaryWriter 和 BinaryReader 类操作任何流来读写二进制数据。当使用 BinaryWriter 类写入数据时,调用它的 Write 方法,该方法在重载后可以支持所有常见的 C# 数据类型,包括字符串、字符、整数、浮点数以及十进制数等,然后数据会被编码为一系列字节写入文件,也可以配置该过程中的编码类型。

问题4:如何创建临时文件;
解决方案:
有时需要在特定用户的临时目录下创建一个临时文件,这要求该文件具有唯一的名称,避免与其它程序生成的临时文件相冲突。我们会有多种选择。最简单的是,在程序所在目录内使用GUID或时间戳加上随机值作为文件名称。但Path类提供的方法还是可以为你节省工作量,这就是它的静态GetTempFileName方法,它在当前用户的临时目录下创建一个临时文件(文件名称一定是唯一的),临时目录通常类似于这样:C:Documents and Settings[username]Local SettingsTemp。

==================================DirectoryInfo

在使用二进制文件时,一定要特别注意其中的数据类型。当你读取数据时,一定要使用 BinaryReader 类的某种强类型的 Read 方法。例如,要读取字符串,要使用 ReadString 方法。(BinaryWriter 在写入二进制文件时总会记录字符串的长度以避免任何可能的错误)

string tempFile = Path.GetTempFileName();

:用于复制移动重命名创建删除目录的

五、流文件操作 

写入文件的示例:

using (FileStream fs = new FileStream(tempFile, FileMode.Open))
{
using (BinaryWriter writer = new BinaryWriter(fs))
{
// 写入数据
writer.Write("临时文件信息");
}
}
// Do something
// 最后删除临时文件
File.Delete(tempFile);

【实例方法】

string name = "Test.data";
//打开文件或通过File创建fs = File.Create(path, 1024)
FileStream fs = new FileStream(name, FileMode.CreateNew);
//转换为字节 写入数据(可写入中文)
Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
//字节数组,字节偏移量,最多写入的字节数
fs.Write(info, 0, info.Length);
fs.Close();
//打开文件
fs = new FileStream(name, FileMode.Open, FileAccess.Read);
//读取
BinaryReader r = new BinaryReader(fs);
for (int i = 0; i < 11; i++)
{
    Console.WriteLine(r.ReadInt32());
}

using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
    using (BinaryWriter writer = new BinaryWriter(fs))
    {
        // 写入十进制数,字符串和字符
        writer.Write(234.56M);
        writer.Write("String");
        writer.Write('!');
    }
}

问题5:如何获得随机文件名;
解决方案:
使用Path.GetRandomFileName方法,它与GetTempFileName方法的不同之处在于它仅仅返回一个字符串但不会创建文件。

实例方法需要创建对象

fs.Close(); 

读取文件的示例:

问题6:监视文件系统的变化;
解决方案:
如果指定路径内的文件发生改变(比如文件被修改或创建),你希望能对此作出反应。
如果程序与其它多个程序或业务处理相关,常常需要创建一个程序,并且只有文件系统发生变化时它才处于活动状态。你可以创建一个这样的程序,让它定期区检测指定目录,此时会发现有件事情让你苦恼:检测得越频繁,就会浪费越多的系统资源;而检测得越少,那么检测到变化的时间就会越长。
这时可以使用FileSystemWatcher组件,指定要进行监视的目录或文件,并处理其Created,Deleted,Renamed,Changed事件。
要使用FileSystemWatcher组件,首先要创建它的一个实例,然后设置下列属性:
Path:指定要监视的目录;
Filter:指定要监视的文件类型,如”*.txt”;
NotifyFilter:指定要监视的变化类型;
FileSystemWatcher会引发四个关键的事件:Created,Deleted,Renamed,Changed。这些事件都在其FileSystemEventArgs参数中提供了相关文件的信息:如文件名,路径,改变类型,Renamed事件中还可以了解到改变前的文件名和路径。如果要禁用这些事件,则将它的EnableRaisingEvents属性设置为false。Created,Deleted,Renamed三个事件比较容易处理,但Changed事件就得当心了,你需要设置它的NotifyFilter属性以指示监视那些类型的变化。否则,程序会在文件被修改时淹没在不断发生的事件中(缓存区溢出)。

DirectoryInfo info=new DirectoryInfo(path);

// 以只读模式打开一个二进制文件
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        MessageBox.Show("全部数据:" + sr.ReadToEnd());
        
        fs.Position = 0;
        using (BinaryReader reader = new BinaryReader(fs))
        {
            // 选用合适的数据类型读取数据
            string message = reader.ReadDecimal().ToString() + Environment.NewLine;
            message += reader.ReadString() + Environment.NewLine;
            message += reader.ReadChar().ToString();
            MessageBox.Show(message);
        }
    }
}

// 设置相关属性
watcher.Path = appPath;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
// 添加事件处理函数
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);

info.

问题 3:如何异步读取文件

void OnRenamed(object sender, RenamedEventArgs e)
{
string renamedFormat = "File: {0} 被重命名为 :{1}";
txtChangedInfo.Text = string.Format(renamedFormat, e.OldFullPath, e.FullPath);
}
void OnChanged(object sender, FileSystemEventArgs e)
{
// 显示通知信息
txtChangedInfo.Text = "文件: " + e.FullPath + "发生改变" + Environment.NewLine;
txtChangedInfo.Text += "改变类型: " + e.ChangeType.ToString();
}

方法;

解决方案:

问题7:如何使用独立存储文件;
解决方案:
有时你需要将数据存储在文件中,但对本地硬盘驱动器却没有必要的权限(FileIOPermission)。这时要用到System.IO.IsolatedStorage命名空间中的类,这些类允许你的程序在特定用户的目录下将数据写入文件而不需要直接访问硬盘驱动器的权限:

==================================Directory:

有时你需要读取一个文件但又不希望影响程序的执行。常见的情况是读取一个存储在网络驱动器上的文件。

// 创建当前用户的独立存储
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly())
{
// 创建一个文件夹
store.CreateDirectory("MyFolder");
// 创建一个独立存储文件
using (Stream fs = new IsolatedStorageFileStream("MyFile.txt", FileMode.Create, store))
{
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine("Test Line!");
writer.Flush();
}

用于复制移动重命名创建删除目录的

FileStream 提供了对异步操作的基本支持,即它的 BeginRead 和 EndRead 方法。使用这些方法,可以在 .NET Framework 线程池提供的线程中读取一个数据块,而无须直接与 System.Threading 命名空间中的线程类打交道。

Debug.WriteLine("当前大小:" + store.CurrentSize.ToString() + Environment.NewLine);
Debug.WriteLine("范围:" + store.Scope.ToString() + Environment.NewLine);
string[] files = store.GetFileNames("*.*");
if (files.Length > 0)
{
Debug.WriteLine("当前文件:" + Environment.NewLine);
foreach (string file in files)
{
Debug.WriteLine(file + Environment.NewLine);
}
}
}

【静态方法】

采用异步方式读取文件时,可以选择每次读取数据的大小。根据情况的不同,你可能会每次读取很小的数据(比如,你要将数据逐块拷贝至另一个文件),也可能是一个相对较大的数据(比如,在程序逻辑开始之前需要一定数量的数据)。在调用 BeginRead 时指定要读取数据块的大小,同时传入一个缓冲区(buffer)以存放数据。因为 BeginRead 和 EndRead 需要访问很多相同的信息,如 FileStream,buffer,数据块大小等,因此将这些内容封装一个单独的类当中是一个好主意。

静态方法直接使用类名

下面这个类就是一个简单的示例。AsyncProcessor 类提供了 StartProcess 方法,调用它开始读取,每次读取操作结束,OnCompletedRead 回调函数会被触发,此时可以处理数据,如果还有剩余数据,则开始一个新的读取操作。默认情况下,AsyncProcessor 类每次读取 2KB 数据。

.

写入文件的示例:

方法调用

using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
    using (BinaryWriter writer = new BinaryWriter(fs))
    {
        // 写入十进制数,字符串和字符
        writer.Write(234.56M);
        writer.Write("String");
        writer.Write('!');
    }
}
    
class AsyncProcessor
{
    private Stream inputStream;
    
    // 每次读取块的大小
    private int bufferSize = 2048;
    
    public int BufferSize
    {
        get { return bufferSize; }
        set { bufferSize = value; }
    }
    
    // 容纳接收数据的缓存
    private byte[] buffer;
    
    public AsyncProcessor(string fileName)
    {
        buffer = new byte[bufferSize];
        
        // 打开文件,指定参数为 true 以提供对异步操作的支持
        inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true);
    }
    
    public void StartProcess()
    {
        // 开始异步读取文件,填充缓存区
        inputStream.BeginRead(buffer, 0, buffer.Length, OnCompletedRead, null);
    }
    
    private void OnCompletedRead(IAsyncResult asyncResult)
    {
        // 已经异步读取一个 块 ,接收数据
        int bytesRead = inputStream.EndRead(asyncResult);
        
        // 如果没有读取任何字节,则流已达文件结尾
        if (bytesRead > 0)
        {
            // 暂停以模拟对数据块的处理
            Debug.WriteLine("   异步线程:已读取一块");
            Thread.Sleep(TimeSpan.FromMilliseconds(20));
            
            // 开始读取下一块
            inputStream.BeginRead(buffer, 0, buffer.Length, OnCompletedRead, null);
        }
        else
        {
            // 结束操作
            Debug.WriteLine("   异步线程:读取文件结束");
            inputStream.Close();
        }
    }
}

String path ="E:\C#";

使用该类时可以这么写:

//文件地址

// 开始在另一线程中异步读取文件
AsyncProcessor asyncIO = new AsyncProcessor("test.txt");
asyncIO.StartProcess();

Directory.Exists(path);

// 在主程序中,做其它事情,这里简单地循环 10 秒
DateTime startTime = DateTime.Now;
while (DateTime.Now.Subtract(startTime).TotalSeconds < 10)
{
    Debug.WriteLine("主程序:正在进行");
    // 暂停线程以模拟耗时的操作
    Thread.Sleep(TimeSpan.FromMilliseconds(100));
}

//判断目录是否存在

Debug.WriteLine("主程序:已完成");

Directory.CreateDirectory(path);

问题 4:如何创建临时文件

//创建目录

解决方案:

Directory.GetCreationTime(path).ToLongDateString()

有时需要在特定用户的临时目录下创建一个临时文件,这要求该文件具有唯一的名称,避免与其它程序生成的临时文件相冲突。我们会有多种选择。最简单的是,在程序所在目录内使用 GUID 或时间戳加上随机值作为文件名称。但 Path 类提供的方法还是可以为你节省工作量,这就是它的静态 GetTempFileName 方法,它在当前用户的临时目录下创建一个临时文件(文件名称一定是唯一的),临时目录通常类似于这样:C:Documents and Settings[username]Local SettingsTemp。

string tempFile = Path.GetTempFileName();

//获取目录创建的时间

using (FileStream fs = new FileStream(tempFile, FileMode.Open))
{
    using (BinaryWriter writer = new BinaryWriter(fs))
    {
        // 写入数据
        writer.Write("临时文件信息");
    }
}
   
// 最后删除临时文件
File.Delete(tempFile);

String[]fileNames=Directory.GetFiles(path);//

问题 5:如何获得随机文件名

获取子文件

解决方案:

String[]directoryNames=Directory.GetDirectories(path);//

使用 Path.GetRandomFileName 方法,它与 GetTempFileName 方法的不同之处在于它仅仅返回一个字符串但不会创建文件。

获取子目录

问题 6:监视文件系统的变化

Directory.Delete(path);

解决方案:

//目录删除

如果指定路径内的文件发生改变(比如文件被修改或创建),你希望能对此作出反应。

Directory.GetFileSystemEntries(path);//

如果程序与其它多个程序或业务处理相关,常常需要创建一个程序,并且只有文件系统发生变化时它才处于活动状态。你可以创建一个这样的程序,让它定期区检测指定目录,此时会发现有件事情让你苦恼:检测得越频繁,就会浪费越多的系统资源;而检测得越少,那么检测到变化的时间就会越长。

返回指定目录的所有子目录和文件

这时可以使用 FileSystemWatcher 组件,指定要进行监视的目录或文件,并处理其 Created,Deleted,Renamed,Changed 事件。

Directory.GetCurrentDirectory();//

要使用 FileSystemWatcher 组件,首先要创建它的一个实例,然后设置下列属性:

返回程序当前工作的目录

  • Path:指定要监视的目录;
  • Filter:指定要监视的文件类型,如“*.txt”;
  • NotifyFilter:指定要监视的变化类型;
  • FileSystemWatcher会引发四个关键的事件:Created,Deleted,Renamed,Changed。这些事件都在其 FileSystemEventArgs 参数中提供了相关文件的信息:如文件名,路径,改变类型,Renamed 事件中还可以了解到改变前的文件名和路径。如果要禁用这些事件,则将它的 EnableRaisingEvents 属性设置为 false。Created,Deleted,Renamed 三个事件比较容易处理,但 Changed 事件就得当心了,你需要设置它的 NotifyFilter 属性以指示监视那些类型的变化。否则,程序会在文件被修改时淹没在不断发生的事件中(缓存区溢出)。

Directory.GetLastAccessTime(path);//

// 设置相关属性
watcher.Path = appPath;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
   
// 添加事件处理函数
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
    
    
void OnRenamed(object sender, RenamedEventArgs e)
{
    string renamedFormat = "File: {0} 被重命名为 :{1}";
    txtChangedInfo.Text = string.Format(renamedFormat, e.OldFullPath, e.FullPath);
}

返回最后访问时间

void OnChanged(object sender, FileSystemEventArgs e)
{
    // 显示通知信息
    txtChangedInfo.Text = "文件: " + e.FullPath + "发生改变" + Environment.NewLine;
    txtChangedInfo.Text += "改变类型: " + e.ChangeType.ToString();
}

Directory.GetLastWriteTime(path);//

问题 7:如何使用独立存储文件

返回最后修改时间

解决方案:

Directory.GetParent(path);//

有时你需要将数据存储在文件中,但对本地硬盘驱动器却没有必要的权限(FileIOPermission)。这时要用到 System.IO.IsolatedStorage 命名空间中的类,这些类允许你的程序在特定用户的目录下将数据写入文件而不需要直接访问硬盘驱动器的权限。

返回指定目录的父目录

// 创建当前用户的独立存储
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly())
{
    // 创建一个文件夹
    store.CreateDirectory("MyFolder");
    
    // 创建一个独立存储文件
    using (Stream fs = new IsolatedStorageFileStream("MyFile.txt", FileMode.Create, store))
    {
        StreamWriter writer = new StreamWriter(fs);
        writer.WriteLine("Test Line!");
        writer.Flush();
    }
    
    Debug.WriteLine("当前大小:" + store.CurrentSize.ToString() + Environment.NewLine);
    Debug.WriteLine("范围:" + store.Scope.ToString() + Environment.NewLine);
    string[] files = store.GetFileNames("*.*");
    if (files.Length > 0)
    {
        Debug.WriteLine("当前文件:" + Environment.NewLine);
        foreach (string file in files)
        {
            Debug.WriteLine(file + Environment.NewLine);
        }
    }
}

Directory.Move(要移动的目录,指定目录);//

将目录移动到指定位置

Directory.SetCreationTime(path,日期);

//设置创建日期

Directory.SetCurrentDirectory(path);//

将工作目录设置为指定目录

Directory.SetLastWriteTime(path,时间);//设置最后修改时间

=======================================================FileInfo

:用于创建,复制,删除,移动文件的实例方法实例方法需要创建对象

FileInfo

info=new

FileInfo(path);

info.

方法;

=======================================================File

用于创建,复制,删除,移动文件的静态方法,静态方法直接使用类名

.

方法调用

File.方法

File.AppendAllText(path,"",Encoding.Default);//

将指定字符串追加到文件中若文件不存在则创建文件

File.WriteAllText(path,"",Encoding.Default);

//创建新文件并写入内容,然后关闭该文件,目标

文件已存在时覆盖该文件

String[] a=File.ReadAllLines(path,Encoding.Default);//

打开文件并将所有行读入一个字符串,然后关闭该文件

File.OpenRead(path);

//打开指定文件进行读取

【Encoding.Default】

:编码方式

==================================================FileStream

(文件流)

:主要用于

使用二进制方式读写文件数据,可读取任何文件

创建FileStream对象

FileStream

stream=new

FileStream(文件路径,FileMode.Append,FileAccess.ReadWrite,FileShare.None);

//创建FileStream对象

【FileMode】

:指定系统打开文件的方式

FileStream

(CreateNew创建新文件,Creat创建新文件,如果存在则覆盖,Open打开现有文件,

OpenOrcreate打开文件,不存在则创建,Append打开文件查找到文件尾,Truncate

打开文件并清除内容)

【FileAccess】

:指定文件的访问方式(

Read只读,

write只写,

readwrite读写)

【FileShare】

控制其他

FileStream

对象对此文件的访问权(none不共享,read

允许随后打开文件并读取,write允许写入,

readwrite允许读写)

例:

FileStreamReader=new

FileStream(path,FileMode.Append,FileAccess.ReadWrite,FileShare.None);//

创建FileStream对象

//读取数据

byte[] aa=new

byte[Reader.Length];

Reader.Read(aa,0,aa.Length);

//将文件中数据读入byte数组aa

Reader.Flush();

Reader.Close();

//

写入数据

FileStreamWrite=new

FileStream(path,FileMode.Append,FileAccess.ReadWrite,FileShare.None);//

创建

FileStream对象

Write.Write(aa,0,aa.Length);

//从aa中取出数据写入文件

Write.Flush();

Write.Close();

 

Reader.ReadByte();//读取一个字节

reader.Position=6;//绝对定位

Reader.Seek(0,SeekOrigin.Begin);////相对定位

Write.WriteByte(字节);//将一个字节写入当前流

================================================================BufferedStream

:为Stream对象提供缓存,减少IO次数,提高读写效率

BufferedStreamreader=newBufferedStream(Stream对象);

================================================================StreamReader

:以一种特定的编码从字节流中读取字符

================================================================StreamWriter

:以一种特定的编码向字节流中写入字符//创建流先创建

Filestream对象

FileStreamfose=newFileStream("e:\",FileMode.Append,FileAccess.Read,FileShare.Delete);

根据FileStream对象创建StreamReader或StreamWriter对象

StreamReaderreader=newStreamReader(fose,Encoding.Default);

FileStreamfos=newFile Stream(path,FileMode.Create,FileAccess.Read,FileShare.Inheritable);

StreamWriterwrite=new StreamWriter(fos,Encoding.Default);

int data;

data=reader.Read();//一个一个读取

char[] c=new char[1];

reader.ReadBlock(c,0,c.Length);//将读取的字符放入

char数组String  qq=reader.ReadLine();//

读取一行数据 reader.ReadToEnd();//从当前位置读到结尾

writer.Write((char)data);//写入Char型数据

writer.Write(datas,0,len);//写入数组中的指定元素

writer.WriteLine(datas);//写入后换行

write.Write(数据类型);//写入数据,可以是任何基本数据类型

本文由10bet手机官网发布于多线程,转载请注明出处:文件读写相关技术介绍,O常见操作汇总

上一篇:改变文件的创建,轻松读取 下一篇:轻松读取和设置文件属性,文件操作大全
猜你喜欢
热门排行
精彩图文