i have created simple project save blob file data into oracle database using c# winform and worked fine. Now, i wanna play video from blob oracle data using c# but i couldn't. here is my code:
if (koneksidb.con.State == ConnectionState.Open)
{
koneksidb.con.Close();
}
koneksidb.con.Open();
OracleCommand cmd = new OracleCommand();
OracleDataReader dr;
cmd.CommandText = #"SELECT ID,FILENAME, FILEDATA, KETERANGAN, SUBSTR(FILENAME, -4)AS FILEEXTENTION FROM LATIHANFILEMANAGER WHERE ID = '1' AND ISPREVIEW = N'1'";
cmd.Connection = koneksidb.con;
dr = cmd.ExecuteReader();
while (dr.Read())
{
string fileExtention = dr["FILEEXTENTION"].ToString(); //got file extention from database
switch(fileExtention)
{
case ".pdf": //when blob is pdf file worked fine
byte[] FileBytes = (byte[])dr["FILEDATA"];
System.IO.MemoryStream stream = new System.IO.MemoryStream(FileBytes);
fmPdfViewer f = new fmPdfViewer();
f.pdfViewer1.LoadDocument(stream); //when file .pdf i can display preview using pdf viewer in devexpress
f.Show();
break;
case ".mp4": //when blob is video
string path = ""; //here the problem how can i play file video from blob oracle data
fmVideoViewer vd = new fmVideoViewer();
vd.axWindowsMediaPlayer1.URL = path;
vd.axWindowsMediaPlayer1.settings.autoStart = true;
vd.Show();
break;
}
}
dr.Close();
really need the solution, thanks before.
You can save the file on disk and play it.
byte[] bytes = (byte[])dr["FILEDATA"];
string name = (string)dr["FILENAME"] + (string)dr["FILEEXTENTION"];
var path = System.IO.Path.Combine(Application.StartupPath, name);
System.IO.File.WriteAllBytes(path , bytes);
this.axWindowsMediaPlayer1.URL = path;
this.axWindowsMediaPlayer1.Ctlcontrols.play();
You can use Application.StartupPath or any other path you prefer to cache files.
After a while it's better to cleanup cached files.
Related
We are trying to store an executable(exe) file in SQL. We are getting no error either writing or reading. Just the file we stored is not working after downloading back.
This is how we store the file:
databaseFilePut(#"FilePath", con, dt.Rows[0].ItemArray[0].ToString(), "ASIL");
And this is the inside of the function:
public static void databaseFilePut(string varFilePath, SqlConnection con, string version, string OFSET )
{
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 sqlWrite = new SqlCommand("UPDATE ERP_TOOL_UPDATE SET Version=#Version1, ExeDosyasi= #ExeDosyasi1, OFSET= #OFSET1", con))
{
sqlWrite.Parameters.AddWithValue("#Version1", (double.Parse(version) + 1).ToString());
sqlWrite.Parameters.Add("#ExeDosyasi1", SqlDbType.VarBinary, file.Length).Value = file;
sqlWrite.Parameters.AddWithValue("#OFSET1", "ASIL");
sqlWrite.ExecuteNonQuery();
}
}
After saving to the database this is what the data like:
0x4D5A90000300000004000000FFFF0000B8000.... and goes on.
After reading we try to recreate the stored exe with this code:
SqlCommand com = new SqlCommand("Select ExeDosyasi From ERP_TOOL_UPDATE WHERE OFSET = 'ASIL' ", con);
com.CommandType = CommandType.Text;
SqlDataReader reader = com.ExecuteReader();
reader.Read();
byte[] blob;
byte[] blob2;
blob = (byte[])reader[0];
blob2 = System.Text.Encoding.Default.GetBytes(System.Text.Encoding.Unicode.GetString(blob));
using (var fs = new FileStream(#"C:\Users\Bilal\Desktop\ERPAnalizTool.exe", FileMode.Create, FileAccess.Write))
{
fs.Write(blob2, 0, blob2.Length);
fs.Flush();
}
We are not getting any errors, it saves the file. Just the problem is the file has a little bit smaller size. When we try to run, it doesn't run. Like it never was an exe before.
Any help would be appreciated. Thank you all.
Your problem is the following line:
blob2 = System.Text.Encoding.Default.GetBytes(System.Text.Encoding.Unicode.GetString(blob));
The blob variable contains the bytes you wrote to the database, which is the content of the file read in the databaseFilePut method. There is no reason at all to convert it to a Unicode string and then to the system default encoding (Windows-1252 on my system). The data is not a string, it is binary. The double conversion will simply produce a mangled byte sequence.
Simply write the blob variable to disk:
blob = (byte[])reader[0];
File.WriteAllBytes(#"C:\Users\Bilal\Desktop\ERPAnalizTool.exe", blob);
I am using dotnet zip library to create zip file. My files are saved into a database and I am reading each row and load file data into memory from the database and save the memory stream to zip file. my below code works fine.
using System.IO;
using Ionic.Zip;
private void button2_Click(object sender, EventArgs e)
{
using (SqlConnection sqlConn = new SqlConnection(#"Data Source=BBATRIDIP\SQLSERVER2008R2;Initial Catalog=test;Integrated Security=True"))
{
string query = String.Format(#"SELECT Name, ContentType, Data FROM [TestTable]");
SqlCommand cmd = new SqlCommand(query, sqlConn);
cmd.Connection.Open();
System.IO.MemoryStream memStream = null;
ZipFile zip = new ZipFile();
zip.MaxOutputSegmentSize = 1024 * 1024; // 1MB each segment size would be
// the above line would split zip file into multiple files and each file
//size would be 1MB
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
byte[] data = (byte[])reader["Data"];
memStream = new System.IO.MemoryStream(data);
string strFile = reader["Name"].ToString() + "\\" + reader["ContentType"].ToString();
ZipEntry ze = zip.AddEntry(strFile, memStream);
int xx = 0;
}
}
zip.Save(#"e:\MyCustomZip.zip");
memStream.Dispose();
MessageBox.Show("Job Done");
// here u can save the zip in memory stream also there is a overload insteaa of saving in HD
}
}
but if i change a bit into the code then corrupted zip file is creating. if i change this line zip.Save(#"e:\MyCustomZip.zip"); then problem occur.
using (SqlConnection sqlConn = new SqlConnection(#"Data Source=BBATRIDIP\SQLSERVER2008R2;Initial Catalog=test;Integrated Security=True"))
{
string query = String.Format(#"SELECT Name, ContentType, Data FROM [TestTable]");
SqlCommand cmd = new SqlCommand(query, sqlConn);
cmd.Connection.Open();
System.IO.MemoryStream memStream = null;
ZipFile zip = new ZipFile();
zip.MaxOutputSegmentSize = 1024 * 1024; // 1MB each segment size would be
// the above line would split zip file into multiple files and each file
//size would be 1MB
zip.Save(#"e:\MyCustomZip.zip");
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
byte[] data = (byte[])reader["Data"];
memStream = new System.IO.MemoryStream(data);
string strFile = reader["Name"].ToString() + "\\" + reader["ContentType"].ToString();
ZipEntry ze = zip.AddEntry(strFile, memStream);
int xx = 0;
}
}
memStream.Dispose();
MessageBox.Show("Job Done");
// here u can save the zip in memory stream also there is a overload insteaa of saving in HD
}
I want to create zip with zero kb initially and when I will add stream to zip in loop then zip file size will increase gradually. if you see my above code where I try to do that but I got no success. what am I doing wrong in the code?
Another issue
dotnet zip compression ratio not good. i zip a 152 KB doc file with dotnet zip and when zip was created then i was zip file size was 136KB. is there any tweak exist which create small size zip file. share the knowledge. thanks
So, looking at the documentation for ZipFile.Save, we see the following:
Use this when creating a new zip file, or when updating a zip archive.
So, it seems that you need to call this repeatedly to get the "update" behaviour you are looking for. As such just need to move your Save into the loop:
//...
ZipFile zip = new ZipFile();
zip.MaxOutputSegmentSize = 1024 * 1024;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
byte[] data = (byte[])reader["Data"];
memStream = new System.IO.MemoryStream(data);
string strFile =
reader["Name"].ToString() + "\\" + reader["ContentType"].ToString();
ZipEntry ze = zip.AddEntry(strFile, memStream);
zip.Save(#"e:\MyCustomZip.zip");
}
}
With regards to your second question (never a good idea on SO, try to stick to one problem per question):
Without knowing what you are compressing, it's very difficult to speculate about what kind of compression ratio you might achieve. If the data is already compressed (e.g. compressed image/video such as jpeg/h264), zipping isn't going to give you any gains whatsoever. Your only hint about the nature of the content is that it is a "doc". If you're talking about a modern Word document (docx), this is already a zip compressed folder structure. Gains will be minimal. If it's another kind of doc, perhaps it contains embedded (compressed) media? This will also be relatively incompressible.
I'm trying to get attachments (images, word documents, etc.) stored as an Image datatype from a SQL Server database. The attachments can be of any file type, but I'm just trying to get a .jpg to download successfully.
I'm able to save the file to my local drive, but it appears to be corrupting the file in the process.
What I'm trying to do:
Retrieve binary data of type IMAGE from SQL Server Database.
Create a file from the binary data.
Save the file to a local directory.
My CODE:
public void ProcessRequest()
{
//Get the ticket number from query string
_ticketNumber = context.Request.QueryString["ID"];
SqlConnection conn = new SqlConnection(_DBConn);
SqlCommand cmd = new SqlCommand();
string fileName = ""; //Holds the file name retrieved from DB
byte[] data; // Holds the IMAGE data from DB
using (conn)
{
using (cmd)
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT File_Name, Data FROM Tickets_All INNER JOIN Attachments ON Tickets_All.ID = Attachments.[Object_ID] WHERE Ticket = #Ticket";
cmd.Parameters.AddWithValue("#Ticket", _ticketNumber);
cmd.Connection = conn;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
fileName = reader.GetString(0);
data = (byte[])reader["Data"];
if (data != null)
{
SaveData(fileName, data);
}
}
}
reader.Close();
}
}
protected bool SaveData(string FileName, byte[] Data)
{
string path = #"C:\Windows\temp\test.jpg";
try
{
BinaryWriter writer = new BinaryWriter(File.OpenWrite(path));
writer.Write(Data);
writer.Flush();
writer.Close();
}
catch (Exception ex)
{
return false;
}
return true;
}
Please forgive me if the code isn't up to par with best practices, I'm more of a VB programmer and I've never had to do this before. I'm just trying to get a working example.
Thanks in advance.
I would use the Image.FromStream method to do this :
http://msdn.microsoft.com/en-us/library/system.drawing.image.fromstream(v=vs.110).aspx
protected bool SaveData(string FileName, byte[] Data)
{
using (Image image = Image.FromStream(new MemoryStream(Data)))
{
image.Save("MyImage.jpg", ImageFormat.Jpeg);
}
return true;
}
Thanks for the input everyone. After doing some additional testing, I think that the data being retrieved from the database has been compressed in some way. I'm able to insert and pull out files programmatically just fine, the problem comes in when the application puts the data into the database (3rd party software). I'm going to look into the compression what I can come up with.
I am using C#. I want to store PDF files from a Windows forms application to a SQL database. And I want to retrieve it to my Windows Forms application again. What controls can I use to upload PDF files (for example for image I use picture box). What is the data type for PDF files?
Thanks in advance
To select a file you can use OpenFileDialog
Saving any file into database
You'd better store pdf in file storage and save link to it in database.
To store a PDF file in your SQL Server Database, you need to store the contents of the file in BinaryData field. However, I am sure that you will face so many problem with this setup, that you would do better to save your file contents in the SystemData folder and just store the file path or name in to DB.
This will be much more reliable and easy to maintain.
Another approach if your application is storing only files, is to use MongoDb instead of SQL Server. I am not familiar with that, but quite sure that this will be an easy and good solution.
There is an app in the Windows App Store specifically for storing PDF file info and PDF metadata in a SQL database.
You can then search and filter that database using simple, standard SQL queries.
https://www.microsoft.com/en-us/store/p/pdfdb/9n4z1l2hc2c0
public void getTestReportDocument(string reportid, string extenstype)
{
try
{
string filesName = "";
if (sqlConn.State == ConnectionState.Closed)
sqlConn.Open();
if(extenstype == ".pdf")
{
filesName = Path.GetTempFileName();
}
else
{
filesName = Path.GetTempFileName() + extenstype;
}
SqlCommand cmd = new SqlCommand("GetTestReportDocuments", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ReportID", reportid);
using (SqlDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.Default))
{
while (dr.Read())
{
int size = 1024 * 1024;
byte[] buffer = new byte[size];
int readBytes = 0;
int index = 0;
using (FileStream fs = new FileStream(filesName, FileMode.Create, FileAccess.Write, FileShare.None))
{
while ((readBytes = (int)dr.GetBytes(0, index, buffer, 0, size)) > 0)
{
fs.Write(buffer, 0, readBytes);
index += readBytes;
}
}
}
}
Process prc = new Process();
prc.StartInfo.FileName = filesName;
prc.Start();
}
catch (Exception ex)
{
throw ex;
}
finally
{
//daDiagnosis.Dispose();
//daDiagnosis = null;
}
}
Take a look at this screenshot for the solution.
I have been able to upload an image to sql server, in binary format. This is the code that I am using to upload it..
protected void Button2_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string filename = FileUpload1.FileName;
Stream imgStream = FileUpload1.PostedFile.InputStream;
int imgLen = FileUpload1.PostedFile.ContentLength;
byte[] imgBinaryData = new byte[imgLen];
string strCm = "s_PictInsert";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.Add(new SqlParameter("#TheImage", SqlDbType.Image)).Value = imgBinaryData;
Cn.Open();
cm.ExecuteNonQuery();
Cn.Close();
}
}
When I look at the database, all I see in the database, of the pic I uploaded, is 0x00000000000000 etc...I don't know why it looks like that...
Then I am using this code to retrieve the image..
protected void Button3_Click(object sender, EventArgs e)
{
string strCm = "select TheImage from [Pictures] where PictureID = 2";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.Text;
Cn.Open();
SqlDataReader dr = cm.ExecuteReader();
if (dr.Read())
{
Response.ContentType = "image/jpg";
Response.BinaryWrite((byte[])dr["TheImage"]);
}
Cn.Close();
}
when I click the button it doesn't show me the image it just writes the markup out to the page.
What I want to do is retrieve the image and put it to an asp image, the thing is the images that I upload can be .png format.
I only used response.binarywrite is because that is what I was shown to do. But it doesn't work the way I was told it would.
Thanks
The problem is with your upload function, you are not setting imgBinaryData with the data from the file stream, you are only settings the size to match, so it will default to all zeros.
Instead of this part:
byte[] imgBinaryData = new byte[imgLen];
Replace it with this:
byte[] imgBinaryData = null;
using (var reader = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
imgBinaryData = reader.ReadBytes(FileUpload1.PostedFile.ContentLength);
}
Then check to see what your database data looks like.
On a side note, I would recommend always storing file name and MIME type when storing files in a database, you never know when you will need them!
try this:
var length = FileUpload1.PostedFile.ContentLength;
Byte[] imgBinaryData = new Byte[length];
var stream = FileUpload1.FileContent;
stream.Read(imgBinaryData, 0, length);
then insert the binary object. Your code does not read the image into the stream for insertion. The above code should read the image into the byte array, then your db code should insert actual data instead of the placeholder.
You are storing image in binary format to the database, you will retrieve the same. You need to use MemoryStream to get the image from the byte array that you retrieved.
See this :
Retrieve image from database and display on ASP.NET without httphandler