将文件转换为字节数组是将ANY文件格式保存到磁盘或数据库var二进制列的最佳方法吗?
因此,如果有人想保存.gif或.doc/.docx或.pdf文件,我可以将其转换为字节数UFT8并将其作为字节流保存到数据库中吗?
Mad*_*Boy 144
既然没有提到你的意思是什么数据库我就是假设SQL Server.以下解决方案适用于2005年和2008年.
您必须使用VARBINARY(MAX)
其中一列创建表.在我的例子,我创建的表Raporty
与列RaportPlik
之中VARBINARY(MAX)
列.
file
从drive
以下位置输入数据库的方法:
public static void databaseFilePut(string varFilePath) {
byte[] file;
using (var stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read)) {
using (var reader = new BinaryReader(stream)) {
file = reader.ReadBytes((int) stream.Length);
}
}
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlWrite = new SqlCommand("INSERT INTO Raporty (RaportPlik) Values(@File)", varConnection)) {
sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;
sqlWrite.ExecuteNonQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法是file
从数据库获取并保存在drive
:
public static void databaseFileRead(string varID, string varPathToNewLocation) {
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("@varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
sqlQueryResult.Read();
var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
using (var fs = new FileStream(varPathToNewLocation, FileMode.Create, FileAccess.Write))
fs.Write(blob, 0, blob.Length);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法是file
从数据库获取并将其作为MemoryStream
:
public static MemoryStream databaseFileRead(string varID) {
MemoryStream memoryStream = new MemoryStream();
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("@varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
sqlQueryResult.Read();
var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
//using (var fs = new MemoryStream(memoryStream, FileMode.Create, FileAccess.Write)) {
memoryStream.Write(blob, 0, blob.Length);
//}
}
}
return memoryStream;
}
Run Code Online (Sandbox Code Playgroud)
这个方法是放入MemoryStream
数据库:
public static int databaseFilePut(MemoryStream fileToPut) {
int varID = 0;
byte[] file = fileToPut.ToArray();
const string preparedCommand = @"
INSERT INTO [dbo].[Raporty]
([RaportPlik])
VALUES
(@File)
SELECT [RaportID] FROM [dbo].[Raporty]
WHERE [RaportID] = SCOPE_IDENTITY()
";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;
using (var sqlWriteQuery = sqlWrite.ExecuteReader())
while (sqlWriteQuery != null && sqlWriteQuery.Read()) {
varID = sqlWriteQuery["RaportID"] is int ? (int) sqlWriteQuery["RaportID"] : 0;
}
}
return varID;
}
Run Code Online (Sandbox Code Playgroud)
快乐的编码:-)
虽然您可以以这种方式存储文件,但它有很大的权衡:
这些只是我能想到的一些缺点.对于小型项目,可能值得以这种方式存储文件,但如果您正在设计企业级软件,我强烈建议不要使用它.
它真的取决于数据库服务器.
例如,SQL Server 2008支持FILESTREAM
这种情况的数据类型.
除此之外,如果你使用a MemoryStream
,它有一个ToArray()
转换为a 的方法byte[]
- 这可以用于填充varbinary
字段..
我将描述在 SQL Server 和 Oracle 中存储文件的方式。首先,这很大程度上取决于您如何获取文件,以及如何获取其内容,并且取决于您用于存储内容的数据库以及存储方式。这是 2 个单独的数据库示例,其中有 2 种单独的方法来获取我使用的文件。
SQL服务器
简短回答:我使用了一个转换为 a 的 base64 字节字符串byte[]
并将其存储在一个varbinary(max)
字段中。
长答案:
假设您正在通过网站上传,因此您正在使用控件<input id="myFileControl" type="file" />
或 React DropZone。要获取该文件,您需要执行类似var myFile = document.getElementById("myFileControl")[0];
或 的操作myFile = this.state.files[0];
。
从那里,我将使用此处的代码获取 base64 字符串:Convert input=file to byte array (use function UploadFile2
)。
然后我将该字符串、文件名 ( myFile.name
) 和类型 ( myFile.type
) 放入 JSON 对象中:
var myJSONObj = {
file: base64string,
name: myFile.name,
type: myFile.type,
}
Run Code Online (Sandbox Code Playgroud)
并使用 XMLHttpRequest 将文件发布到 MVC 服务器后端,指定 Content-Type 为application/json
: xhr.send(JSON.stringify(myJSONObj);
。您必须构建一个 ViewModel 才能将其绑定:
public class MyModel
{
public string file { get; set; }
public string title { get; set; }
public string type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并指定[FromBody]MyModel myModelObj
为传入参数:
[System.Web.Http.HttpPost] // required to spell it out like this if using ApiController, or it will default to System.Mvc.Http.HttpPost
public virtual ActionResult Post([FromBody]MyModel myModelObj)
Run Code Online (Sandbox Code Playgroud)
然后您可以将其添加到该函数中并使用实体框架保存它:
MY_ATTACHMENT_TABLE_MODEL tblAtchm = new MY_ATTACHMENT_TABLE_MODEL();
tblAtchm.Name = myModelObj.name;
tblAtchm.Type = myModelObj.type;
tblAtchm.File = System.Convert.FromBase64String(myModelObj.file);
EntityFrameworkContextName ef = new EntityFrameworkContextName();
ef.MY_ATTACHMENT_TABLE_MODEL.Add(tblAtchm);
ef.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
tblAtchm.File = System.Convert.FromBase64String(myModelObj.file);
是操作线。
您需要一个模型来表示数据库表:
public class MY_ATTACHMENT_TABLE_MODEL
{
[Key]
public byte[] File { get; set; } // notice this change
public string Name { get; set; }
public string Type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这会将数据varbinary(max)
以byte[]
. Name
和分别Type
是nvarchar(250)
和nvarchar(10)
。您可以通过将其作为int
列 & MY_ATTACHMENT_TABLE_MODEL
as添加到表格中来包含大小public int Size { get; set;}
,然后添加到上面的行中tblAtchm.Size = System.Convert.FromBase64String(myModelObj.file).Length;
。
甲骨文
简短回答:将其转换为 a byte[]
,将其分配给 an OracleParameter
,将其添加到您的,然后使用对参数值的引用OracleCommand
更新表的字段:BLOB
ParameterName
:BlobParameter
长答案:当我为 Oracle 执行此操作时,我使用的是OpenFileDialog
以下方式检索并发送字节/文件信息:
byte[] array;
OracleParameter param = new OracleParameter();
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "Image Files (*.jpg, *.jpeg, *.jpe)|*.jpg;*.jpeg;*.jpe|Document Files (*.doc, *.docx, *.pdf)|*.doc;*.docx;*.pdf"
if (dlg.ShowDialog().Value == true)
{
string fileName = dlg.FileName;
using (FileStream fs = File.OpenRead(fileName)
{
array = new byte[fs.Length];
using (BinaryReader binReader = new BinaryReader(fs))
{
array = binReader.ReadBytes((int)fs.Length);
}
// Create an OracleParameter to transmit the Blob
param.OracleDbType = OracleDbType.Blob;
param.ParameterName = "BlobParameter";
param.Value = array; // <-- file bytes are here
}
fileName = fileName.Split('\\')[fileName.Split('\\').Length-1]; // gets last segment of the whole path to just get the name
string fileType = fileName.Split('.')[1];
if (fileType == "doc" || fileType == "docx" || fileType == "pdf")
fileType = "application\\" + fileType;
else
fileType = "image\\" + fileType;
// SQL string containing reference to BlobParameter named above
string sql = String.Format("INSERT INTO YOUR_TABLE (FILE_NAME, FILE_TYPE, FILE_SIZE, FILE_CONTENTS, LAST_MODIFIED) VALUES ('{0}','{1}',{2},:BlobParamerter, SYSDATE)", fileName, fileType, array.Length);
// Do Oracle Update
RunCommand(sql, param);
}
Run Code Online (Sandbox Code Playgroud)
在 Oracle 更新中,使用 ADO 完成:
public void RunCommand(string strSQL, OracleParameter param)
{
OracleConnection oraConn = null;
OracleCommand oraCmd = null;
try
{
string connString = GetConnString();
oraConn = OracleConnection(connString);
using (oraConn)
{
if (OraConnection.State == ConnectionState.Open)
OraConnection.Close();
OraConnection.Open();
oraCmd = new OracleCommand(strSQL, oraConnection);
// Add your OracleParameter
if (param != null)
OraCommand.Parameters.Add(param);
// Execute the command
OraCommand.ExecuteNonQuery();
}
}
catch (OracleException err)
{
// handle exception
}
finally
{
OraConnction.Close();
}
}
private string GetConnString()
{
string host = System.Configuration.ConfigurationManager.AppSettings["host"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["port"].ToString();
string serviceName = System.Configuration.ConfigurationManager.AppSettings["svcName"].ToString();
string schemaName = System.Configuration.ConfigurationManager.AppSettings["schemaName"].ToString();
string pword = System.Configuration.ConfigurationManager.AppSettings["pword"].ToString(); // hopefully encrypted
if (String.IsNullOrEmpty(host) || String.IsNullOrEmpty(port) || String.IsNullOrEmpty(serviceName) || String.IsNullOrEmpty(schemaName) || String.IsNullOrEmpty(pword))
{
return "Missing Param";
}
else
{
pword = decodePassword(pword); // decrypt here
return String.Format(
"Data Source=(DESCRIPTION =(ADDRESS = ( PROTOCOL = TCP)(HOST = {2})(PORT = {3}))(CONNECT_DATA =(SID = {4})));User Id={0};Password={1};",
user,
pword,
host,
port,
serviceName
);
}
}
Run Code Online (Sandbox Code Playgroud)
该FILE_CONTENTS
列的数据类型是BLOB
、 the FILE_SIZE
was NUMBER(10,0)
、LAST_MODIFIED
wasDATE
和其余的 were NVARCHAR2(250)
。
归档时间: |
|
查看次数: |
181290 次 |
最近记录: |