skip to Main Content

I im trying to store GLTF file in a postgreSQL. I came up with an idea to convert file to byte array with memory Stream. But when i try to convert it back, from byte array to file with System.IO.File.WriteAllBytes i get damaged file.

Is it possible to convert gltf to bytes and then back again?

I was trying to use packages like SharpGLTF, but it does not help.

2

Answers


  1. Chosen as BEST ANSWER

    The trouble was that GLTF2.0 is encoded type of file. Converting it to array crashes its content. The only solution i found was using .obj or .fbx formats.


  2. The basic approach to save or retrieve a file from the database is:

    Read the raw file into a byte[] array.

    Save that byte[] array into the database.

    And to retrieve the file?

    Then get/load/query the database row.

    Cast the binary column into a byte[] array.

    Save/write the byte array to a file.

    So, code to save a file into database will look like this:

    (I’m using SQL server, not PostgreSQL, but the code should be near identical using the PostgreSQL .net database provider).

    So, to save a file to the database, then this:

            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);
    

    And to do the reverse, and get a file from the database, then this:

            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);   
    

    I don’t know what column types are available in PostgreSQL, but a binary or blob type of column should exist, and using such a column type should allow the above process of converting a file to a byte[] array, and then sending that to the database.

    And as the above shows, you reverse the process when wanting to get a valid file from the database. So, get the row you need, convert the blob/binary column to a byte array, and then save that byte array to a file.

    Since we using a byte array, then the file type being text, pdf, a .dll, or whatever does not matter.

    And I used in above some handy helper routines, since I don’t want to type over and over creating the database connection object, and command object.

    So, the helper routines used above from my global static class was:

        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();
                }
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search