store a file into a database and retrive it

hi

I want to store my generated xml files into a database and then retrive some of them. my data type in sql server database is Image. my algorithm works OK with images but when I try to store xml files I miss a few characters from the end of the retrived xml file. and for some heavier xml files have the same problem with some rubbish characters attached to the end of the file. what's going on file is a file. if my algorithm had problem it shouldn't work with Images either.



Answer this question

store a file into a database and retrive it

  • GS80

    I propose that the code you use to read the file isn't working properly.  I'm assuming you're reading it in using a buffer of a certain size   Can we see the code you use to load the file into memory

    As for storing it in the database, you could store it using the XML type (assuming you're using SQL Server), or a normal text type.  However I doubt the type is causing the problem.  As you always get out what you put in.

     


  • Rod Yager

    Ok yes, all files are binary, but they contain different encoding, classicly a text file(xml) is not considered to be a binary file, based on that coding, ie one may be ascii the other may be base64.

    Paul stated correctly that it is the way in which you read and write binary files that is important, and specific to the encoding, however a byte array is always going to be an array of bytes.

    So we agree on that, totally.

    My recommendation that your xml be converted into a binary format (base64, hex16 etc) before inserting into the image field was incorrect, my concern was that SQL would in fact handle the data differently expecting it encoded/or encoding it in a different way, however text, and image fields are handled in the same maner : http://www.microsoft.com/technet/prodtechnol/sql/2000/reskit/part3/c1161.mspx mfr=true

    I applogise for my absurd suggestion, and will fast for 5 days and sleep on the cold floor outside over the entire xmas period.

    Regards






  • bobbins

    thank you for your response

    the the field will not always been filled with xml files, it can also be CSV, Text or in future maybe something else.

    I would rather to dont store a file into the hard disk at all and save it into a MemoryStream instead and then store it into the database directly but I couldn't

    here is my codes. it mostly comes from msdn documentation:

    public void retrive_file_partly()

    {

    CommonMethods_class c = new CommonMethods_class();

    SqlConnection connection = new SqlConnection(c.Get_connection_string());

    SqlCommand command = new SqlCommand("Select * from temp", connection);

    // Writes the BLOB to a file

    FileStream stream;

    // Streams the BLOB to the FileStream object.

    BinaryWriter writer;

    // Size of the BLOB buffer.

    int bufferSize = 50;

    // The BLOB byte[] buffer to be filled by GetBytes.

    byte[] outByte = new byte[bufferSize];

    // The bytes returned from GetBytes.

    long retval;

    // The starting position in the BLOB output.

    long startIndex = 0;

    // Open the connection and read data into the DataReader.

    connection.Open();

    SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

    while (reader.Read())

    {

    // Create a file to hold the output.

    stream = new FileStream(

    "C:\\retrive.xml", FileMode.OpenOrCreate, FileAccess.Write);

    writer = new BinaryWriter(stream);

    // Reset the starting byte for the new BLOB.

    startIndex = 0;

    // Read bytes into outByte[] and retain the number of bytes returned.

    retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);

    // Continue while there are bytes beyond the size of the buffer.

    while (retval == bufferSize)

    {

    writer.Write(outByte);

    writer.Flush();

    // Reposition start index to end of last buffer and fill buffer.

    startIndex += bufferSize;

    retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);

    }

    // Write the remaining buffer.

    if (retval != 0)

    writer.Write(outByte, 0, (int)retval - 1);

    writer.Flush();

    // Close the output file.

    writer.Close();

    stream.Close();

    }

    // Close the reader and the connection.

    reader.Close();

    connection.Close();

    }


  • Sudheer Kandali

    GavH:

    SQL expects an image column to be binary, an xml file is not binary, it is text utf* .

    All files are binary, they are all sequences of bytes.  So it's not even an issue if he reads the whole thing into a byte array and then stores it in the database as an image.  It's only an issue when he comes to change that byte array into a string.  If he writes the file back to disk in exactly the same sequence then it will be exactly the same file.

    You should not really insert text into a binray field, you should insert it into a text/xml field. If you must sinsert into the same field then you need to convert the xml file format to binary

    Can you give a reason why he should convert the xml format to binary   It's absurd to suggest that he does.


  • AliOmar3333

    Hi ashk1860

    Sorry you did not get a solution,

    Updating your GetFile method should fix your problem, consider the following :

    public byte[] GetFile(string filePath)
    {
    //binary friendly read
    /*
    FileStream stream = new FileStream(
    filePath, FileMode.Open, FileAccess.Read);
    BinaryReader reader = new BinaryReader(stream);
    byte[] file = reader.ReadBytes((int)stream.Length);
    reader.Close();
    stream.Close();
    return file;
    */


    //text friendly read
    /*
    FileStream stream = new FileStream(filePath,FileMode.Open,FileAccess.Read);
    StreamReader reader = new StreamReader();

    string file = reader.ReadToEnd();
    reader.Close();
    return (new UnicodeEncoding()).GetBytes(file);
    */

    //very friendly read - no file format assumed
    FileStream stream = new FileStream(filePath,FileMode.Open,FileAccess.Read);
    byte[] buffer = new byte[stream.Length];

    //this is not really good practice as the entire stream may not be availble
    //in one chunk, such as with a slow network share, however :
    stream.Read(buffer, 0, (int)stream.Length);
    stream.Close();
    return buffer;
    }

    Regards


  • HumteeDumbtee

    SQL expects an image column to be binary, an xml file is not binary, it is text utf* .

    You should not really insert text into a binray field, you should insert it into a text/xml field. If you must sinsert into the same field then you need to convert the xml file format to binary, and will have to convert it back to text to use it again when you retrieve it.

    Consider the following for how to that on the .Net side http://www.codeproject.com/cs/library/BinaryStringFun.asp

    or (More specific to your specific issue but in VB.Net)

    http://www.motobit.com/tips/detpg_read-write-sql-image-file/

    Regards



  • arcliner

    dear GavH:

    I am trying your solution

    and dear Poul:

    I have the same problem with rubbish characters for all xml files

    here is my file reader methods: (if I had bug, it shouldn't work for Images and for example exe files either)

    public static void Addfile(string path)

    {

    CommonMethods_class k = new CommonMethods_class();

    byte[] file = GetFile(path);

    using (SqlConnection connection = new SqlConnection(k.Get_connection_string()))

    {

    SqlCommand command = new SqlCommand("INSERT INTO temp (examplefile) Values(@File)", connection);

    command.Parameters.Add("@File", SqlDbType.Image , file.Length).Value = file;

    connection.Open();

    command.ExecuteNonQuery();

    }

    }

    public static byte[] GetFile(string filePath)

    {

    FileStream stream = new FileStream(

    filePath, FileMode.Open, FileAccess.Read);

    BinaryReader reader = new BinaryReader(stream);

    byte[] file = reader.ReadBytes((int)stream.Length);

    reader.Close();

    stream.Close();

    return file;

    }

    by the way, if you have any suggestion to store a memory stream into the database please tell me. or maybe it's better to open another thread.


  • mlgray

    Ok at a quick glance that looks like it may work, although your buffer loop could be simplified:

    // Create a file to hold the output.
    stream = new FileStream("C:\\retrive.xml", FileMode.OpenOrCreate, FileAccess.Write);
    writer = new BinaryWriter(stream);

    // Reset the starting byte for the new BLOB.
    startIndex = 0;

    do
    {
    // Read bytes into outByte[] and retain the number of bytes returned.
    retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
    writer.Write(outByte, 0, (int)retval);
    startIndex += retval;

    } while (retval != 0);

    writer.Flush();

    // Close the output file.
    writer.Close();
    stream.Close();

    You may also have a bug in the file-reader, which reads your XML file into memory before placing it in the database. Could we see that


  • store a file into a database and retrive it