[英]UnauthorizedAccessException when calling FileInfo.Length
我確實通過 Crashlytics 收到報告,當我調用FileInfo.Length;
時,我的 Unity 應用程序的某些用戶(大約 0.5%)收到 UnauthorizedAccessException FileInfo.Length;
堆棧跟蹤的有趣部分是:
Non-fatal Exception: java.lang.Exception
UnauthorizedAccessException : Access to the path '/storage/emulated/0/Android/data/com.myCompany.myGreatGame/files/assets/myAsset.asset' is denied.
System.IO.__Error.WinIOError (System.IO.__Error)
System.IO.FileInfo.get_Length (System.IO.FileInfo)
相應的文件(對於每個報告來說都是不同的文件)是由同一個應用程序(可能是之前的多個會話)編寫的(或當前正在編寫的)。 調用發生在后台線程中,並且可能同時進行一些寫入。 但是根據 .net doc 這個屬性應該是預先緩存的(見https://docs.microsoft.com/en-us/dotnet/api/system.io.fileinfo.length?view=netframework-2.0 )
導致它的整個代碼是:
private static long DirSize(DirectoryInfo d)
{
long size = 0;
FileInfo[] fileInfos = d.GetFiles();
foreach (FileInfo fileInfo in fileInfos)
{
size += fileInfo.Length;
}
...
有沒有人經歷過類似的事情並知道可能是什么原因造成的?
這看起來是一個非常奇特的錯誤,因此,我沒有證據支持我的建議。
建議1:
用戶已安裝防病毒軟件 - 這些應用程序有時像惡意軟件一樣工作,鎖定主機程序未使用的文件來測試它們(特別是如果它們想防止惡意行為)。 這將解釋錯誤的罕見性質。 在 Length 方法調用失敗后,我會嘗試查看文件的權限,這可能會給您(也可能是我們)更多的見解。
建議2:
在某些情況下,當應用程序主動寫入此文件時,您無法讀取長度。 這不應該發生,但即使在操作系統中也會發生錯誤。 可能的路徑:某些應用程序正在寫入文件。 文件被修改並寫入元數據(包括長度),而碰巧您正在從另一個線程讀取長度,操作系統鎖定文件以防止讀取元數據(包括長度),同時寫入元數據(可能是出於安全原因)
建議 3(也是最有可能的):
壞 SD 卡/內存/CPU - 由於您無法控制客戶端的硬件,因此總會發生一些隨機錯誤。 我會檢查這 0.5% 的錯誤是否不是來自一個用戶,或者似乎來自多個用戶,但由於硬件的其他問題,他們的唯一 ID 重置(檢查其他數據,如手機型號,因為這也可能為您提供線索)。
如果您仔細閱讀Microsoft 的文檔,它會明確指出:
插入 #1 和 #2 可以輕松識別問題:當您嘗試獲取該信息時,您打開了一個帶有排他鎖的文件,這會給您帶來 #1 中的錯誤。 我建議實現兩種不同的邏輯,一種是明顯的 try/catch 塊,但是因為該塊 (a) 性能成本和 (b) 不能解決知道文件大小的邏輯問題,您還應該緩存當您獲得排他鎖時,您可以自己處理這些數據。
將它們放在內存中的靜態表中,一個簡單的鍵/值(文件/大小),並在調用 FileInfo.Length() 之前對其進行檢查。 基本上,當您獲得鎖時,您將文件/大小值添加到字典中,完成后將其刪除。 這樣,您將永遠不會再次出現錯誤,同時能夠計算目錄大小。
~皮諾
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.