Sql server 将上载文件存储为SQL Server数据库中的二进制数据

Sql server 将上载文件存储为SQL Server数据库中的二进制数据,sql-server,asp.net-mvc,entity-framework,Sql Server,Asp.net Mvc,Entity Framework,我一直在努力解决这个问题。我正在尝试将一个文件上传到服务器,并将其保存为数据库中的二进制数据 我知道如何上传一个文件到服务器,它的工作良好 我需要知道如何将文件保存为数据库中的二进制数据 这就是我所取得的成就: 在SQL Server数据库中,我有一个名为files的表,其中包含以下列: Id, int, identity column FileName, nvarchar(50) UploadDate, datetime FileContent, varbinary(max) HomeC

我一直在努力解决这个问题。我正在尝试将一个文件上传到服务器,并将其保存为数据库中的二进制数据

我知道如何上传一个文件到服务器,它的工作良好

我需要知道如何将文件保存为数据库中的二进制数据

这就是我所取得的成就:

在SQL Server数据库中,我有一个名为
files
的表,其中包含以下列:

Id, int, identity column 
FileName, nvarchar(50) 
UploadDate, datetime
FileContent, varbinary(max)
HomeController.cs

[HttpPost]
public ActionResult Index(HttpPostedFileBase[] files)
{
    try
    {
        foreach (var file in files)
        {
            // extract only the filename
            var fileName = Path.GetFileName(file.FileName);

            // extract the file content to byte array
            var content = new byte[file.ContentLength];
            // reads the content from stream
            file.InputStream.Read(content, 0, file.ContentLength);

            //get file extesion
            var fileExtension = Path.GetExtension(fileName);
            //save file name as uniqe
            var uniqueFileName = Guid.NewGuid().ToString();

            Files fu = new Files
            {
                FileName = uniqueFileName,
                UploadDate = DateTime.Now,
                FileContent = content
            };

            DB.Files.Add(fu);
            DB.SaveChanges();
        }
    }
    catch (Exception e) { }

    // redirect back to the index action to show the form once again
    return RedirectToAction("Index");
}
index.cshtml

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="files" multiple/>
    <input type="submit" value="OK" />
}
@使用(Html.BeginForm(“Index”,“Home”,FormMethod.Post,new{enctype=“multipart/formdata”}))
{
}
此代码将一条记录插入数据库表中,该记录如下所示:

Id  FileName                                UploadDate              FileContent
1   716d30a5-8019-4ec9-a5e9-5b3966296bfc    2015-11-27 21:50:27.037 <Binary data>
Id文件名上传日期文件内容
1716D30A5-8019-4ec9-a5e9-5b3966296bfc 2015-11-27 21:50:27.037

我不知道为什么
fileContent
列中会填充文本

,因为文件内容数据类型是二进制的,Sql server会在内部将其作为二进制数据类型进行管理。通过查看表,您无法直接看到二进制文件

如果您想在SSMS中查看二进制数据,请尝试

这是一个检索binday数据的示例

// Assumes that connection is a valid SqlConnection object.
SqlCommand command = new SqlCommand(
  "SELECT pub_id, logo FROM pub_info", connection);

// Writes the BLOB to a file (*.bmp).
FileStream stream;                          
// Streams the BLOB to the FileStream object.
BinaryWriter writer;                        

// Size of the BLOB buffer.
int bufferSize = 100;                   
// The BLOB byte[] buffer to be filled by GetBytes.
byte[] outByte = new byte[bufferSize];  
// The bytes returned from GetBytes.
long retval;                            
// The starting position in the BLOB output.
long startIndex = 0;                    

// The publisher id to use in the file name.
string pubID = "";                     

// Open the connection and read data into the DataReader.
connection.Open();
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

while (reader.Read())
{
  // Get the publisher id, which must occur before getting the logo.
  pubID = reader.GetString(0);  

  // Create a file to hold the output.
  stream = new FileStream(
    "logo" + pubID + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
  writer = new BinaryWriter(stream);

  // Reset the starting byte for the new BLOB.
  startIndex = 0;

  // Read bytes into outByte[] and retain the number of bytes returned.
  retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);

  // Continue while there are bytes beyond the size of the buffer.
  while (retval == bufferSize)
  {
    writer.Write(outByte);
    writer.Flush();

    // Reposition start index to end of last buffer and fill buffer.
    startIndex += bufferSize;
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
  }

  // Write the remaining buffer.
  writer.Write(outByte, 0, (int)retval - 1);
  writer.Flush();

  // Close the output file.
  writer.Close();
  stream.Close();
}

// Close the reader and the connection.
reader.Close();
connection.Close();

来源:

由于文件内容数据类型是二进制的,Sql server在内部将其作为二进制数据类型进行管理。通过查看表,您无法直接看到二进制文件

如果您想在SSMS中查看二进制数据,请尝试

这是一个检索binday数据的示例

// Assumes that connection is a valid SqlConnection object.
SqlCommand command = new SqlCommand(
  "SELECT pub_id, logo FROM pub_info", connection);

// Writes the BLOB to a file (*.bmp).
FileStream stream;                          
// Streams the BLOB to the FileStream object.
BinaryWriter writer;                        

// Size of the BLOB buffer.
int bufferSize = 100;                   
// The BLOB byte[] buffer to be filled by GetBytes.
byte[] outByte = new byte[bufferSize];  
// The bytes returned from GetBytes.
long retval;                            
// The starting position in the BLOB output.
long startIndex = 0;                    

// The publisher id to use in the file name.
string pubID = "";                     

// Open the connection and read data into the DataReader.
connection.Open();
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

while (reader.Read())
{
  // Get the publisher id, which must occur before getting the logo.
  pubID = reader.GetString(0);  

  // Create a file to hold the output.
  stream = new FileStream(
    "logo" + pubID + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
  writer = new BinaryWriter(stream);

  // Reset the starting byte for the new BLOB.
  startIndex = 0;

  // Read bytes into outByte[] and retain the number of bytes returned.
  retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);

  // Continue while there are bytes beyond the size of the buffer.
  while (retval == bufferSize)
  {
    writer.Write(outByte);
    writer.Flush();

    // Reposition start index to end of last buffer and fill buffer.
    startIndex += bufferSize;
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
  }

  // Write the remaining buffer.
  writer.Write(outByte, 0, (int)retval - 1);
  writer.Flush();

  // Close the output file.
  writer.Close();
  stream.Close();
}

// Close the reader and the connection.
reader.Close();
connection.Close();

来源:

InputStream.Read
的工作方式与您认为的不一样,您必须使用返回的int并一直读取,直到完全读取数据。SQL Server就是这样显示二进制数据的。您的数据尚未神奇地转换为“二进制数据”。@ataravati,不是每个人都有15年的经验:)现在我知道了。。感谢
InputStream.Read
的工作方式与您认为的不一样,您必须使用返回的int并继续读取,直到完全读取数据。SQL Server就是这样显示二进制数据的。您的数据尚未神奇地转换为“二进制数据”。@ataravati,不是每个人都有15年的经验:)现在我知道了。。谢谢,你说数据库中插入的数据很好吗?是的,它被插入了,现在你必须检索它。我尝试了这个:“从[dbo].[Files]中选择sys.fn_sqlvarbasetostr(FileContent)”,结果是“操作数类型冲突:varbinary(max)与sql_variant不兼容”,所以,你说插入到数据库的数据没有问题?是的,它被插入了,现在你必须检索它。我尝试过这样做:“从[dbo].[Files]中选择sys.fn\u sqlvarbasetostr(FileContent)”,结果是—“操作数类型冲突:varbinary(max)与sql\u variant不兼容”