簡體   English   中英

鎖定替換網站上的文件的問題

[英]Locking issues with replacing files on a website

我想用更新的版本替換IIS網站上的現有文件。 假設這些文件是大型pdf文檔,可以通過超鏈接訪問。 該網站全天候運行,因此我擔心在某人嘗試讀取文件的同時更新文件時會出現鎖定問題。

使用服務器上運行的C#代碼更新文件。 我可以想到打開文件寫兩個選項。

選項1)使用FileShare.Read打開要寫入的文件:

using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))

當此文件處於打開狀態,並且用戶通過超鏈接請求在Web瀏覽器中讀取相同的文件時,該文檔將打開為空白頁面。

選項2)使用FileShare.None打開要寫入的文件:

using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)) 

當此文件處於打開狀態,並且用戶通過超鏈接請求在Web瀏覽器中讀取相同的文件時,瀏覽器會顯示錯誤。 在IE 8中,您獲得HTTP 500,“網站無法顯示頁面”,並且在Firefox 3.5中,您會得到:“進程無法訪問該文件,因為它正由另一個進程使用。”

瀏覽器行為有點合理,看似合理。 我想用戶在更新文件的同時嘗試讀取文件的可能性極小。 如果以某種方式,文件更新是原子的,就像使用包裹在事務中的SQL更新數據庫一樣,這將是很好的。

我想知道你們是否擔心這類事情,並且更喜歡上述任一選項,甚至還有其他選擇來更新文件。

如何使用不同的名稱復制新版本的文件,然后將File.Move()設置為overwrite參數為true 在您編寫它時,您不會干擾Web服務器,並且移動文件會很快。

我通常不擔心這種問題,但你可以這樣做:

  • 創建指向ASPX頁面的鏈接,該頁面下載引用的文件,如“Download.aspx?Name = Document1.pdf”
  • 在該頁面中,在下載該文件之前,查找名為“Updated”的文件夾
  • 如果找到它,請從中獲取文件
  • 如果沒有,請從“當前”文件夾中獲取它

要更新您的文件:

  • 創建文件夾名稱“正在更新”
  • 將新文件復制到其中
  • 將其重命名為“已更新”(因此新下載將其用作源)
  • 更新“當前”文件夾
  • 刪除“已更新”文件夾

一種選擇是在超鏈接和文件之間構建一個額外的層。 而不是直接鏈接到文件使超鏈接指向另一個頁面(或類似的資源)。 然后,該資源/頁面可以確定哪個是需要發送到瀏覽器的最新文件,然后將其發送到瀏覽器。 這樣鏈接將始終相同,但文件可以更改。

這本質上是一個線程問題,以干凈的方式解決這些問題可能很棘手。 從概念上講,您希望從多個線程同步對文件的讀寫訪問權限。

為此,我會將文件存儲在IIS的網站根目錄之外,以便IIS不直接提供它。 我會創建一個單獨的HttpHandler來代替它。 HttpHandler會鎖定寫代碼也會鎖定的對象。 您應該使用ReaderWriterLockSlim以便您可以擁有多個並發讀取( EnterReadLock ),同時還確保只能執行一個寫入線程( EnterWriteLock ),並且在寫入時阻止讀取。

有一個類似的問題,我開發了自己的解決方案(基本上有一個文件的多個版本,通過ASHX處理程序提供它們)。

參閱我的CodeProject文章討論解決方案(以及可能的警告)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM