在實際的項目開發中,我們經常需要使用到文件的I/O操作,主要包含對文件的增改刪查等操作,這些基本的操作我們都是很熟悉,但是較少的人去考慮文件的安全和操作的管理等方面,例如文件的訪問權限管理,文件數據的徹底刪除和數據的恢復等等,這一系列的操作需要我們對.NET的相關知識有一個深刻的學習。
在本文章主要介紹文件和目錄的一些基本操作,以及文件目錄的權限和安全設置的相關內容。
提到文件的I/O操作,這個對於每一個開發者來說都不是陌生的事,因為這些操作是我們在項目開發過程中經常使用到的一些操作。那麼在.NET中操作文件的類在System.IO命名空間下,一下介紹一下常見的I/O操作類:
DiveInfo:提供了對邏輯磁盤的基本信息訪問的途徑。(只能查看信息,不能做任何修改。)
System.Environment:用來枚舉驅動器。(不能獲取驅動器的屬性)
System.Management:.NET針對WMI調用。
Directory和DircetoryInfo:用於操作目錄。(前者為靜態類,後者則須在實例化後調用,功能上相同)
File和FileInfo:用於操作文件。(前者為靜態類,後者須實例化後調用,功能上相同)
以上介紹了一些文件的基本操作類,本次主要講解目錄和文件操作,一下給出文件和目錄操作的一些基本方法:
/// <summary>
/// 寫文件
/// </summary>
/// <param name="fileName">文件名</param>
/// <param name="content">文件內容</param>
/// <param name="encoding">指定文件編碼</param>
protected void Write_Txt(string fileName, string content, string encoding)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException(fileName);
}
if (string.IsNullOrEmpty(content))
{
throw new ArgumentNullException(content);
}
if (string.IsNullOrEmpty(encoding))
{
throw new ArgumentNullException(encoding);
}
var code = Encoding.GetEncoding(encoding);
var htmlfilename = HttpContext.Current.Server.MapPath("Precious\\" + fileName + ".txt");
var str = content;
var sw = StreamWriter.Null;
try
{
using (sw = new StreamWriter(htmlfilename, false, code))
{
sw.Write(str);
sw.Flush();
}
}
catch (IOException ioex)
{
throw new IOException(ioex.Message);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
sw.Close();
}
}
/// <summary>
/// 讀文件
/// </summary>
/// <param name="filename">文件路徑</param>
/// <param name="encoding">文件編碼</param>
/// <returns></returns>
protected string Read_Txt(string filename, string encoding)
{
if (string.IsNullOrEmpty(filename))
{
throw new ArgumentNullException(filename);
}
if (string.IsNullOrEmpty(encoding))
{
throw new ArgumentNullException(encoding);
}
var code = Encoding.GetEncoding(encoding);
var temp = HttpContext.Current.Server.MapPath("Precious\\" + filename + ".txt");
var str = string.Empty;
if (!System.IO.File.Exists(temp)) return str;
var sr = StreamReader.Null;
try
{
using (sr = new StreamReader(temp, code))
{
str = sr.ReadToEnd();
}
}
catch (IOException ioex)
{
throw new IOException(ioex.Message);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
sr.Close();
}
return str;
}
/// <summary>
/// 拷貝文件
/// </summary>
/// <param name="orignFile">原始文件</param>
/// <param name="newFile">新文件路徑</param>
public static void FileCoppy(string orignFile, string newFile)
{
if (string.IsNullOrEmpty(orignFile))
{
throw new ArgumentException(orignFile);
}
if (string.IsNullOrEmpty(newFile))
{
throw new ArgumentException(newFile);
}
System.IO.File.Copy(orignFile, newFile, true);
}
/// <summary>
/// 刪除文件
/// </summary>
/// <param name="path">路徑</param>
public static void FileDel(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException(path);
}
System.IO.File.Delete(path);
}
/// <summary>
/// 移動文件
/// </summary>
/// <param name="orignFile">原始路徑</param>
/// <param name="newFile">新路徑</param>
public static void FileMove(string orignFile, string newFile)
{
if (string.IsNullOrEmpty(orignFile))
{
throw new ArgumentException(orignFile);
}
if (string.IsNullOrEmpty(newFile))
{
throw new ArgumentException(newFile);
}
System.IO.File.Move(orignFile, newFile);
}
/// <summary>
/// 在當前目錄下創建目錄
/// </summary>
/// <param name="orignFolder">當前目錄</param>
/// <param name="newFloder">新目錄</param>
public static void FolderCreate(string orignFolder, string newFloder)
{
if (string.IsNullOrEmpty(orignFolder))
{
throw new ArgumentException(orignFolder);
}
if (string.IsNullOrEmpty(newFloder))
{
throw new ArgumentException(newFloder);
}
Directory.SetCurrentDirectory(orignFolder);
Directory.CreateDirectory(newFloder);
}
/// <summary>
/// 創建文件夾
/// </summary>
/// <param name="path"></param>
public static void FolderCreate(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException(path);
}
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
public static void FileCreate(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException(path);
}
var createFile = new FileInfo(path);
if (createFile.Exists) return;
var fs = createFile.Create();
fs.Close();
fs.Dispose();
}
/// <summary>
/// 遞歸刪除文件夾目錄及文件
/// </summary>
/// <param name="dir"></param>
/// <returns></returns>
public static void DeleteFolder(string dir)
{
if (string.IsNullOrEmpty(dir))
{
throw new ArgumentException(dir);
}
if (!Directory.Exists(dir)) return;
foreach (var d in Directory.GetFileSystemEntries(dir))
{
if (System.IO.File.Exists(d))
{
//直接刪除其中的文件
System.IO.File.Delete(d);
}
else
{
//遞歸刪除子文件夾
DeleteFolder(d);
}
}
//刪除已空文件夾
Directory.Delete(dir, true);
}
/// <summary>
/// 指定文件夾下面的所有內容copy到目標文件夾下面
/// </summary>
/// <param name="srcPath">原始路徑</param>
/// <param name="aimPath">目標文件夾</param>
public static void CopyDir(string srcPath, string aimPath)
{
if (string.IsNullOrEmpty(srcPath))
{
throw new ArgumentNullException(srcPath);
}
if (string.IsNullOrEmpty(aimPath))
{
throw new ArgumentNullException(aimPath);
}
try
{
if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar)
{
aimPath += Path.DirectorySeparatorChar;
}
if (!Directory.Exists(aimPath))
{
Directory.CreateDirectory(aimPath);
}
var fileList = Directory.GetFileSystemEntries(srcPath);
foreach (var file in fileList)
{
if (Directory.Exists(file))
{
CopyDir(file, aimPath + Path.GetFileName(file));
}
else
{
System.IO.File.Copy(file, aimPath + Path.GetFileName(file), true);
}
}
}
catch (IOException ioex)
{
throw new IOException(ioex.Message);
}
catch (Exception ee)
{
throw new Exception(ee.ToString());
}
}
/// <summary>
/// 獲取指定文件夾下所有子目錄及文件
/// </summary>
/// <param name="path">詳細路徑</param>
public static string GetFoldAll(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(path);
}
var str =string.Empty;
var thisOne = new DirectoryInfo(path);
str = ListTreeShow(thisOne, 0, str);
return str;
}
/// <summary>
/// 獲取指定文件夾下所有子目錄及文件函數
/// </summary>
/// <param name="theDir">指定目錄</param>
/// <param name="nLevel">默認起始值,調用時,一般為0</param>
/// <param name="rn">用於迭加的傳入值,一般為空</param>
/// <returns></returns>
public static string ListTreeShow(DirectoryInfo theDir, int nLevel, string rn)
{
if (theDir == null)
{
throw new ArgumentNullException("theDir");
}
//獲得目錄
DirectoryInfo[] subDirectories = theDir.GetDirectories();
foreach (DirectoryInfo dirinfo in subDirectories)
{
if (nLevel == 0)
{
rn += "├";
}
else
{
var s =string.Empty;
for (int i = 1; i <= nLevel; i++)
{
s += "│ ";
}
rn += s + "├";
}
rn += "<b>" + dirinfo.Name + "</b><br />";
//目錄下的文件
var fileInfo = dirinfo.GetFiles();
foreach (FileInfo fInfo in fileInfo)
{
if (nLevel == 0)
{
rn += "│ ├";
}
else
{
var f = string.Empty;
for (int i = 1; i <= nLevel; i++)
{
f += "│ ";
}
rn += f + "│ ├";
}
rn += fInfo.Name.ToString() + " <br />";
}
rn = ListTreeShow(dirinfo, nLevel + 1, rn);
}
return rn;
}
/// <summary>
/// 獲取指定文件夾下所有子目錄及文件(下拉框形)
/// </summary>
/// <param name="path">詳細路徑</param>
///<param name="dropName">下拉列表名稱</param>
///<param name="tplPath">默認選擇模板名稱</param>
public static string GetFoldAll(string path, string dropName, string tplPath)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(path);
}
if (string.IsNullOrEmpty(tplPath))
{
throw new ArgumentNullException(tplPath);
}
var strDrop = "<select name=\"" + dropName + "\" id=\"" + dropName + "\"><option value=\"\">--請選擇詳細模板--</option>";
var str =string.Empty;
DirectoryInfo thisOne = new DirectoryInfo(path);
str = ListTreeShow(thisOne, 0, str, tplPath);
return strDrop + str + "</select>";
}
/// <summary>
/// 獲取指定文件夾下所有子目錄及文件函數
/// </summary>
/// <param name="theDir">指定目錄</param>
/// <param name="nLevel">默認起始值,調用時,一般為0</param>
/// <param name="rn">用於迭加的傳入值,一般為空</param>
/// <param name="tplPath">默認選擇模板名稱</param>
/// <returns></returns>
public static string ListTreeShow(DirectoryInfo theDir, int nLevel, string rn, string tplPath)
{
if (theDir == null)
{
throw new ArgumentNullException("theDir");
}
//獲得目錄
DirectoryInfo[] subDirectories = theDir.GetDirectories();
foreach (DirectoryInfo dirinfo in subDirectories)
{
rn += "<option value=\"" + dirinfo.Name + "\"";
if (string.Equals(tplPath, dirinfo.Name, StringComparison.CurrentCultureIgnoreCase))
{
rn += " selected ";
}
rn += ">";
if (nLevel == 0)
{
rn += "┣";
}
else
{
string s = string.Empty;
for (int i = 1; i <= nLevel; i++)
{
s += "│ ";
}
rn += s + "┣";
}
rn += "" + dirinfo.Name + "</option>";
//目錄下的文件
FileInfo[] fileInfo = dirinfo.GetFiles();
foreach (FileInfo fInfo in fileInfo)
{
rn += "<option value=\"" + dirinfo.Name + "/" + fInfo.Name + "\"";
if (string.Equals(tplPath, fInfo.Name, StringComparison.CurrentCultureIgnoreCase))
{
rn += " selected ";
}
rn += ">";
if (nLevel == 0)
{
rn += "│ ├";
}
else
{
string f = string.Empty;
for (int i = 1; i <= nLevel; i++)
{
f += "│ ";
}
rn += f + "│ ├";
}
rn += fInfo.Name + "</option>";
}
rn = ListTreeShow(dirinfo, nLevel + 1, rn, tplPath);
}
return rn;
}
/// <summary>
/// 獲取文件夾大小
/// </summary>
/// <param name="dirPath">文件夾路徑</param>
/// <returns></returns>
public static long GetDirectoryLength(string dirPath)
{
if (string.IsNullOrEmpty(dirPath))
{
throw new ArgumentNullException(dirPath);
}
if (!Directory.Exists(dirPath))
{
return 0;
}
long len = 0;
DirectoryInfo di = new DirectoryInfo(dirPath);
foreach (FileInfo fi in di.GetFiles())
{
len += fi.Length;
}
DirectoryInfo[] dis = di.GetDirectories();
if (dis.Length > 0)
{
for (int i = 0; i < dis.Length; i++)
{
len += GetDirectoryLength(dis[i].FullName);
}
}
return len;
}
/// <summary>
/// 獲取指定文件詳細屬性
/// </summary>
/// <param name="filePath">文件詳細路徑</param>
/// <returns></returns>
public static string GetFileAttibe(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException(filePath);
}
var str = string.Empty;
FileInfo objFi = new FileInfo(filePath);
str += "詳細路徑:" + objFi.FullName + "<br>文件名稱:" + objFi.Name + "<br>文件長度:" + objFi.Length + "字節<br>創建時間" + objFi.CreationTime.ToString() + "<br>最後訪問時間:" + objFi.LastAccessTime.ToString() + "<br>修改時間:" + objFi.LastWriteTime.ToString() + "<br>所在目錄:" + objFi.DirectoryName + "<br>擴展名:" + objFi.Extension;
return str;
}
提到權限這個概念,這對於每一個開發者都是再熟悉不過的,因為我們在開發項目時,都會考慮用戶權限管理等等,但是文件的權限操作呢?這裡我們就簡單的介紹一下.NET中對文件訪問權限的訪問和設置。文件權限中的訪問控制列表: 自由訪問控制列表(DACL):Microsoft Windows NT和更高版本用於保護資源的機制;系統訪問控制列表(SACL):一種控制與資源關聯的審核消息的機制。System.Security.AccessControl命名空間通過一些類提供對訪問控制列表的訪問。DiectorySecurity:該類指定目錄的訪問控制和審核安全。指定系統目錄的訪問權限以及訪問嘗試的審核方式。FileSecurity:該類指定系統文件的訪問權限以及如何審核訪問嘗試。
下面介紹一下文件權限操作的類和方法:
[SecuritySafeCritical]
public FileSecurity GetAccessControl()
{
if (this._handle.IsClosed)
{
__Error.FileNotOpen();
}
return new FileSecurity(this._handle, this._fileName, AccessControlSections.Group | AccessControlSections.Owner | AccessControlSections.Access);
}
[SecurityCritical, SecurityPermission(SecurityAction.Assert, UnmanagedCode=true)]
internal FileSecurity(SafeFileHandle handle, string fullPath, AccessControlSections includeSections) : base(false, handle, includeSections, false)
{
if (fullPath != null)
{
new FileIOPermission(FileIOPermissionAccess.NoAccess, AccessControlActions.View, fullPath).Demand();
}
else
{
new FileIOPermission(PermissionState.Unrestricted).Demand();
}
}
[SecuritySafeCritical]
public void SetAccessControl(FileSecurity fileSecurity)
{
if (fileSecurity == null)
{
throw new ArgumentNullException("fileSecurity");
}
if (this._handle.IsClosed)
{
__Error.FileNotOpen();
}
fileSecurity.Persist(this._handle, this._fileName);
}
/// <summary>
/// 共享文檔操作
/// </summary>
public class FileSharingOperationHelper
{
public static bool ConnectState(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(path);
}
return ConnectState(path, "", "");
}
/// <summary>
/// 連接遠程共享文件夾
/// </summary>
/// <param name="path">遠程共享文件夾的路徑</param>
/// <param name="userName">用戶名</param>
/// <param name="passWord">密碼</param>
/// <returns></returns>
public static bool ConnectState(string path, string userName, string passWord)
{
var proc = new Process();
try
{
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
var dosLine = "net use " + path + " " + passWord + " /user:" + userName;
proc.StandardInput.WriteLine(dosLine);
proc.StandardInput.WriteLine("exit");
while (!proc.HasExited)
{
proc.WaitForExit(1000);
}
var errormsg = proc.StandardError.ReadToEnd();
proc.StandardError.Close();
if (!string.IsNullOrEmpty(errormsg))
{
throw new Exception(errormsg);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
proc.Close();
proc.Dispose();
}
return true;
}
/// <summary>
/// 向遠程文件夾保存本地內容,或者從遠程文件夾下載文件到本地
/// </summary>
/// <param name="src">要保存的文件的路徑,如果保存文件到共享文件夾,這個路徑就是本地文件路徑如:@"D:\1.avi"</param>
/// <param name="dst">保存文件的路徑,不含名稱及擴展名</param>
/// <param name="fileName">保存文件的名稱以及擴展名</param>
public static void Transport(string src, string dst, string fileName)
{
if (string.IsNullOrEmpty(src))
{
throw new ArgumentNullException(src);
}
if (string.IsNullOrEmpty(dst))
{
throw new ArgumentNullException(dst);
}
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException(fileName);
}
FileStream inFileStream = null;
FileStream outFileStream = null;
try
{
inFileStream = new FileStream(src, FileMode.Open);
if (!Directory.Exists(dst))
{
Directory.CreateDirectory(dst);
}
dst = dst + fileName;
outFileStream = new FileStream(dst, FileMode.OpenOrCreate);
var buf = new byte[inFileStream.Length];
int byteCount;
while ((byteCount = inFileStream.Read(buf, 0, buf.Length)) > 0)
{
outFileStream.Write(buf, 0, byteCount);
}
}
catch (IOException ioex)
{
throw new IOException(ioex.Message);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (inFileStream != null)
{
inFileStream.Flush();
inFileStream.Close();
}
if (outFileStream != null)
{
outFileStream.Flush();
outFileStream.Close();
}
}
}
}
文件權限的規則:容器的訪問規則可能被配置為不僅應用於對象本身,而且還應用於它的子對象、子容器或這兩者。每個訪問規則不是顯示的就是繼承的。DACL可以有對象的所有者任意修改,還可以由所有者已經給予其梗概DACL權限的任何更改。對象的安全描述包含另一個規則列表,稱為系統訪問權限列表(SACL),該列表將控制系統對對象執行哪個類型的審核。審核是一種具有安全敏感性的操作。在windows中,審核只能由本地安全機構(LSA)生成,LSA是唯一允許向安全事件日志中寫入的組件。
看到文件刪除,可能有人會問,前面不是已經介紹過文件的刪除操作嗎?為什麼這裡還需要詳細的介紹。不錯,上面的確介紹了文件和目錄的刪除方法,但是這裡是介紹如何徹底的刪除文件。我們常規的刪除文件和文件格式化,一般是可以被恢復的。我們在操作刪除的時候,只是將文件的索引給刪除了,並沒有刪除實際的內容。文件的索引記錄了文件在磁盤中的位置信息,當執行刪除操作時,只是從文件分配聊表中刪除了目錄。
那麼可能會有人問,怎麼講文件徹底的刪除呢?文件的粉碎,其實就是在刪除文件分配列表的同時,把文件在磁盤上占用的所有扇區數據置為0。
在.NET中提供了兩種文件徹底的方法:
(1).調用系統API來完成這樣的“粉碎”操作。
(2).在刪除文件之前先刪除文件的所有內容,然後在執行刪除操作,被稱為“假粉碎”。(此方法可以被人恢復文件,但是恢復的數據只是文件中的0)
為了文件安全,可以采用多輪粉碎的方式:第一輪,通過文件操作Windows API,找到原始文件的銘文在存儲器上所載區域,逐字符逐位進行完全填充,全部填充為0。第二輪,通過磁盤操作WindowsAPI找到原始文件或目錄在FAT表中的位置,將原始文件或目錄在FAT表中項清零。第三輪,通過磁盤操作WindowsAPI,找到原始文件或目錄在備份FAT表的位置,將原始文件或目錄在備份FAT表中的表項清零。
/// <summary>
/// 粉碎文件操作
/// </summary>
public class KillFileHelper
{
/// <summary>
/// 強力粉碎文件,文件如果被打開,很難粉碎
/// </summary>
/// <param name="filename">文件全路徑</param>
/// <param name="deleteCount">刪除次數</param>
/// <param name="randomData">隨機數據填充文件,默認true</param>
/// <param name="blanks">空白填充文件,默認false</param>
/// <returns>true:粉碎成功,false:粉碎失敗</returns>
public static bool KillFile(string filename, int deleteCount, bool randomData = true, bool blanks = false)
{
if (string.IsNullOrEmpty(filename))
{
throw new ArgumentNullException(filename);
}
const int bufferLength = 1024000;
var ret = true;
try
{
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var f = new FileInfo(filename);
var count = f.Length;
long offset = 0;
var rowDataBuffer = new byte[bufferLength];
while (count >= 0)
{
var iNumOfDataRead = stream.Read(rowDataBuffer, 0, bufferLength);
if (iNumOfDataRead == 0)
{
break;
}
if (randomData)
{
var randombyte = new Random();
randombyte.NextBytes(rowDataBuffer);
}
else if (blanks)
{
for (var i = 0; i < iNumOfDataRead; i++)
rowDataBuffer[i] = 0;
}
else
{
for (var i = 0; i < iNumOfDataRead; i++)
rowDataBuffer[i] = Convert.ToByte(Convert.ToChar(deleteCount));
}
// 寫新內容到文件。
for (var i = 0; i < deleteCount; i++)
{
stream.Seek(offset, SeekOrigin.Begin);
stream.Write(rowDataBuffer, 0, iNumOfDataRead);
}
offset += iNumOfDataRead;
count -= iNumOfDataRead;
}
}
//每一個文件名字符代替隨機數從0到9。
var newName = "";
do
{
var random = new Random();
var cleanName = Path.GetFileName(filename);
var dirName = Path.GetDirectoryName(filename);
var iMoreRandomLetters = random.Next(9);
// 為了更安全,不要只使用原文件名的大小,添加一些隨機字母。
for (var i = 0; i < cleanName.Length + iMoreRandomLetters; i++)
{
newName += random.Next(9).ToString();
}
newName = dirName + "\\" + newName;
} while (File.Exists(newName));
// 重命名文件的新的隨機的名字。
File.Move(filename, newName);
File.Delete(newName);
}
catch
{
//可能其他原因刪除失敗了,使用我們自己的方法強制刪除
var matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
try
{
//要檢查被那個進程占用的文件
var fileName = filename;
var tool = new Process { StartInfo = { FileName = "handle.exe", Arguments = fileName + " /accepteula", UseShellExecute = false, RedirectStandardOutput = true } };
tool.Start();
tool.WaitForExit();
var outputTool = tool.StandardOutput.ReadToEnd();
foreach (Match match in Regex.Matches(outputTool, matchPattern))
{
//結束掉所有正在使用這個文件的程序
Process.GetProcessById(int.Parse(match.Value)).Kill();
}
File.Delete(fileName);
}
catch
{
ret = false;
}
}
return ret;
}
}
上面介紹了文件的基本操作,文件權限操作,文件的刪除操作,最後介紹一下文件的加密和解密操作。File和FileInfo類對文件加密進行了進一步的封裝,提供了Encrypt和Decrypt方法用來對文件加密和解密。這兩種方法要求文件系統必須為NFTS系統,對操作系統版本也要求必須是NT以上版本,使用該方法加密的文件,必須由同一用戶才能進行解密。
具體看一下該方法的實現代碼:
[SecuritySafeCritical]
public static void Encrypt(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
string fullPathInternal = Path.GetFullPathInternal(path);
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
if (!Win32Native.EncryptFile(fullPathInternal))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 5)
{
DriveInfo info = new DriveInfo(Path.GetPathRoot(fullPathInternal));
if (!string.Equals("NTFS", info.DriveFormat))
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));
}
}
__Error.WinIOError(errorCode, fullPathInternal);
}
}
[SecuritySafeCritical]
public static void Decrypt(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
string fullPathInternal = Path.GetFullPathInternal(path);
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
if (!Win32Native.DecryptFile(fullPathInternal, 0))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 5)
{
DriveInfo info = new DriveInfo(Path.GetPathRoot(fullPathInternal));
if (!string.Equals("NTFS", info.DriveFormat))
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));
}
}
__Error.WinIOError(errorCode, fullPathInternal);
}
}
以上簡單的介紹了文件的操作和文件的權限管理方法,如果需要更加深入的了解這些操作方法,可以查看msdn,或者查看.NET的“墊片”,查看相應的接口。在當代社會中,數據安全和文件安全都是很重要的,我們應該更加深入的去學習安全知識,提高系統的穩定性。