Web开发之C#:(9)C#常用类库3:文件操作类

作者:陆金龙    发表时间:2016-07-21 00:37   


3.文件操作类

3.1Path(静态类)

命名空间:System.IO.Path

定义:public static class Path

说明:

1)Path 类的大多数成员不与文件系统交互,并且不验证路径字符串指定的文件是否存在。

2)Path 类的成员可快速方便地执行如确定文件扩展名是否是路径的一部分、将两个字符串组合成一个路径名的操作。

3)Path 类的所有成员都是静态的,因此无需创建实例即可访问。

3.1.1Path类的重要方法

1)Path.ChangeExtension() 方法

定义:public static string ChangeExtension(string path,string extension)

说明:(基于Windows桌面平台上)

如果 path 是 null 或空字符串 (""),则返回的路径信息是未修改的。

如果 extension是null,则返回的字符串包含指定的路径,扩展名已移除。

如果 path 没有扩展名,且 extension 不是 null,则以extension为扩展名。

示例:

string file = @"E:\备份文件\资源\美女图片\img";

file = Path.ChangeExtension(file, "mp3");

Console.WriteLine(file);

运行以上代码块将输出:E:\备份文件\资源\美女图片\img.mp3

2)Path.Combine() 方法

定义:public static string Combine(string path1,string path2)

说明:

如果 path2 不包括根,则结果是两个路径的串联,两者间含有分隔符。

如果 path2 包括根(以分隔符或驱动器规格起始),则返回 path2。

示例:

string path = @"E:\备份文件\资源\美女图片\img.jpg";

string file = Path.Combine(path, @"04.jpg");

运行以上代码块file的值:E:\备份文件\资源\美女图片\img.jpg\04.jpg

string path = @"E:\备份文件\资源\美女图片\img.jpg";

string file = Path.Combine(path, @"d:\04.jpg");

运行以上代码块file的值:d:\04.jpg

string path = @"E:\备份文件\资源\美女图片\img.jpg";

string file = Path.Combine(path, @"\04.jpg");

运行以上代码块file的值:\04.jpg

3)Path.GetDirectoryName() 方法

定义:public static string GetDirectoryName(string path)

说明:

每次调用时截断最后一个文件夹级别,丢弃后面的部分。

如果路径由根目录组成,如“c:\”,则返回 null。

示例:

Path.GetDirectoryName("E:\备份文件\资源\美女图片\img.jpg");

得到:"E:\备份文件\资源\美女图片"

Path.GetDirectoryName('C:\mydir\myfile.ext')  

得到'C:\mydir'

Path .GetDirectoryName('C:\mydir\')  

得到'C:\mydir'

4)Path.GetFullPath() 方法

定义:public static string GetFullPath(string path)

说明:

相当于将与程序运行目录(或当前卷)与path做了一个Combine

path路径不以\开头,则用程序运行目录拼接

path路径以\开头,则用当前卷(如:D:\)拼接

 

示例:

string fupath = Path.GetFullPath("abc.txt");   

得到:D:\MyDocuments\Visual Studio2010\Projects\Path\Path\bin\Debug\abc.txt

string fupath1 = Path.GetFullPath("\mydir");   

得到:D:\mydir

3.2 Directory(静态类)

实现搜索功能,返回字符串数组。

3.2.1Directory.GetDirectories()方法

获取文件夹路径(不包含文件)

3.2.2Directory.GetFiles()方法

获取文件路径(不包含文件夹)

Directory类方法递归遍历文件夹和文件

示例:获取所有(如*.cs)文件路径

static void Main(string[] args)

{

string path = @"C:\Documents and Settings\蒋坤\桌面\file";

string search = "*.cs";

List<string> list = new List<string>();

list.AddRange(Directory.GetFiles(path, "*.cs"));

GetFilees(path, list);

File.WriteAllLines("search.log", list.ToArray());

}

 

private static void GetFilees(string path, List<string> list)

{

// 得到路径下的文件夹

string[] ps = Directory.GetDirectories(path);

// 遍历文件夹

for (int i = 0; i < ps.Length; i )

{

//得到ps[i]路径的cs文件

list.AddRange(Directory.GetFiles(ps[i], "*.cs"));

  //递归调用本方法搜索子文件夹

GetFilees(ps[i], list);

}

}

3.2.3方法汇总

CreateDirectory(String) 在指定路径创建所有目录和子目录。
CreateDirectory(String, DirectorySecurity) 创建指定路径中的所有目录,并应用指定的 Windows 安全性。
Delete(String) 从指定路径删除空目录。
Delete(String, Boolean) 删除指定的目录并(如果指示)删除该目录中的所有子目录和文件。
Exists(String)确定给定路径是否引用磁盘上的现有目录。

 

GetDirectories(String) 获取指定目录中的子目录的名称(包括其路径)。
GetDirectories(String, String) 在当前目录获取与指定搜索模式匹配的子目录的名称(包括它们的路径)。
GetDirectories(String, String, SearchOption) 获取与在当前目录中的指定搜索模式相匹配的子目录(包括其路径)的名称,并且可以搜索子目录。
GetDirectoryRoot 返回指定路径的卷信息、根信息或两者同时返回。
GetFiles(String) 返回指定目录中文件的名称(包括其路径)。
GetFiles(String, String) 返回指定目录中与指定的搜索模式匹配的文件的名称(包含它们的路径)。
GetFiles(String, String, SearchOption) 返回指定目录中与指定的搜索模式匹配的文件的名称(包含它们的路径),并使用一个值以确定是否搜索子目录。

 

GetFileSystemEntries(String) 返回指定目录中所有文件和子目录的名称。
GetFileSystemEntries(String, String) 返回与指定搜索条件匹配的文件系统项的数组。
GetFileSystemEntries(String, String, SearchOption) 获取指定路径中与搜索模式匹配的所有文件名称和目录名称的数组,还可以搜索子目录。

 

EnumerateDirectories(String) 返回指定路径中的目录名称的可枚举集合。
EnumerateDirectories(String, String) 返回指定路径中与搜索模式匹配的目录名称的可枚举集合。
EnumerateDirectories(String, String, SearchOption) 返回指定路径中与搜索模式匹配的目录名称的可枚举集合,还可以搜索子目录。
EnumerateFiles(String)     返回指定路径中的文件名的可枚举集合。
EnumerateFiles(String, String)     返回指定路径中与搜索模式匹配的文件名称的可枚举集合。
EnumerateFiles(String, String, SearchOption) 返回指定路径中与搜索模式匹配的文件名称的可枚举集合,还可以搜索子目录。
EnumerateFileSystemEntries(String) 返回指定路径中的文件系统项的可枚举集合。
EnumerateFileSystemEntries(String, String) 返回指定路径中与搜索模式匹配的文件系统项的可枚举集合。
EnumerateFileSystemEntries(String, String, SearchOption) 返回指定路径中与搜索模式匹配的文件名称和目录名称的可枚举集合,还可以搜索子目录。

GetAccessControl(String) 获取一个 DirectorySecurity 对象,该对象封装指定目录的访问控制列表 (ACL) 项。
GetAccessControl(String, AccessControlSections) 获取一个 DirectorySecurity 对象,它封装指定目录的指定类型的访问控制列表 (ACL) 项。
GetCreationTime 获取目录的创建日期和时间。
GetCreationTimeUtc 获取目录创建的日期和时间,其格式为协调通用时间 (UTC)。
GetCurrentDirectory 获取应用程序的当前工作目录。
GetLastAccessTime 返回上次访问指定文件或目录的日期和时间。
GetLastAccessTimeUtc 返回上次访问指定文件或目录的日期和时间,其格式为协调通用时间 (UTC)。
GetLastWriteTime 返回上次写入指定文件或目录的日期和时间。
GetLastWriteTimeUtc 返回上次写入指定文件或目录的日期和时间,其格式为协调通用时间 (UTC)。
GetLogicalDrives 检索此计算机上格式为"<驱动器号>:\"的逻辑驱动器的名称。
GetParent 检索指定路径的父目录,包括绝对路径和相对路径。
Move 将文件或目录及其内容移到新位置。
SetAccessControl 将 DirectorySecurity 对象描述的访问控制列表 (ACL) 项应用于指定的目录。
SetCreationTime 为指定的文件或目录设置创建日期和时间。
SetCreationTimeUtc 设置指定文件或目录的创建日期和时间,其格式为协调通用时间 (UTC)。
SetCurrentDirectory 将应用程序的当前工作目录设置为指定的目录。
SetLastAccessTime 设置上次访问指定文件或目录的日期和时间。
SetLastAccessTimeUtc 设置上次访问指定文件或目录的日期和时间,其格式为协调通用时间 (UTC)。
SetLastWriteTime 设置上次写入目录的日期和时间。
SetLastWriteTimeUtc 设置上次写入某个目录的日期和时间,其格式为协调通用时间 (UTC)。

3.3File类(静态类)

3.3.1读写

每次使用,都会打开文件,使用完毕,会关闭文件。

适用于一次性读写一个文件,所以常用方法都是AllLines/AllText。

像词典数据,一次性读入,就用File类的ReadLines方法就行了。

ReadAllTextReadAllLines

WriteAllTextWriteAllLines

AppendAllText

3.3.2文件操作

File.CreateText(path) 创建或打开一个文件用于写入 UTF-8编码的文本,可得到流并能进行操作

File.OpenText(path) 打开现有 UTF-8 编码文本文件以进行读取,可以得到流

File. Move (path, path2)

File.Copy(path, path2)

File.Delete(path2)

File.Exists(path)  判断文件是否存在,返回bool值

应用实例:

class Test

{

    public static void Main()

    {

        string path = @"c:\temp\MyTest.txt";

        if (!File.Exists(path))

        {

            // Create a file to write to.

            using (StreamWriter sw = File.CreateText(path))

            {

                sw.WriteLine("Hello");

                sw.WriteLine("Welcome");

            }

        }

        // Open the file to read from.

        using (StreamReader sr = File.OpenText(path))

        {

            string s = "";

            while ((s = sr.ReadLine()) != null)

            {

                Console.WriteLine(s);

            }

        }

        try

        {

            string path2 = path "temp";

            // Ensure that the target does not exist.

            File.Delete(path2);

 

            // Copy the file.

            File.Copy(path, path2);

            Console.WriteLine("{0} was copied to {1}.", path, path2);

 

            // Delete the newly created file.

            File.Delete(path2);

            Console.WriteLine("{0} was successfully deleted.", path2);

        }

        catch (Exception e)

        {

            Console.WriteLine("The process failed: {0}", e.ToString());

        }

    }

}

 

3.4Stream 类

定义:public abstract class Stream : MarshalByRefObject, IDisposable

说明:流是字节序列的抽象概念,例如文件、输入/输出设备、内部进程通信管道或者 TCP/IP 套接字。

基本操作:

读取流。读取是从流到数据结构(如字节数组)的数据传输。

写入流。写入是从数据结构到流的数据传输。

流支持查找。查找是对流内的当前位置进行查询和修改。

3.4.1FileStream 类

定义:public class FileStream : Stream

说明:

使用 FileStream 类对文件系统上的文件进行读取、写入、打开和关闭操作。

FileStream 对输入输出进行缓冲,从而提高性能。(文件大时,分多次操作)

请确保对所有 FileStream 对象调用 Dispose 方法。

比较:

MemoryStream 类通过字节数组创建流,而且功能与 FileStream 类似。

FileStream 重要方法

FileStream.ReadByte()和FileStream.WriteByte() 读写单个字节(得到和写入int值)

FileStream.Read()和FileStream.Write(),读写字节数组(字符串需转化成字节数组)

可以一次性操作一个字节数组,而不是一个一个读写字节。

1) FileStream.ReadByte() 每次从文件读取一个字节

// 以下代码读取文件前三个字节(每个汉字占两个字节,遇到汉字分两次读取)

FileStream file = new FileStream(@"作业.txt", FileMode.Open, FileAccess.Read);

int text = file.ReadByte();

Console.WriteLine(text);

text = file.ReadByte();

Console.WriteLine(text);

text = file.ReadByte();

Console.WriteLine(text);

file.Close();

file.Dispose();

2) FileStream.WriteByte() 每次向文件写入一个字节

//如果要写汉字,每字分两次写,要提供该字前后两个字节对应的int值

FileStream file0 = new FileStream("abc.txt", FileMode.Create, FileAccess.Write);

file0.WriteByte(97);

file0.WriteByte((byte)'a');

file0.WriteByte((byte)'b');

file0.WriteByte((byte)'c');

string str = "Helloautoman,you are very brave,i like you !";

for (int i = 0; i < str.Length; i )

{

//字符串还是要转换成一个个字节来写

file0.WriteByte((byte)str[i]);

}

//以下两行写入汉字"和"(要知道186和205才行,很麻烦)

file0.WriteByte(186);

file0.WriteByte(205);

3) FileStream.Read()方法,每次从文件读取一个字节数组

byte[] bt = new byte[500];

FileStream f1 = new FileStream("file1.txt", FileMode.Open, FileAccess.Read);

int count =f1.Read(bt1, 0, bt1.Length);

count为返回缓冲区中的总字节数,读到文件结束(流的末尾),就返回-1。

4)FileStream.Write()方法,每次向文件写入一个字节数组

FileStream f2 = new FileStream("file2.txt", FileMode.Create, FileAccess.Write);

f2.Write(bt1, 0, bt1.Length);

以上通过FileStream.Read()、FileStream.Write()和字节数组实现文件复制功能。

附:Encoding 类, 专门针对字符集编码,从字符串获得字节数组

//从字符串获取字节数组 Encoding类的UTF8.GetBytes() 方法

byte[ ] bt1 = Encoding.UTF8.GetBytes("我是一个字符串");

byte[ ] bt2 = Encoding.GetEncoding("GB2312").GetBytes("字符串");

5) FileStream.Seek()方法设定文件指针的位置

有两个参数:第一参数规定文件指针以字节为单位移动的距离,负值表示向前查找;第二个参数规定开始计算的位置,用 SeekOrigin 枚举的一个值表示: SeekOrigin 有三个值:Begin  Current   End。

aFile.Seek(8,SeekOrigin.Begin);将文件的指针移动到第8个字节,起始位置是第1个字节。

aFile.Seek(-5,SeekOrigin.End); 从文件的末尾向前查找五个字节。

aFile.Seek(2,SeekOrigin.Current);

aFile.Seek(0,SeekOrigin.Begin) ---文件的起始位置

aFile.Read();

读入缓冲区中的总字节数。如果当前的字节数没有所请求那么多,则总字节数可能小于所请求的字节数;或者如果已到达流的末尾,则为零。

3.4.2FileStream 类应用

//FileStream 构造函数的用法

public static void Main()

{

string path = @"c:\temp\MyTest.txt";

// Delete the file if it exists.

if (File.Exists(path))

{

    File.Delete(path);

 }

//Create the file.

using (FileStream fs = File.Create(path))

{

    AddText(fs, "This is some text");

    AddText(fs, "This is some more text,");

    AddText(fs, "\r\nand this is on a new line");

    AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");

    for (int i=1;i < 120;i )

    {

        AddText(fs, Convert.ToChar(i).ToString());

        //Split the output at every 10th character.

        if (Math.IEEERemainder(Convert.ToDouble(i), 10) == 0)

        {

            AddText(fs, "\r\n");

        }

    }

 }

 //Open the stream and read it back.

 using (FileStream fs = File.OpenRead(path))

{

     byte[] b = new byte[1024];

     UTF8Encoding temp = new UTF8Encoding(true);

     while (fs.Read(b,0,b.Length) > 0)

     {

         Console.WriteLine(temp.GetString(b));

     }

  }

}

private static void AddText(FileStream fs, string value)

{

byte[] info = new UTF8Encoding(true).GetBytes(value);

fs.Write(info, 0, info.Length);

}

//打开一个文件(如果文件不存在则创建该文件)并将信息追加到文件末尾。

public static void Main()

{

FileStream fs=new FileStream("c:\\Variables.txt", FileMode.Append, FileAccess.Write, FileShare.Write);

fs.Close();

StreamWriter writer=new StreamWriter("c:\\Variables.txt", true, Encoding.ASCII);

string NextLine="This is the appended line.";

writer.Write(NextLine);

writer.Close();

}

3.5StreamReader类和 StreamWriter 类

引子:FileStream几乎用得少,StreamReader和StreamWriter用得多。

适用于需要多次(特别是循环)操作同一个文件的情况。

对一个文件需要进行多次读写操作的,创建这两个类的对象,打开文件后,在进行多次读写过程中,文件始终处于就绪状态,直到调用对象的Close()方法才同时关闭文件。

对数据库文件中频繁读写数据,一般用StreamReader和StreamWriter,避免多次打开关闭数据库。

除非另外指定,StreamReader 的默认编码为 UTF-8,而不是当前系统的 ANSI 代码页。

UTF-8 可以正确处理 Unicode 字符并在操作系统的本地化版本上提供一致的结果。

3.5.1 StreamReader类读字符串

System.IO. StreamReader

实现一个TextReader,使其以一种特定的编码从字节流中读取字符。

StreamReader旨在以一种特定的编码输入字符,用来读取标准文本文件的各行信息。

1)StreamReader.Read () 方法

读取输入流中的下一个字符或下一组字符。

返回:Int32对象,输入流中的下一个字符。如果不再有可用的字符,则为 -1。

public override int Read()

读取输入流中的下一个字符并使该字符的位置提升一个字符。

public override int Read(char[] buffer,int index,int count)

从 index 开始,从当前流中将最多的 count 个字符读入 buffer。

public static void Main()

{

 string path = @"MyTest.txt";

try

{

if (File.Exists(path))

{

File.Delete(path);

}

using (StreamWriter sw = new StreamWriter(path))

{

sw.WriteLine("This");

sw.WriteLine("is some text");

}

 

using (StreamReader sr = new StreamReader(path))

{

char[] c = null;

//StreamReader.Peek()方法

//返回下一个可用的字符,但不使用它。

//表示下一个要读取的字符的整数;如果没有更多可读取的字符或该流不支持查找,则为 -1。

while (sr.Peek() >= 0)

{

c = new char[5];

sr.Read(c, 0, c.Length);

Console.WriteLine(c);

}

}

}

catch (Exception e)

{

Console.WriteLine("The process failed: {0}", e.ToString());

}

}

}

2)StreamReader.ReadLine()方法

从当前流中读取一行字符并将数据作为字符串返回。

返回:字符串输入流中的下一行;如果到达了输入流的末尾,则为 null。

public static void Main()

{

try

{

  // Create an instance of StreamReader to read from a file.

  // The using statement also closes the StreamReader.

  using (StreamReader sr = new StreamReader("TestFile.txt"))

  {

       string line;

       // Read and display lines from the file until the end of

       // the file is reached.

       while ((line = sr.ReadLine()) != null)

       {

            Console.WriteLine(line);

       }

}

}

catch (Exception e)

{

// Let the user know what went wrong.

Console.WriteLine("The file could not be read:");

Console.WriteLine(e.Message);

}

}

3)StreamReader.ReadToEnd()方法

返回:字符串,流的其余部分(从当前位置到末尾)。

如果当前位置位于流的末尾,则返回空字符串 ("")。

public static void Main()

{

string path = @"c:\temp\MyTest.txt";

try

{

if (File.Exists(path))

{

File.Delete(path);

    }

// 不加Encoding.Default,默认为UTF8

using (StreamWriter sw = new StreamWriter(path,Encoding.Default))

    {

sw.WriteLine("This");

sw.WriteLine("is some text");

}

using (StreamReader sr = new StreamReader(path))

    {

//This allows you to do one Read operation.

Console.WriteLine(sr.ReadToEnd());

    }

}

catch (Exception e)

{

Console.WriteLine("The process failed: {0}", e.ToString());

}

}

3.5.2 StreamWriter类写字符串

1)StreamWriter. Write()方法

2)StreamWriter. WriteLine()方法