天天看點

對 File.Delete 方法的一點看法

在我寫的“推箱子”程式的 datafile 類中有下面這麼一個方法:

<!--

code highlighting produced by actipro codehighlighter (freeware)

http://www.codehighlighter.com/

-->    ///

<summary>

    ///  删除通關步驟檔案

    ///

</summary>

<param name="level">關數</param>

    private

void deletestepsfile(int level)

    {

      file.delete(getstepsfilename(filename, level));

    }

    該方法主要用在“編輯”關卡完成後儲存資料時删除本關的通關步驟(因為關卡地圖都被修改了,原來的通關步驟當然不再适用了)。然而,在一次測試中,發現“編輯”關卡完成後儲存資料時居然引發一個“directorynotfoundexception”異常。經過查找原因,發現通關步驟檔案是儲存在“steps”目錄下,由于從來沒有儲存過通關步驟,是以也就沒有建立“steps”目錄,file.delete 方法在指定的檔案不存在時并不引發異常, 但是如果指定的路徑無效,還是會引發 directorynotfoundexception

異常。

    後來,将 datafile.deletestepsfile 方法改為下面這個樣子就正常了(請參見“使用 c# 開發智手機軟體:推箱子(十)”):

      // 雖然 file.delete(): 删除指定的檔案。如果指定的檔案不存在,則不引發異常。

      // 但是: 如果指定的路徑無效,還是會引發 directorynotfoundexception 異常。

      // 是以需要先用 file.exists() 判斷一下檔案是否存在

      string name

= getstepsfilename(filename, level);

      if (file.exists(name)) file.delete(name);

     我們來看看 msdn 上對“file.delete 方法”的描述:

file.delete 方法

(system.io)

删除指定的檔案。如果指定的檔案不存在,則不引發異常。

命名空間:  system.io

程式集:  mscorlib(在 mscorlib.dll 中)

文法

public static void delete (

  string path

)

參數

path   要删除的檔案的名稱。

異常

異常類型

條件

argumentexception

path 是一個零長度字元串,僅包含空白或者包含一個或多個由 invalidpathchars 定義的無效字元。

argumentnullexception

path 為空引用(在 visual basic 中為 nothing)。

directorynotfoundexception

指定的路徑無效(例如,它位于未映射的驅動器上)。

ioexception

指定的檔案正在使用中。

notsupportedexception

path 的格式無效。

pathtoolongexception

指定的路徑、檔案名或者兩者都超出了系統定義的最大長度。例如,在基于 windows 的平台上,路徑必須小于 248 個字元,檔案名必須小于 260 個字元。

unauthorizedaccessexception

調用方沒有所要求的權限。

- 或 -

path 是一個目錄。

path 指定一個隻讀檔案。

備注允許 path 參數指定相對或絕對路徑資訊。相對路徑資訊被解釋為相對于目前工作目錄。若要擷取目前工作目錄,請參見 getcurrentdirectory。

有關通用 i/o 任務的清單,請參見 通用 i/o 任務。

windows nt 4.0 平台說明: delete 不删除為正常 i/o 打開的檔案或已在記憶體中映射的檔案。

    還有“file.exists 方法”(該方法不會引發異常):

file.exists 方法

确定指定的檔案是否存在。

命名空間:   system.io

程式集:   mscorlib(在 mscorlib.dll 中)

public static bool exists (

path   要檢查的檔案。

傳回值如果調用方具有要求的權限并且 path 包含現有檔案的名稱,則為 true;否則為 false。如果

path 為 空引用(在 visual basic 中為 nothing)、無效路徑或零長度字元串,則此方法也将傳回 false。如果調用方不具有讀取指定檔案所需的足夠權限,則不引發異常并且該方法傳回 false,這與 path 是否存在無關。

備注不應使用 exists 方法來驗證路徑,此方法僅檢查

path 中指定的檔案是否存在。将無效路徑傳遞到 exists 将傳回 false。

請注意,在您調用 exists 方法和對檔案執行其他操作(如 delete)之間,其他程序可能會對檔案進行一些處理。建議的程式設計做法是在 try...catch 塊中包裝 exists 方法和對檔案采取的操作,如示例中所示。這有助于縮小潛在沖突的範圍。exists 方法隻能幫助確定檔案是可用的,但無法保證。

允許 path 參數指定相對或絕對路徑資訊。相對路徑資訊被解釋為相對于目前工作目錄。若要擷取目前工作目錄,請參見 getcurrentdirectory。

如果 path 描述一個目錄,則此方法傳回 false。在确定檔案是否存在之前,從 path 參數中移除尾随空格。

    現在我們用下面這段程式來測試一下:

對 File.Delete 方法的一點看法

using system;

對 File.Delete 方法的一點看法

using system.io;

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

sealed

class test

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

{

對 File.Delete 方法的一點看法

  static

void main(string[] args)

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

try

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

      console.write("請輸入要删除的檔案名:

");

對 File.Delete 方法的一點看法

string filename

= console.readline();

對 File.Delete 方法的一點看法

if (filename

== "null") filename

= null;

對 File.Delete 方法的一點看法

if (args.length

< 1

|| file.exists(filename))

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

        file.delete(filename);

對 File.Delete 方法的一點看法

        console.writeline("file.delete 成功");

對 File.Delete 方法的一點看法

      }

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

catch (exception ex)

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

      console.writeline("錯誤:

" + ex.tostring());

對 File.Delete 方法的一點看法
對 File.Delete 方法的一點看法

  }

對 File.Delete 方法的一點看法

}

對 File.Delete 方法的一點看法

    運作結果如下:

檔案名

直接調用 file.delete 方法

d:\cs\work>test

先調用 file.exists 方法

d:\cs\work>test with file.exists

零長度字元串

請輸入要删除的檔案名:

錯誤: system.argumentexception: 路徑的形式不合法。

   在 system.io.path.normalizepathfast(string path, boolean fullcheck)

   在 system.io.path.getfullpathinternal(string path)

   在 system.io.file.delete(string path)

   在 test.main(string[] args)

非法字元

請輸入要删除的檔案名: |

錯誤: system.argumentexception: 路徑中具有非法字元。

   在 system.io.path.checkinvalidpathchars(string path)

空引用

請輸入要删除的檔案名: null

錯誤: system.argumentnullexception: 值不能為空。

參數名: path

無效的路徑

請輸入要删除的檔案名: none\a.txt

錯誤: system.io.directorynotfoundexception:

未能找到路徑“d:\cs\work\none\a.txt”的一部分。

   在 system.io.__error.winioerror(int32 errorcode, string maybefullpath)

無效的網絡路徑

請輸入要删除的檔案名: \\z\a.txt

錯誤: system.io.ioexception: 找不到網絡路徑。

格式無效

請輸入要删除的檔案名: ab:

錯誤: system.notsupportedexception: 不支援給定路徑的格式。

   在 system.security.util.stringexpressionset.canonicalizepath(string path, boolean needfullpath)

   在 system.security.util.stringexpressionset.createlistfromexpressions(string[] str, boolean needfullpath)

   在 system.security.permissions.fileiopermission.addpathlist(fileiopermissionaccess access, accesscontrolactions control, string[] pathlistorig, boolean checkforduplicates, boolean needfullpath, boolean copypathlist)

   在 system.security.permissions.fileiopermission..ctor(fileiopermissionaccess access, string[] pathlist, boolean checkforduplicates, boolean needfullpath)

檔案名太長

請輸入要删除的檔案名: -this-string's-length-is-249-

錯誤: system.io.pathtoolongexception: 指定的路徑或檔案名太長,或者兩者都太長。完全限定檔案名必須少于 260 個字元,并且目錄名必須少于 248 個字元。

正在使用的檔案

請輸入要删除的檔案名: test.exe

錯誤: system.unauthorizedaccessexception: 對路徑“d:\cs\work\test.exe”的通路被拒絕。

一個目錄

請輸入要删除的檔案名: d:\cs

錯誤: system.unauthorizedaccessexception: 對路徑“d:\cs”的通路被拒絕。

隻讀檔案

請輸入要删除的檔案名: readonly.file

錯誤: system.unauthorizedaccessexception: 對路徑“d:\cs\work\readonly.file”的通路被拒絕。

不存在的檔案

請輸入要删除的檔案名: none.file

file.delete 成功

正常的檔案

請輸入要删除的檔案名: readwrite1.file

請輸入要删除的檔案名: readwrite2.file

    可以看出,如果先調用 file.exists 方法判斷一下指定的檔案是否存在再決定是否調用 file.delete 方法,則僅僅在“指定的檔案正在使用中”和“指定一個隻讀檔案”這兩種情況下會引發異常。而如果直接調用 file.delete 方法,則在“指定的檔案不存在”的情況下不引發異常,但是在“指定的路徑無效”的情況下會引發異常。

    實際上,我認為,“指定的路徑無效”應該也算“指定的檔案不存在”的一種情況。是以,fcl 中的 file.delete 方法如果按以下原則進行設計則對開發人員更為友好:

    1. file.delete 方法在“指定的檔案不存在”時引發 filenotfoundexception 異常。

    2. file.delete 方法在“指定的檔案不存在”和“指定的路徑無效”時不引發異常。

    我更傾向于第二種方案。這樣,在大多數情況下,就可以直接調用 file.delete 方法,而不用先調用 file.exists 方法。

繼續閱讀