OutOfMemoryException при использовании файлового потока SQL - PullRequest
2 голосов
/ 14 декабря 2010

Я пытаюсь загрузить ZIP-файл размером около 600 МБ в таблицу SQL 2008 FILESTREAM и получаю исключение OutOfMemoryException.Я использую класс SqlFileStream для загрузки файла (как описано в этом руководстве - http://www.aghausman.net/dotnet/saving-and-retrieving-file-using-filestream-sql-server-2008.html). У меня 32-разрядная машина Vista с оперативной памятью 4 ГБ, если это имеет значение, и я использую VS 2010, Entity Framework 4.

Вот мой фрагмент кода -

public static void AddItem(RepositoryFile repository)
    {
        var contents = repository.Data; // I get the exception at this line.
        repository.Data = System.Text.Encoding.ASCII.GetBytes("0x00");

        using (var scope = new TransactionScope())
        {
            using (var db = new MyEntities())
            {
                db.RepositoryTable.AddObject(repository);
                db.SaveChanges();
            }

            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
            using (var cmd = new SqlCommand("SELECT Data.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM dbo.RepositoryTable", con))
            {
                cmd.Connection.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var path = reader.GetString(0);
                        var transactionContext = reader.GetSqlBytes(1).Buffer;
                        var fileStream = new SqlFileStream(path, transactionContext, FileAccess.Write);

                        fileStream.Write(contents, 0, contents.Length);
                        fileStream.Close();
                    }
                }
            }

            scope.Complete();
        }
    }

Как загрузить файл без ошибок?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 14 декабря 2010

Я разобрался в проблеме.Вот мой код -

private void AddFile()
    {
        if (!fupFile.HasFile)
        {
            lblMessage.Text = "Please select a file.";                
            return;
        }

        var data = new byte[(int) fupFile.FileContent.Length];
        fupFile.FileContent.Read(data, 0, data.Length);

        if (fupFile.FileContent.Length > 0)
        {
            var repositoryFile = new Repository
                                     {
                                         ID = Guid.NewGuid(),
                                         Name = Path.GetFileName(fupFile.PostedFile.FileName),                                             
                                         Data = System.Text.Encoding.ASCII.GetBytes("0x00")
                                     };

            RepositoryController.AddItem(repositoryFile, data); // Calling DAL class.
        }
    }

// DAL method
public static void AddItem(RepositoryFile repository, byte[] data)
{
    using (var scope = new TransactionScope())
    {
        using (var db = new MyEntities()) // DBContext
        {
            db.RepositoryTable.AddObject(repository);
            db.SaveChanges();
        }

        using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        using (var cmd = new SqlCommand(string.Format("SELECT Data.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM dbo.RepositoryTable WHERE ID='{0}'", repository.ID), con)) // "Data" is the column name which has the FILESTREAM. Data.PathName() gives me the local path to the file.
        {
            cmd.Connection.Open();
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    var path = reader.GetString(0);
                    var transactionContext = reader.GetSqlBytes(1).Buffer;
                    var fileStream = new SqlFileStream(path, transactionContext, FileAccess.Write);

                    fileStream.Write(contents, 0, contents.Length); //Write contents to the file.
                    fileStream.Close();
                }
            }
        }

        scope.Complete();
    }
}
0 голосов
/ 14 декабря 2010

Знание, где именно происходит ошибка, может помочь найти решение.Одно из внесенных изменений, которое может помочь, - это разбиение файла на части (не пишите все сразу, зацикливайтесь и пишите немного по очереди).Это дает потоку возможность сбрасывать и, следовательно, освобождать системные ресурсы.

...