Est-ce que la conversion d’un fichier en un tableau d’octets est la meilleure façon d’enregistrer le format de fichier ANY sur le disque ou la firebase database var binary column?
Donc, si quelqu’un veut enregistrer un fichier .gif ou .doc / .docx ou .pdf, est-ce que je peux le convertir en un bytearray UFT8 et l’enregistrer sur la firebase database sous forme de stream d’octets?
Comme il n’est pas mentionné quelle firebase database vous voulez dire, je suppose que SQL Server. La solution ci-dessous fonctionne pour 2005 et 2008.
Vous devez créer une table avec VARBINARY(MAX)
comme l’une des colonnes. Dans mon exemple, j’ai créé la Table Raporty
avec la colonne RaportPlik
colonne VARBINARY(MAX)
.
Méthode pour placer le file
dans la firebase database à partir du drive
:
public static void databaseFilePut(ssortingng 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(); } }
Cette méthode consiste à récupérer le file
de la firebase database et à l’enregistrer sur le drive
:
public static void databaseFileRead(ssortingng varID, ssortingng 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); } } }
Cette méthode consiste à récupérer le file
de la firebase database et à le mettre en MemoryStream
:
public static MemoryStream databaseFileRead(ssortingng 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; }
Cette méthode consiste à mettre MemoryStream
dans la firebase database:
public static int databaseFilePut(MemoryStream fileToPut) { int varID = 0; byte[] file = fileToPut.ToArray(); const ssortingng 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; }
Heureux codage 🙂
Bien que vous puissiez stocker des fichiers de cette manière, les compromis sont importants:
Ce ne sont là que quelques-uns des inconvénients que je peux imaginer. Pour les projets de petite taille, il peut être intéressant de stocker des fichiers de cette manière, mais si vous concevez des logiciels de niveau professionnel, je vous le déconseille fortement.
Cela dépend vraiment du serveur de firebase database.
Par exemple, SQL Server 2008 prend en charge un type de données FILESTREAM
pour cette situation.
En dehors de cela, si vous utilisez un MemoryStream
, il a une méthode ToArray()
qui sera convertie en un byte[]
– cela peut être utilisé pour varbinary
un champ varbinary
.
Confirmant que j’ai pu utiliser la réponse publiée par MadBoy et éditée par Otiel sur MS SQL Server 2012 et 2014 en plus des versions précédemment répertoriées utilisant des colonnes varbinary (MAX).
Si vous vous demandez pourquoi vous ne pouvez pas “Filestream” (noté dans une réponse séparée) en tant que type de données dans le concepteur de tables SQL Server ou pourquoi vous ne pouvez pas définir le type de données d’une colonne sur “Filestream” en utilisant T-SQL, atsortingbut du type de données varbinary (MAX). Ce n’est pas un type de données en soi.
Consultez ces articles sur la configuration et l’activation de FILESTREAM sur une firebase database: https://msdn.microsoft.com/en-us/library/cc645923(v=sql.120).aspx
http://www.kodyaz.com/t-sql/default-filestream-filegroup-is-not-available-in-database.aspx
Une fois configurée, une colonne varbinary (max) activée pour filestream peut être ajoutée comme suit:
ALTER TABLE TableName
ADD ColumnName varbinary (max) FILESTREAM NULL
ALLER
Quelle firebase database utilisez-vous? Normalement, vous ne sauvegardez pas les fichiers dans une firebase database, mais je pense que sql 2008 a le support pour cela …
Un fichier est une donnée binary, donc UTF 8 n’a pas d’importance ici.
UTF 8 est important lorsque vous essayez de convertir une chaîne en un tableau d’octets … et non un tableau en octets.
Je décrirai la manière dont j’ai stocké les fichiers dans SQL Server et Oracle. Cela dépend en grande partie de la façon dont vous obtenez le fichier, en premier lieu, de la manière dont vous allez obtenir son contenu, et cela dépend de la firebase database que vous utilisez pour le contenu dans lequel vous allez le stocker. Ce sont 2 exemples de bases de données séparés avec 2 méthodes distinctes pour obtenir le fichier que j’ai utilisé.
serveur SQL
Réponse courte: J’ai utilisé une chaîne d’octets base64 convertie en byte[]
et varbinary(max)
dans un varbinary(max)
.
Longue réponse:
Supposons que vous téléchargez via un site Web, vous utilisez donc un contrôle ou React DropZone. Pour obtenir le fichier, vous faites quelque chose comme
var myFile = document.getElementById("myFileControl")[0];
ou myFile = this.state.files[0];
.
De là, j’obtiens la chaîne base64 en utilisant le code ici: Convertir input = file en tableau d’octets (utilisez la fonction UploadFile2
).
Ensuite, j’obtiendrais cette chaîne, le nom du fichier ( myFile.name
) et tapez ( myFile.type
) dans un object JSON:
var myJSONObj = { file: base64ssortingng, name: myFile.name, type: myFile.type, }
et publier le fichier sur un serveur principal MVC à l’aide de XMLHttpRequest, en spécifiant un Content-Type d’ application/json
: xhr.send(JSON.ssortingngify(myJSONObj);
Vous devez créer un ViewModel pour le lier à:
public class MyModel { public ssortingng file { get; set; } public ssortingng title { get; set; } public ssortingng type { get; set; } }
et spécifiez [FromBody]MyModel myModelObj
tant que paramètre transmis:
[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)
Ensuite, vous pouvez append ceci dans cette fonction et l’enregistrer en utilisant Entity Framework:
MY_ATTACHMENT_TABLE_MODEL tblAtchm = new MY_ATTACHMENT_TABLE_MODEL(); tblAtchm.Name = myModelObj.name; tblAtchm.Type = myModelObj.type; tblAtchm.File = System.Convert.FromBase64Ssortingng(myModelObj.file); EntityFrameworkContextName ef = new EntityFrameworkContextName(); ef.MY_ATTACHMENT_TABLE_MODEL.Add(tblAtchm); ef.SaveChanges();
tblAtchm.File = System.Convert.FromBase64Ssortingng(myModelObj.file);
être la ligne opératoire.
Vous auriez besoin d’un modèle pour représenter la table de firebase database:
public class MY_ATTACHMENT_TABLE_MODEL { [Key] public byte[] File { get; set; } // notice this change public ssortingng Name { get; set; } public ssortingng Type { get; set; } }
Cela sauvegardera les données dans un varbinary(max)
sous la byte[]
un byte[]
. Name
et Type
étaient respectivement nvarchar(250)
et nvarchar(10)
. Vous pouvez inclure la taille en l’ajoutant à votre table en tant que colonne int
& MY_ATTACHMENT_TABLE_MODEL
tant que public int Size { get; set;}
public int Size { get; set;}
, et ajoutez la ligne tblAtchm.Size = System.Convert.FromBase64Ssortingng(myModelObj.file).Length;
au dessus.
Oracle
Réponse courte: Convertissez-le en un byte[]
, assignez-le à un OracleParameter
, ajoutez-le à votre OracleCommand
et mettez à jour le champ BLOB
votre table en utilisant une référence à la valeur ParameterName
du ParameterName
:BlobParameter
Réponse longue: Quand je l’ai fait pour Oracle, j’utilisais OpenFileDialog
et j’ai récupéré et envoyé les informations sur les octets / fichiers de la manière suivante:
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) { ssortingng 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); }
Et dans la mise à jour Oracle, faite avec ADO:
public void RunCommand(ssortingng sql, OracleParameter param) { OracleConnection oraConn = null; OracleCommand oraCmd = null; try { ssortingng connSsortingng = GetConnSsortingng(); oraConn = OracleConnection(connSsortingng); 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 ssortingng GetConnSsortingng() { ssortingng host = System.Configuration.ConfigurationManager.AppSettings["host"].ToSsortingng(); ssortingng port = System.Configuration.ConfigurationManager.AppSettings["port"].ToSsortingng(); ssortingng serviceName = System.Configuration.ConfigurationManager.AppSettings["svcName"].ToSsortingng(); ssortingng schemaName = System.Configuration.ConfigurationManager.AppSettings["schemaName"].ToSsortingng(); ssortingng pword = System.Configuration.ConfigurationManager.AppSettings["pword"].ToSsortingng(); // hopefully encrypted if (Ssortingng.IsNullOrEmpty(host) || Ssortingng.IsNullOrEmpty(port) || Ssortingng.IsNullOrEmpty(serviceName) || Ssortingng.IsNullOrEmpty(schemaName) || Ssortingng.IsNullOrEmpty(pword)) { return "Missing Param"; } else { pword = decodePassword(pword); // decrypt here return Ssortingng.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 ); } }
Et le type de données pour la colonne FILE_CONTENTS
était BLOB
, le FILE_SIZE
était NUMBER(10,0)
, LAST_MODIFIED
était DATE
et les autres étaient NVARCHAR2(250)
.
Oui, le meilleur moyen de stocker un fichier dans une firebase database consiste généralement à enregistrer le tableau d’octets dans une colonne BLOB. Vous souhaiterez probablement que deux colonnes stockent en plus les métadonnées du fichier, telles que le nom, l’extension, etc.
Il n’est pas toujours judicieux de stocker des fichiers dans la firebase database – par exemple, la taille de la firebase database augmentera rapidement si vous y stockez des fichiers. Mais tout dépend de votre scénario d’utilisation.