Приведите длину файлового потока к int - PullRequest
0 голосов
/ 22 июля 2011

У меня есть вопрос о безопасности броска от long до 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;
    }

Ответы [ 2 ]

4 голосов
/ 22 июля 2011

короткий ответ: да, таким образом у вас будут проблемы с любым файлом длиной> = 2 ГБ!

если вы не ожидаете больших файлов, вы можете вставить их непосредственно в начало блока using:

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

в противном случае вы не должны приводить к int, а менять byte[] read = new byte[fsLength]; на byte[] read = new byte[fs.Length]; и использовать цикл для чтения содержимого файла в «кусках» макс. 2 ГБ на блок.

Другой альтернативой (доступной в .NET4) является использование MemoryMappedFile (см. http://msdn.microsoft.com/en-us/library/dd997372.aspx) - таким образом вам вообще не нужно вызывать Read: -)

3 голосов
/ 22 июля 2011

Ну, int - это 32-битная версия, а long - это 64-битная версия, поэтому всегда есть вероятность потери некоторых данных при преобразовании, если вы открываете файлы объемом 2 ГБ;с другой стороны, такое выделение байтового массива fsLength может показывать, что вы не ожидаете таких больших файлов.Поставьте отметку, чтобы убедиться, что fs.Length не превышает 2 147 483 647, и с вами все будет в порядке.

...