Я пытаюсь сохранить файл GLTF в postgreSQL. Мне пришла в голову идея преобразовать файл в массив байтов с помощью потока памяти. Но когда я пытаюсь преобразовать его обратно из массива байтов в файл с помощью System.IO.File.WriteAllBytes, я получаю поврежденный файл.
Можно ли преобразовать gltf в байты, а затем обратно?
Я пытался использовать пакеты типа SharpGLTF, но это не помогает.
Основной подход к сохранению или извлечению файла из базы данных:
Считайте необработанный файл в массив byte[].
Сохраните этот массив byte[] в базе данных.
И получить файл?
Затем получите/загрузите/запросите строку базы данных.
Преобразуйте двоичный столбец в массив byte[].
Сохраните/запишите массив байтов в файл.
Итак, код сохранения файла в базу данных будет выглядеть так:
(Я использую SQL-сервер, а не PostgreSQL, но код должен быть почти идентичен при использовании поставщика базы данных PostgreSQL .net).
Итак, чтобы сохранить файл в базу данных, нужно следующее:
string sFile = Server.MapPath($@"~/UpLoadFiles/control.pdf");
byte[] FileAsBytes = File.ReadAllBytes(sFile);
string sFileNameOnly = Path.GetFileName(sFile);
string strSQL =
@"INSERT INTO tblFiles (FileName, UpLoaded, MineType, FileB)
VALUES (@FileName, @UpLoaded, @MineType, @FileB)";
SqlCommand cmdSQL = new SqlCommand(strSQL);
cmdSQL.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = sFileNameOnly;
cmdSQL.Parameters.Add("@UpLoaded", SqlDbType.DateTime).Value = DateTime.Now;
cmdSQL.Parameters.Add("@MineType", SqlDbType.NVarChar).Value =
MimeMapping.GetMimeMapping(sFile);
cmdSQL.Parameters.Add("@FileB", SqlDbType.Binary).Value = FileAsBytes;
General.MyRstE(cmdSQL);
А чтобы сделать обратное и получить файл из базы данных, то так:
int PK = 3; // for testing database PK row id
SqlCommand cmdSQL = new SqlCommand("SELECT * FROM tblFiles WHERE ID = @ID");
cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PK;
DataTable dt = General.MyRstP(cmdSQL);
string strFile = dt.Rows[0]["FileName"].ToString();
byte[] FileAsBytes = dt.Rows[0]["FileB"] as byte[];
File.WriteAllBytes(strFile, FileAsBytes);
Я не знаю, какие типы столбцов доступны в PostgreSQL, но столбец должен существовать в двоичном или BLOB-типе, и использование такого типа столбца должно позволить описанный выше процесс преобразования файла в массив byte[] и последующую отправку этого в базу данных.
И, как показано выше, вы выполняете обратный процесс, когда хотите получить действительный файл из базы данных. Итак, получите нужную строку, преобразуйте столбец blob/двоичный в массив байтов, а затем сохраните этот массив байтов в файл.
Поскольку мы используем массив байтов, то тип файла: текстовый, pdf, .dll или любой другой не имеет значения.
И выше я использовал несколько удобных вспомогательных процедур, так как я не хочу снова и снова вводить текст, создавая объект подключения к базе данных и объект команды.
Итак, использованные выше вспомогательные процедуры из моего глобального статического класса были:
public static DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public static DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public static void MyRstE(SqlCommand cmdSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
cmdSQL.ExecuteNonQuery();
}
}
}
Конечно, но опять же опубликованный код будет работать с файлами любого типа, и поэтому для приведенного выше кода не существует никаких ограничений. Здесь существуют незначительные преимущества, но, конечно, использование строки вместо массива byte[] по-прежнему является хорошим предложением с вашей стороны.
Проблема была в том, что GLTF2.0 — это закодированный тип файла. Преобразование его в массив приводит к сбою его содержимого. Единственное решение, которое я нашел, — это использование форматов .obj или .fbx.
Я бы предложил прочитать файл, закодировать его в Base64, а затем сохранить в базе данных в виде текста. Читайте в обратном порядке.