2011-07-21 53 views
0

我对从long到int的演员安全性有疑问。我担心我写的方法可能会失败。你能否看看下面的代码,告诉我是否可以编写一些能够避免可能失败的东西?将文件流长度转换为int

预先感谢您。

public static string ReadDecrypted(string fileFullPath) 
    { 
     string result = string.Empty; 

     using (FileStream fs = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read)) 
     { 
      int fsLength = (int)fs.Length; 
      byte[] decrypted; 
      byte[] read = new byte[fsLength]; 
      if (fs.CanRead) 
      { 
       fs.Read(read, 0, fsLength); 
       decrypted = ProtectedData.Unprotect(read, CreateEntropy(), DataProtectionScope.CurrentUser); 
       result = Utils.AppDefaultEncoding.GetString(decrypted, 0, decrypted.Length); 
      } 
     } 
     return result; 
    } 
+3

你为什么铸造为int? – Yahia

+0

为什么不直接声明fsLength并避免演员阵容? – Tod

+0

我不是C#的专家,但假设'fs.Length'等于2到31的幂(1 << 31)。您的演员阵容会导致“fsLength”的负数? –

回答

4

简短的回答是:是的,这样你就会遇到长度大于等于2 GB的文件问题!

,如果你不指望大,那么你可以在使用块开始直接插入任何文件:

if (((int)fs.Length) != fs.Length) throw new Exception ("too big"); 

否则你不应该强制转换为int,但改变byte[] read = new byte[fsLength];byte[] read = new byte[fs.Length];和使用一个循环来读取最大值的“块”中的文件内容。每块2 GB。

另一种选择(可以在.NET4)是使用MemoryMappedFile(见http://msdn.microsoft.com/en-us/library/dd997372.aspx) - 这种方式,你不需要调用Read在所有:-)

+0

有关循环的建议是我需要的,谢谢 –

3

好,int是32位和long是64位的,所以总是有一个与如果你打开了2GB的文件,中投失去一些数据的可能性;另一方面,fsLength的字节数组的分配似乎表明您并不期望那些大的文件。请检查以确保fs.Length不大于2,147,483,647,并且您应该没问题。

+0

你为你的答案;我知道,如果我期待更大的文件,我应该避免演员阵容。我怎么能在这样的大文件上调用filestream.Read(),你能提供一个提示吗? –

+2

你可以直接调用filestream.Read(),不要一次读取整个文件;读一个块,处理该块,然后读取下一个块。 –