Is it possible to create a file in memory instead of on HDD. If yes, then how?
I want to avoid creating a temporary file on the HDD for security reasons.
Printable View
Is it possible to create a file in memory instead of on HDD. If yes, then how?
I want to avoid creating a temporary file on the HDD for security reasons.
Hi.
Instead of writing your data to a filestream you could use a memorystream.
I am trying to read a binary (bitmap) data from database (a separate thread). On retrieval the data is returned as string whereas I need it as byte() which I then route through memorystream to a bitmap. But it doesn't quite work as getchunk returns a string!
The workaround would be to create a HDD file from getChunk and do a image.FromFile, and that's why the question (to avoid a HDD file).
So, if a memorystream can simulate this, it would be nice. But from what little I know about memorystream, it can be filled using byte() (back to where I started).
The simple answer would be to not use GetChunk then. Maybe this will help:
http://www.edneeis.com/tutorial.aspx?ID=7
Thanks for the help.
Problem is: I don't know how to connect to Access database using SQLClient. I've all along used ADODB. I've tried the example with OleDb but still same casting error.
In the code you've linked to, I presume that DataRow passed to ExportImageFromDB is coming from a Dataset.
Yes the datarow would be for a dataset and the overloaded version handles the datareader. To switch it to Oledb just replace any reference to Sql components with Oledb and/or add an imports System.Data.Oledb. So SqlDataReader would be OledbDataReader with the imports at the top.
I still get the error: "Specified cast in not valid"!!!
Is it something in setup of my vb.net? I am using vb.net 2003 (not the studio) on XP Pro.
VB Code:
Option Strict Off Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim conn As OleDb.OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\TEMP\DB1.MDB") conn.Open() Dim cmd As New OleDb.OleDbCommand("SELECT * FROM BMP", conn) Dim da As New OleDb.OleDbDataAdapter(cmd) Dim cb As New OleDb.OleDbCommandBuilder(da) Dim ds As New DataSet Dim dr As DataRow Dim odr As OleDb.OleDbDataReader odr = cmd.ExecuteReader odr.Read() MsgBox(odr.Item("LEN_BMP")) Dim mydata() As Byte Try mydata = CType(odr.Item("BMP"), Byte()) Catch ex As Exception MsgBox(ex.Message) End Try End Sub
When you get an exception you should check it's stacktrace property for more information (like the line number that is causing the ruckus). These lines are not needed:
Dim da As New OleDb.OleDbDataAdapter(cmd)
Dim cb As New OleDb.OleDbCommandBuilder(da)
Dim ds As New DataSet
Dim dr As DataRow
VB Code:
Option Strict Off Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim conn As OleDb.OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\TEMP\DB1.MDB") conn.Open() Dim cmd As New OleDb.OleDbCommand("SELECT * FROM BMP", conn) Dim odr As OleDb.OleDbDataReader = cmd.ExecuteReader If odr.Read() Then MsgBox(odr.Item("LEN_BMP")) Dim mydata() As Byte Try 'if the next line is where it bombs then you don't have an array of bytes stored in the database mydata= odr.Item("BMP") Catch ex As Exception MsgBox(ex.StackTrace,,ex.Message) End Try End If End Sub
Someone said, either in this thread or a related thread, that if I am getting "Specified cast is not valid (or something like that)", may be the data being retrieved is not binary. Should've listened. Also don't believe when it says memo field can be used for storing images.
So a hundred dollars (for buying books) poorer and after a weekend with out any sleep, I realized that field BMP in table was defned as MEMO. I changed it to OLE Object, and <poof> the error is gone. Not only that, in the debugger/step mode, I can see that the data that comes back is ok.
Well, I chalk up my mistakes to experience, but your mistakes, a different story. ;)
Here's the code.
Button1 inserts a row in empty BMP table, Button2 retrieves it.
VB Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ssql As String Dim sConn As String Dim objDA As OleDbDataAdapter Dim objDS As New System.Data.DataSet Dim objRow As Data.DataRow Dim objDt As Data.DataTable Dim objcb As OleDbCommandBuilder sConn = "Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\TEMP\DB1.MDB" ssql = "SELECT * FROM bmp" objDA = New OleDbDataAdapter(ssql, sConn) objcb = New OleDbCommandBuilder(objDA) objDA.Fill(objDS, "BMP") objDt = objDS.Tables("BMP") objRow = objDt.NewRow() Dim b() As Byte = {96, 97, 98} objRow("BMP") = b objRow("LEN_BMP") = 3 objDS.Tables("BMP").Rows.Add(objRow) objDA.Update(objDS, "BMP") End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim ssql As String Dim sConn As String Dim objDA As OleDbDataAdapter Dim objDS As New System.Data.DataSet Dim objRow As Data.DataRow Dim objDt As Data.DataTable Dim objcb As OleDbCommandBuilder sConn = "Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\TEMP\DB1.MDB" ssql = "SELECT * FROM bmp" objDA = New OleDbDataAdapter(ssql, sConn) objcb = New OleDbCommandBuilder(objDA) objDA.Fill(objDS, "BMP") objDt = objDS.Tables("BMP") objRow = objDt.Rows(0) Dim b() As Byte b = objRow("BMP") End Sub
That concludes our thread. Thanks for joining us and contributing. Have a nice day.
(On your way out, you can contribute to a good cause; Sending me on a vacation.)
I've reopened the thread as the actual subject never got addressed i.e. how to create files in memory without going to HDD!!!
I don't understand now, because you have the image in your byte array , b, in the above code.
Let's pretend that you were saving it to a hdd after you pulled it out of the database, what did you plan on doing with it?
This is what I intend on doing:
Create a bitmap in memory based on certain data.
Display it to user. Once approved by user save it in database.
At a future date, when the need arises, retrieve the image from the database and display it on the monitor or print it.
Since the bitmap may contain sensitive data, I don't want to put it in a file on the HDD. I know, there is always a possibility that paging file may contain such data and some one can actually break into database...but still.
Why not just encrypt the image and save it wherever?
A web app I'm developing does just that... and there's no way unless you know the encryption key (store it in the database, encrypted itself in the registry, or wherever). We save the image on the webserver, and since they are encrypted, there is no way for webmasters to peruse sensitive images.
Here's a sample (not that it automatically works for your setup) which takes a string which is actually a GUID, that the database assigns to new records of the images, and then uses that as the filename for the image on the server.
The code you don't see in this function, creates a Guid for the filename, stores that plus the file's extension, and original filename in the Sql server.
VB Code:
Private Function uploaddata(ByVal newmediaguidname As String) As Boolean 'Variable to hold the FileName Dim m_strFileName As String 'Variable FolderName where the files will be saved Dim m_strFolderName As String = Server.MapPath("/yourwebserver") & "/Data/" 'Variable to hold the File Dim m_objFile As HttpPostedFile 'Variable used in the Loop Dim i As Integer Try 'Get the HttpPostedFile m_objFile = Request.Files(0) 'Check that the File exists, has a name, and is not empty If Not (m_objFile Is Nothing Or m_objFile.FileName = "" Or m_objFile.ContentLength < 1) Then 'Creates the containing folder on the server if it does not exist If (Not Directory.Exists(m_strFolderName)) Then Directory.CreateDirectory(m_strFolderName) End If 'encrypt the stream Dim UE As New UnicodeEncoding Dim des As New RijndaelManaged '<-this is a System.Net class, don't freak out Dim key As Byte() [b]key = UE.GetBytes("aUniqueKeyGoesHere") 'change the string to something unique[/b] Dim myicryptotransform As ICryptoTransform = des.CreateEncryptor(key, key) Dim fileData(m_objFile.InputStream.Length) As Byte m_objFile.InputStream.Read(fileData, 0, m_objFile.InputStream.Length) Dim fs As FileStream = New FileStream(m_strFolderName & newmediaguidname & ".kjb", FileMode.CreateNew) 'i used .kjb, use any made up extension you wish Dim mycryptostream As New CryptoStream(fs, myicryptotransform, CryptoStreamMode.Write) mycryptostream.Write(fileData, 0, fileData.Length) mycryptostream.Close() fs.close() Else Return False End If Catch errorVariable As Exception 'Trap the exception Return False End Try Return True End Function
nemaroller:
Are you sure the above example is for creating a file in the memory? Appears more like how to get file from a webserver.
Ok, I posted that code because it shows how easy it is to just encrypt the images on the web server, where they would most likely be stored, instead of putting them in a database. The code actually encrypts a file submitted to a website, and stores it in the website folder.
If you want to store the image as a string in a database, all you have to do is write the Cryptostream to a streamwriter, which in turns writes to a StringBuilder, and then use StringBuilders' ToString method to grab the string to store in the database.
It be almost identical to my example above, except my examples writes the image to a filestream.
Off the track:
IF you use Image.FromStream , once that is executed, you have the image in MEMORY. What you decide to do with it from there is your choice.
It seems to me all you need to do is encrypt the image, so other users CANNOT just open them up and look at them.
You can store the image in a public folder, on a public web server, or in a database. Either way, they should be encrypted.
The best place to store the image really depends on what your project is, and what you need to accomplish. YOu haven't given us any other details, so I don't know which way to direct you to.
Unless its absolutely necessary, because images are usually large, I would stay away from storing images in databases.
I am writing a signature capture program for Credit card processing and don't fill comfortable about storing such data in files on HDD and hence the database route. Also it is easier for me to find the signature when in database.
VB Code:
'get an imaginary image 'i use a hard drive image to simulate your 'capture' Dim myinputstream As New IO.FileStream("C:\Documents and Settings\Karl\My Documents\My Pictures\babybeyer.jpg", IO.FileMode.Open) Dim myimg As Image = Image.FromStream(myinputstream) myinputstream.Close() 'create a graphics object for the image Dim mybmp As New Bitmap(myimg) 'now we destroy the image source myimg.Dispose() 'we will now save it to memory Dim mymemorystream As New IO.MemoryStream mybmp.Save(mymemorystream, Imaging.ImageFormat.Jpeg) 'we destroyed the image mybmp.Dispose() 'we will now populate the picturebox to prove the image 'came from memory PictureBox1.Image = Image.FromStream(mymemorystream) mymemorystream.Close()
And here's a more complete example, which is probably what you really want, as it shows how to store the image to a string, or a byte array, so you can save that to the database.
NOTE: you'll need two pictureboxes
VB Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'get an imaginary image 'i use a hard drive image to simulate your 'capture' Dim myinputstream As New System.IO.FileStream("C:\test.jpg", IO.FileMode.Open) Dim myimg As Image = Image.FromStream(myinputstream) myinputstream.Close() 'create a graphics object for the image Dim mybmp As New Bitmap(myimg) 'now we destroy the image source myimg.Dispose() 'we will now save it to memory Dim mymemorystream As New System.IO.MemoryStream mybmp.Save(mymemorystream, System.Drawing.Imaging.ImageFormat.Jpeg) 'we destroyed the image mybmp.Dispose() 'we will now populate the picturebox to prove the image 'came from memory 'put image from memory into picturebox PictureBox1.Image = Image.FromStream(mymemorystream) 'now, also store the binary data into a bytearray mymemorystream.Seek(0, System.IO.SeekOrigin.Begin) Dim mybytearray(mymemorystream.Length) As Byte mymemorystream.Read(mybytearray, 0, mymemorystream.Length) mymemorystream.Close() 'convert the bytearray contents to string Dim myencoding As System.Text.UnicodeEncoding = New System.Text.UnicodeEncoding Dim myStringData As String = myencoding.GetString(mybytearray) 'image is now held within a STRING '( put string in databse) '(retrieve string from database) 'now convert the string back into a byte array to prove the image persists 'in the string Dim mydecoding = New System.Text.UnicodeEncoding mybytearray = mydecoding.GetBytes(myStringData) 'now retrieve the data from the byte array, and stick it into the image mymemorystream = New System.IO.MemoryStream(mybytearray, 0, mybytearray.Length) PictureBox2.Image = Image.FromStream(mymemorystream) 'close stream mymemorystream.Close() End Sub
This is really educational and helpful. Thanks Nemaroller.
From the code, it appears that any one with access to the encoded data could really decode the data. I am sure there must be a way of using some key to encode/decode the data. I am a newbie at this stuff.
Thanks once again everyone for your help.
The encoding in the last post of mine was just text encoding, not encryption. The post where you mentioned it looked like a web app, in there, there is the encryption classes... you can use those before you send the data to the database, and then decrypt it when you get the data back.