我正在尝试将大约600 MB的zip文件上传到SQL 2008 FILESTREAM表,我得到了OutOfMemoryException。我正在使用SqlFileStream类上传文件(如本教程中所述 - http://www.aghausman.net/dotnet/saving-and-retrieving-file-using-filestream-sql-server-2008.html)。我有一台带有4GB内存的32位Vista机器,如果这很重要,我正在使用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();
}
}
如何上传文件而不出错?
谢谢!
答案 0 :(得分:0)
了解错误发生的确切位置可以帮助找到解决方案。一个可能有帮助的改变是将文件写入块(不要一次写入,循环并一次写入一点)。这使流有机会刷新,从而释放系统资源。
答案 1 :(得分:0)
我想出了这个问题。这是我的代码 -
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();
}
}