[英]convert varbinary to xml C#
我有AC#winforms應用程序將文件保存到sqlserver數據庫(2014)到varbinary(MAX)字段
功能保存
byte[] Bytefile;
using (SqlConnection conn = new SqlConnection(DataHelper.GetConnection()))
{
conn.Open();
DataTable dt = new DataTable();
SqlCommand comm = new SqlCommand("Delete T_Articale_Files where Artricle_id=" + ID, conn);
comm.ExecuteNonQuery();
foreach (string file in Directory.GetFiles(varFilePath))
{
using (var stream = new FileStream(Path.Combine(varFilePath, file), FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(stream))
{
Bytefile = reader.ReadBytes((int)stream.Length);
}
}
using (var sqlWrite = new SqlCommand("INSERT INTO T_Articale_Files (Artricle_id,FileName,FileData) Values(@ID,@FileName,@File)", conn))
{
sqlWrite.Parameters.Add("@ID", SqlDbType.Int, 10).Value = ID;
sqlWrite.Parameters.Add("@FileName", SqlDbType.NVarChar, 50).Value = Path.GetFileName(file);
sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = Bytefile;
sqlWrite.ExecuteNonQuery();
}
}
}
檢索功能
using (SqlConnection conn = new SqlConnection(DataHelper.GetConnection()))
// using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
{
conn.Open();
DataTable dt = new DataTable();
SqlCommand comm = new SqlCommand("SELECT id,FileName FROM T_Articale_Files WHERE Artricle_id = @varID", conn);
comm.Parameters.AddWithValue("@varID", varID);
dt.Load(comm.ExecuteReader());
foreach (DataRow item in dt.Rows)
{
using (var sqlQuery = new SqlCommand(@"SELECT FileData FROM T_Articale_Files WHERE id = @ID", conn))
{
sqlQuery.Parameters.AddWithValue("@ID", item["id"]);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
while (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(Path.Combine(varPathToNewLocation, item["FileName"].ToString()), FileMode.Create, FileAccess.Write))
fs.Write(blob, 0, blob.Length);
}
}
}
}
工作正常現在我已經要求將數據庫轉換為XML,用於沒有連接到服務器的PC
轉換為XML的函數
var xmlFileData = "";
DataSet ds = new DataSet();
var tables = new[] { "V_Articale", "T_Articale", "T_City", "T_Classification", "T_Country", "T_Locations", "T_milishia", "T_Search", "T_statistics", "T_TerrorGroups", "T_Tribes", "T_Users", "T_Articale_Files" };
foreach (var table in tables)
{
var query = "SELECT * FROM " + table;
SqlConnection conn = GetConnection();
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable(table);
da.Fill(dt);
conn.Close();
conn.Dispose();
ds.Tables.Add(dt);
if(table== "T_Articale_Files")
{
foreach (DataRow item in dt.Rows)
{
Byte[] file = GetBytes(item["FileData"].ToString());
}
}
}
xmlFileData = ds.GetXml();
它工作正常,除了二進制文件,它轉換為文本時
輸出XML
<T_Articale_Files>
<id>6</id>
<Artricle_id>1013</Artricle_id>
<FileName>falcon banner.jpg</FileName>
<FileData>/9j/4AAQSkZJRgABAgEASABIAAD/4QleRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUA</FileData>
當試圖將它轉換回圖像時,它給我1kb文件,字符串不是實際圖像
是否有特殊的二進制字段轉換請告知
謝謝
編輯問題解決了@ grek40解決方案轉換為XML
var xmlstream = new StringWriter();
ds.WriteXml(xmlstream, XmlWriteMode.WriteSchema);
string xmlWithSchema = xmlstream.ToString();
其中ds是數據集
轉換回文件
private void databaseFileRead(int varID, string varPathToNewLocation)
{
DataSet ds = new DataSet();
ds.ReadXml(XMLpath);
DataTable dt = new DataTable();
dt = ds.Tables["T_Articale_Files"];
DataView dv = new DataView(dt);
dv.RowFilter = "Artricle_id=" + varID;
if (dv.Count > 0)
{
foreach (DataRowView item in dv)
{
byte[] stringArray = (byte[])(item["FileData"]);
File.WriteAllBytes(Path.Combine(Filepath, item["FileName"].ToString()), stringArray ); // save image to disk
}
}
為了對二進制數據進行可逆字符串編碼,可以使用Base64編碼
public byte[] StrToByteArray(string str)
{
return Convert.FromBase64String(str);
}
public string ByteArrToString(byte[] byteArr)
{
return Convert.ToBase64String(byteArr);
}
將字節轉換為存儲在xml中的字符串,並在使用時從字符串恢復字節。
最初,數據正確寫為xml。 問題很可能是檢索功能。 由於xml不包含架構信息,因此它將<FileData>
視為文本,除非它的指示不同。
為了允許正確的重新讀取,您需要在讀取時使用預定義的模式,或者必須使用表格編寫模式:
dataSet.WriteXml(filenameOrStream, XmlWriteMode.WriteSchema)
// later read the xml and it will respect the schema information
dataSet.ReadXml(filenameOrStream);
一小部分不同方面的樣本:
var sourceDataSet = new DataSet();
var sourceTable = new DataTable("TableWithBinary");
sourceDataSet.Tables.Add(sourceTable);
sourceTable.Columns.Add("Id");
sourceTable.Columns.Add("File", typeof(byte[]));
sourceTable.Rows.Add(1, new byte[] { 1, 0, 2 });
sourceTable.Rows.Add(2, new byte[] { 1, 3, 2 });
// write option 1
string schema = sourceDataSet.GetXmlSchema();
string getxml = sourceDataSet.GetXml();
// write option 2
var writexmlstream = new StringWriter();
sourceDataSet.WriteXml(writexmlstream, XmlWriteMode.WriteSchema);
string writexmlWithSchema = writexmlstream.ToString();
// read wrong (missing schema)
var targetCorrupted = new DataSet();
targetCorrupted.ReadXml(new StringReader(getxml));
// read correct with schema in every xml file
var targetFromXmlWithSchema = new DataSet();
targetFromXmlWithSchema.ReadXml(new StringReader(writexmlWithSchema));
// read correct with separate schema definition and data
var targetFromXml = new DataSet();
targetFromXml.ReadXmlSchema(new StringReader(schema));
targetFromXml.ReadXml(new StringReader(getxml));
對於XML 內的二進制標准格式base64
。 我不認為,上面有什么問題......
您必須記住,XML中禁止使用多個字符。 您不能只在兩個XML標記之間填充二進制數據。 如果偶然的二進制文件中存在<
(或其他某些禁用字符)的數字代碼,它就會中斷。
您顯示的字符串看起來非常像base64代碼。
試試這個
DECLARE @string VARCHAR(100)='Hello World with forbidden characters (< & >)';
DECLARE @binary VARBINARY(MAX) = CAST(@string AS VARBINARY(MAX));
DECLARE @xml XML=(SELECT @string AS string, @binary AS bin FOR XML PATH('test'));
SELECT @xml;
- 結果(編碼實體和二進制隱式轉換為base64)
<test>
<string>Hello World with forbidden characters (< & >)</string>
<bin>SGVsbG8gV29ybGQgd2l0aCBmb3JiaWRkZW4gY2hhcmFjdGVycyAoPCAmID4p</bin>
</test>
- 現在我們從XML讀取(實體被重新編碼,二進制表示為HEX字符串,這可以重新轉換為前VARCHAR(MAX)
SELECT @xml.value('(/test/string)[1]','nvarchar(max)') AS TheStringAsIs
,@xml.value('(/test/bin)[1]','varbinary(max)') AS TheStringAsBinary_HEX
,CAST(@xml.value('(/test/bin)[1]','varbinary(max)') AS VARCHAR(100)) AS ReConverted
結果
The string *as-is*: Hello World with forbidden characters (< & >)
binary data HEX: 0x48656C6C6F20576F726C64207769746820666F7262696464656E206368617261637465727320283C2026203E29
ReConverted: Hello World with forbidden characters (< & >)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.