第十八章 数据访问(In .net4.5) 之 I/O操作

1. 概述

  本章内容包括 文件操作、流操作、读写网络数据 以及 异步I/O操作。

2. 主要内容

  2.1 文件操作

    ① 使用 Drive 和 DriveInfo 访问磁盘信息。

DriveInfo[] drivesInfo = DriveInfo.GetDrives(); 
 
foreach (DriveInfo driveInfo in drivesInfo) 
{ 
    Console.WriteLine(“Drive {0}”, driveInfo.Name); 
    Console.WriteLine(“  File type: {0}”, driveInfo.DriveType); 
 
    if (driveInfo.IsReady == true) 
    { 
        Console.WriteLine(“  Volume label: {0}”, driveInfo.VolumeLabel); 
        Console.WriteLine(“  File system: {0}”, driveInfo.DriveFormat); 
        Console.WriteLine( 
            “  Available space to current user:{015} bytes”, 
            driveInfo.AvailableFreeSpace); 
 
        Console.WriteLine( 
            “  Total available space:          {015} bytes”, 
            driveInfo.TotalFreeSpace); 
 
        Console.WriteLine( 
            “  Total size of drive:            {015} bytes “, 
            driveInfo.TotalSize); 
    } 
}

    ② 可以使用 DictionaryInfo 和 Dictionary 来操作目录信息。

var directory = Directory.CreateDirectory(@”C:\Temp\ProgrammingInCSharp\Directory”);
var directoryInfo = new DirectoryInfo(@”C:\Temp\ProgrammingInCSharp\DirectoryInfo”); 
directoryInfo.Create();

    *使用DictionarySecurity可以操作目录权限。

DirectoryInfo directoryInfo = new DirectoryInfo(“TestDirectory”); 
directoryInfo.Create(); 
DirectorySecurity directorySecurity = directoryInfo.GetAccessControl(); 
directorySecurity.AddAccessRule( 
            new FileSystemAccessRule(“everyone”,  
                                     FileSystemRights.ReadAndExecute,  
                                     AccessControlType.Allow)); 
directoryInfo.SetAccessControl(directorySecurity);

    *使用 EnumerateDirectories 代替  GetDirectories,会更有效率。

    ③ 可以使用 File 和 FileInfo 来操作文件信息。

string path = @”c:\temp\test.txt”; 
 
if (File.Exists(path)) 
{ 
    File.Delete(path); 
} 
 
FileInfo fileInfo new FileInfo(path); 
 
if (fileInfo.Exists) 
{ 
    fileInfo.Delete(); 
}

    ④ 可以使用 Path 类来操作路径信息。

string folder = @”C:\temp”; 
string fileName = “test.dat”; 
string fullPath = Path.Combine(folder, fileName); // Results in C:\\temp\\test.dat

    *使用 Path 类 还可以实现使用临时文件来保存信息( GetRandomFileName, GetTempPath, GetTempFileName)

  2.2 流操作

    ① Stream基类

    ② 编码和解码

      编码解码是在字符与字节间的转换操作。

      .net平台提供的编码格式包括:UTF-8, ASCII, BigEndianUnicode, Unicode, UTF32 和 UTF7.

      使用File类的CreateText、OpenRead、OpenText方法,可以通过返回的StreamWriter、FileStream、StreamReader类,用默认编码的方式快捷的进行转换操作。

    ③ 使用各种类型的流

      使用GZipStream压缩数据

string folder = @»c:\temp»; 
string uncompressedFilePath = Path.Combine(folder, “uncompressed.dat”); 
string compressedFilePath = Path.Combine(folder, “compressed.gz”); 
byte[] dataToCompress = Enumerable.Repeat((byte)’a’, 1024 * 1024).ToArray();
using (FileStream uncompressedFileStream = File.Create(uncompressedFilePath)) 
{ 
    uncompressedFileStream.Write(dataToCompress, 0, dataToCompress.Length); 
} 
using (FileStream compressedFileStream = File.Create(compressedFilePath)) 
{ 
    using (GZipStream compressionStream = new GZipStream( 
                compressedFileStream, CompressionMode.Compress)) 
    { 
        compressionStream.Write(dataToCompress, 0, dataToCompress.Length); 
    } 
} 
 
FileInfo uncompressedFile new FileInfo(uncompressedFilePath); 
FileInfo compressedFile new FileInfo(compressedFilePath); 
 
Console.WriteLine(uncompressedFile.Length); // Displays 1048576 
Console.WriteLine(compressedFile.Length); // Displays 1052

      使用  BufferedStream 一次读写大块数据(通过内存中的缓冲区读写数据,半阻塞式)

string path = @»c:\temp\bufferedStream.txt»; 
 
using (FileStream fileStream = File.Create(path)) 
{ 
    using (BufferedStream bufferedStream = new BufferedStream(fileStream)) 
    { 
        using (StreamWriter streamWriter = new StreamWriter(bufferedStream)) 
        { 
            streamWriter.WriteLine(«A line of text.»); 
        } 
    } 
}

  * 现代操作系统是一个多线程的环境,在其上执行文件操作时(File.Exists不一定可靠),实现完善的异常处理机制是很有必要的。

string path = @”C:\temp\test.txt”; 
 
try 
{ 
    return File.ReadAllText(path); 
} 
catch (DirectoryNotFoundException) { } 
catch (FileNotFoundException) { }
return string.Empty;

  2.3 网络通信

    ① WebRequest 和 WebResponse

WebRequest request = WebRequest.Create(“http://www.microsoft.com”); 
WebResponse response = request.GetResponse(); 
 
StreamReader responseStream new StreamReader(response.GetResponseStream()); 
string responseText = responseStream.ReadToEnd(); 
 
Console.WriteLine(responseText); // Displays the HTML of the website 
 
response.Close();

  2.4 异步I/O操作

    ① Async/await

public  async Task CreateAndWriteAsyncToFile() 
{ 
    using (FileStream stream = new FileStream(“test.dat”, FileMode.Create,  
        FileAccess.Write, FileShare.None, 4096true)) 
    { 
        byte[] data = new byte[100000]; 
        new Random().NextBytes(data); 
 
        await stream.WriteAsync(data, 0, data.Length); 
    } 
}
public async Task ReadAsyncHttpRequest() 
{ 
    HttpClient client new HttpClient(); 
    string result = await client.GetStringAsync(“http://www.microsoft.com”); 
}

    ② 并行操作(Parallel)

public async Task ExecuteMultipleRequestsInParallel() 
{ 
    HttpClient client new HttpClient(); 
 
    Task microsoft = client.GetStringAsync(“http://www.microsoft.com”); 
    Task msdn =  client.GetStringAsync(“http://msdn.microsoft.com”); 
    Task blogs = client.GetStringAsync(“http://blogs.msdn.com/”); 
 
    await Task.WhenAll(microsoft, msdn, blogs); //相比使用三个await更高效
}

3. 总结

  ① 使用 Drive 和 DriveInfo 操作磁盘。

  ② 使用Dictionary 和 DictionaryInfo 操作文件夹。

  ③ 使用 File 和 FileInfo 操作文件。

  ④ 使用 Path 类来操作路径信息。

  ⑤ 流是对一组字节的抽象。

  ⑥ 时刻谨记文件系统是可以同时被多用户操作的。

  ⑦ 使用WebRequest 和 WebResponse 来进行网络请求操作。

  ⑧ 异步I/O操作可以提升用户体验和程序的可靠性。

    

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。