Writing Video Files in Java - java

I'm trying to find a way to save a video file. Initially I'd put the video files as blob data into a database, and now, I'm trying to get the blob data back, convert it into bytes, and then write it to a new file. I've been successful in doing this, but the problem is, I can't make the resulting files to run. I tried storing, retrieving, and writing .flv and .mp4 files, but neither work :/ Can anyone help me? Much appreciated! :)
Here is my code: :)
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection(connectionURL, "root","password");
Statement st1 = (Statement) con.createStatement();
PreparedStatement pstmt = null;
ResultSet rs = null;
pstmt = con.prepareStatement("SELECT video_file from video where video_id = " + video_id);
rs = pstmt.executeQuery();
Blob blob = null;
byte[] blyte = null;
if(rs.next()) {
blob = rs.getBlob("video_file");
InputStream is = blob.getBinaryStream();
FileOutputStream fos = new FileOutputStream("C:\\Downloads\\file2.mp4");
int b = 0;
while(b != -1){
fos.write(b);
b = bis.read();
}
}
//exceptions beyond this point
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (ClassNotFoundException e) {
} catch (SQLException e) {
} catch (FileNotFoundException e) {
} catch (IOException e) {
}

There is a '\0' byte written to fos in first iteration of the while-loop which does not come from bis.read().

Related

using java jdbc downloading blob(audio) from mysql.Things goes well, but I cant play the audio

As the title described, when I download the blob(audio) file from MySQL, things goes well and I get the file, but I can't play the audio immediately, unless I terminate the progress.
I guess the audio file is being occupated by the program, if so how can I solve this problem without terminate the program. thx!
Here the code:
public void downloadAudio(int documentid,String pathname) {
String sql = "SELECT storage FROM chatroom_tool WHERE documentid=?";
ResultSet rSet = null;
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, documentid);
rSet = pstmt.executeQuery();
File file = new File(pathname);
FileOutputStream output = new FileOutputStream(file);
System.out.println("writing to file: " + file.getAbsolutePath());
while (rSet.next()) {
InputStream inputStream = rSet.getBinaryStream("storage");
byte[] buffer = new byte[1024];
while (inputStream.read(buffer) > 0) {
output.write(buffer);
}
}
System.out.println("downLoad success +++++");
} catch (SQLException | IOException e) {
e.printStackTrace();
}finally{
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Here is the picture when I open the audio without terminating the program.
image
inputStream.read does not have to fill the array with data completely, it returns the number of bytes it read. You must use the return value when you write the data to the output stream.
while ((bytes =inputStream.read(buffer)) >0)
output.write(buffer, bytes);
Also you have to close the output stream - Windows does not let other apps open the file as long as your program has it open

Java Apache POI and JDBC: Smart way to fetch huge amount of data into Excel [duplicate]

This question already has answers here:
Writing a large resultset to an Excel file using POI
(7 answers)
Closed 6 years ago.
I want to fetch a huge amount of data (over 100.000 rows with 50 columns) from my Oracle database into an Excel File using Java Apache POI and Oracle JDBC. That is working well for small amount of data but what is the smartest way to handle tasks like this? Maybe using multithreading? I get errors like "java.lang.OutOfMemoryError: Java heap space" although I already increased the memory to 1024MB.
This is my current code:
public void fetchDataIntoExcelFile(String sqlStmt){
// Check whether jdbc driver exists or not
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("Please install the Oracle JDBC Driver!");
e.printStackTrace();
return;
}
// Try to establish a connection to the db
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:#myserver", "user", "password");
} catch (SQLException e) {
e.printStackTrace();
return;
}
XSSFWorkbook wbx = new XSSFWorkbook();
XSSFSheet sheet = wbx.createSheet();
FileOutputStream fos = null;
try {
fos = new FileOutputStream("filename.xlsx");
wbx.write(fos);
} catch (IOException e) {
e.printStackTrace();
System.out.println("Error occured while creating file.");
}
// Execute SQL Statement if connection was successful
if (conn != null) {
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sqlStmt);
ResultSetMetaData columns = rs.getMetaData();
XSSFRow row = null;
XSSFCell cell = null;
// Start writing results into the excel file
int i = 0;
while (rs.next()){
row = sheet.createRow(i++);
for (int j = 1; j <= columns.getColumnCount(); j++){
cell = row.createCell(j);
if (i == 1){
cell.setCellValue(columns.getColumnLabel(j));
}else{
cell.setCellValue(rs.getString(columns.getColumnLabel(j)));
}
}
}
try {
wbx.write(fos);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Connection Failed!");
e.printStackTrace();
return;
}
} else {
System.out.println("Failed to make connection!");
}
}
It helped to use the SXSSF API as suggested. Here is the link:
https://poi.apache.org/spreadsheet/how-to.html#sxssf

Updating JLabel via SetIcon from bytea data type in postgres

I am retrieving gif images from Wolfram|Alpha. In an effort to minimize queries I want to store those images and only query W|A when the data is changed, so I am storing the images as a bytea data type in my postgres db. The "save" portion seems to be working because there is data. System.out.println(rs.getString("fnPlotImg")) yields this: \x4275666665726564496d6167654035356437373834323a2074797065203d203120446972656374436f6c6f724d6f64656c3a20726d61736b3d66663030303020676d61736b3d6666303020626d61736b3d666620616d61736b3d3020496e7465676572496e7465726c65617665645261737465723a207769647468203d2032303020686569676874203d20313335202342616e6473203d203320784f6666203d203020794f6666203d203020646174614f66667365745b305d2030
I have been able to successfully update the image from W|A using this bit of code:
String path = ((WAImage) element).getURL();
URL url = new URL(path);
BufferedImage image = ImageIO.read(url);
picLabel.setIcon(new ImageIcon(image));
I would like to update my application with the image from the database and have attempted this code:
byte[] ba = rs.getBytes("fnPlotImg");
try{
picLabel.setIcon(new ImageIcon(ba));
} catch (NullPointerException e) {
e.printStackTrace();
}
My rationale is that bytea is a byte array, getBytes() is supposed to retrieve a byte array, and ImageIcon() is supposed to handle a byte array.However, if I don't build in a null pointer exception it errors out. I presume this is because I am not saving the image to DB correctly or I am not retrieving it correctly.
All thoughts are welcome, I'm getting fatigued so I'll check in the morning with fresh eyes.
I don't have a installation of PostgreSQL available, but I think you should be writing/reading the image format and not the BufferedImage data.
For example, writing might look something like...
Connection con = ...;
BufferedImage img = ...;
try (PreparedStatement stmt = con.prepareStatement("insert into tableofimages (image) values (?)")) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(img, "png", baos);
try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
stmt.setBinaryStream(1, bais);
int rows = stmt.executeUpdate();
System.out.println(rows + " rows updated");
}
}
} catch (SQLException | IOException exp) {
exp.printStackTrace();
}
And reading might look something like...
Connection con = ...;
try (PreparedStatement stmt = con.prepareStatement("select image from tableofimages")) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
try (InputStream is = rs.getBinaryStream(1)) {
BufferedImage img = ImageIO.read(is);
}
}
}
} catch (SQLException | IOException exp) {
exp.printStackTrace();
}

Issue with getBinaryStream(index)

I am getting null value when I am reading the blob data from database. What might be the issue? Can some one help me on this?
Connection con = null;
PreparedStatement psStmt = null;
ResultSet rs = null;
try {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
con =
DriverManager.getConnection("jdbc:oracle:thin:#MyDatabase:1535:XE","password","password");
System.out.println("connection established"+con);
psStmt = con
.prepareStatement("Select Photo from Person where Firstname=?");
int i = 1;
psStmt.setLong(1, "Nani");
rs = null;
rs = psStmt.executeQuery();
InputStream inputStream = null;
while (rs.next()) {
inputStream = rs.getBinaryStream(1);
//Blob blob = rs.getBlob(1);
//Blob blob1 = (Blob)rs.getObject(1);
//System.out.println("blob length "+blob1);//rs.getString(1);
}
System.out.println("bytessssssss "+inputStream);//here i am getting null value.
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I believe you didn't use setString function to assign any value to firstname which leads to null
for example:
ps.preparedStatement("Select photo from person where firstname = ?");
ps.setString(1,"kick"); <----- add this line
system.out.println("bytes "+rs.getBinaryStream(1));
Another suggestions
there is no need to use rs = null; inside try catch block because you have rs=null; at beginning of
your code.
change
InputStream inputStream = null;
to
InputStream inputStream = new InputStream();
or
get rid of InputStream inputStream = null;
source you should take a look at
The most obvious error is using setLong instead of setString.
However one practice is fatal: declaring in advance. This in other languages is a good practice, but in java one should declare as close as possible.
This reduces scope, by which you would have found the error! Namely inputStream is called after a failed rs.next() - outside the loop. Maybe because no records were found.
This practice, declaring as near as feasible, also helps with try-with-resources which were used here to automatically close the statement and result set.
Connection con = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(
"jdbc:oracle:thin:#MyDatabase:1535:XE","password","password");
System.out.println("connection established"+con);
try (PreparedStatement psStmt = con.prepareStatement(
"Select Photo from Person where Firstname=?")) {
int i = 1;
psStmt.setString(1, "Nani");
try (ResultSet rs = psStmt.executeQuery()) {
while (rs.next()) {
try (InputStream inputStream = rs.getBinaryStream(1)) {
//Blob blob = rs.getBlob(1);
//Blob blob1 = (Blob)rs.getObject(1);
//System.out.println("blob length "+blob1);//rs.getString(1);
Files.copy(inputStream, Paths.get("C:/photo-" + i + ".jpg"));
}
++i;
}
//ERROR System.out.println("bytessssssss "+inputStream);
} // Closes rs.
} // Closes psStmt.
}
1- In your code when setting the parameter's value of SQL query, be sure to use the appropriate data type of the field. So here you should use
psStmt.setString(1, "Nani");
instead of
psStmt.setLong(1, "Nani");
2- Make sure that the query is correct (Table name, field name).
3- Make sure that the table is containing data.

Reading to text file from MySQL

I'm trying to store a text file in a MySQL database, and when needed, save it to a file.
To save the file, I do:
public void saveFile_InDB(File file)
{
try {
String sql = "INSERT INTO sent_emails (fileName, time, clientName) values (?, ?, ?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, new Date().toString());
statement.setString(2, new Date().toString());
InputStream inputStream = new FileInputStream(file);
statement.setBinaryStream(3, inputStream);
int row = statement.executeUpdate();
if (row > 0) {
System.out.println("File saved sucessfully.");
}
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
And to retreive and save the file:
public void retrieveFile_fromDB()
{
try {
Statement stmt = (Statement) conn.createStatement();
ResultSet res = stmt.executeQuery("SELECT * FROM sent_emails WHERE clientName='sally'");
FileOutputStream fos = new FileOutputStream("file.txt");
if (res.next()) {
Blob File = (Blob) res.getBlob("fileName");
InputStream is = File.getBinaryStream();
int b = 0;
while ((b = is.read()) != -1) {
fos.write(b);
}
fos.flush();
}
} catch (IOException e) {
e.getMessage (); e.printStackTrace();
System.out.println(e);
} catch (SQLException e) {
e.getMessage (); e.printStackTrace();
System.out.println(e);
}
}
Storing the file works, but when I try to retrieve and save it, nothing is stored in the output file?
if you want read file from db Mysql
change this part in your code
Blob File = (Blob) res.getBlob("fileName");
InputStream is = File.getBinaryStream();
int b = 0;
while ((b = is.read()) != -1) {
fos.write(b);
}
fos.flush();
use this code read array of bytes
byte [] bs=res.getBytes("fileName");
fos.write(bs);
it will work
if you return multiple files from db you must declare
FileOutputStream fos = new FileOutputStream("file.txt");
inside while loop and change name of file to avoid overriding
You do not seem to put into the database the things that the column names describe?
fileName and time are for example both set to a timestamp, and clientName is set to the contents of the file. When you later try to select based on clientName, you are actually selecting based on the contents of the file.
Furthermore, when reading the data, you are reading the blob data from the column fileName, but this is wrong because:
fileName contains new Date().toString(), not the contents of the file
fileName should surely contain the file's name, not its contents?

Categories

Resources