I have the below code which stores a List to File and then to a mysql blob column. Is it possible to recover that List from the database?
ArrayList<String> myList = new ArrayList<String>();
File tempFile = File.createTempFile("myFile.temp");
tempFile.deleteOnExit();
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeUnshared(myList);
objectOutputStream.close();
String trailQuery = "INSERT INTO table (tempFile) VALUES (?)";
PreparedStatement preparedStatement = connection.prepareStatement(trailQuery);
preparedStatement.setObject(1, tempFile);
I tried to read that but I get a FileNotFoundException
if (resultSet.next()) {
InputStream fileInputStream = resultSet.getBinaryStream("tempFile");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
File inner = (File) objectInputStream.readObject();
FileInputStream fileInputStreamInner = new FileInputStream(inner);
ObjectInputStream objectInputStreamInner = new ObjectInputStream(fileInputStreamInner);
ArrayList<String> myList = (ArrayList<String>) objectInputStreamInner.readObject();
System.out.println(myList.size());
}
Exception
java.io.FileNotFoundException: \tmp\myFile.1708309680603860570.temp (The system cannot find the path specified)
As #EJP mentioned a java.io.File is nothing more than a holder for a filename... had wrong understanding - so none of the contents of the files are there....
Related
Hi i am trying to read an ArrayList of Integer and get EOFException.
i have a ArrayList of Question which is serialized and i do the same thing for reading it no problem, but with ArrayList Integer dont work.
i write the two ArrayList like so: (im ommiting all the other fields that are not relevant)
String sqlQuery = "insert into test values (?,?,?,?,?,?,?,?,?)";
PreparedStatement pst = null;
try {
if (DBConnector.myConn != null) {
pst = DBConnector.myConn.prepareStatement(sqlQuery);
// serialize object
Blob questionsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(t.getQuestions());
oos.close();
Blob pointsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
oos.writeObject(t.getPointsPerQuestion());
oos2.close();
// store in byte array
byte[] questionsAsByte = baos.toByteArray();
byte[] pointsAsByte = baos2.toByteArray();
// fill blob object with byte array
questionsBlob.setBytes(1, questionsAsByte);
pointsBlob.setBytes(1, pointsAsByte);
pst.setBlob(3, questionsBlob);
pst.setBlob(4, pointsBlob);
pst.executeUpdate();
and read the objects:
String sqlQuery = "select * from test where teacherUsername = \"" + username + "\";";
ArrayList<Test> arr = new ArrayList<Test>();
ArrayList<Question> questions;
ArrayList<Integer> points;
try {
if (DBConnector.myConn != null) {
Statement st = DBConnector.myConn.createStatement();
ResultSet rs = st.executeQuery(sqlQuery);
while (rs.next()) {
questions = new ArrayList<>();
points = new ArrayList<>();
Blob questionsBlob = rs.getBlob(3);
BufferedInputStream bis = new BufferedInputStream(questionsBlob.getBinaryStream());
ObjectInputStream ois = new ObjectInputStream(bis);
questions = (ArrayList<Question>) ois.readObject();
System.out.println(questions);
Blob qPointsBlob = rs.getBlob(4);
BufferedInputStream bis1 = new BufferedInputStream(qPointsBlob.getBinaryStream());
ObjectInputStream ois1 = new ObjectInputStream(bis1);
try {
points = (ArrayList<Integer>) ois1.readObject(); // PROBLEM HERE
}catch(EOFException e) {
System.out.println(points);
}
when i try to read the data - it works with the ArrayList of Question and really shows me the questions, but with the ArrayList of Integer it gives me the EOFException.
any ideas ?
This is how I create a simple zip archive with 3 files
FileOutputStream fos = new FileOutputStream(new File("out.zip"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
for (int i = 0; i < 3; i++) {
String s = "hello world " + i;
ZipEntry entry = new ZipEntry("text" + i + ".txt");
zos.putNextEntry(entry);
zos.write(s.getBytes());
zos.closeEntry();
}
}
baos.writeTo(fos);
How can I put a zip inside zip recursively in one turn on the fly? Is there any way to put ZipOutputStream or ZipEntry inside each other?
EDIT:
Solution as Mark suggested:
FileOutputStream fos = new FileOutputStream(new File("out.zip"));
ByteArrayOutputStream resultBytes = new ByteArrayOutputStream();
ByteArrayOutputStream zipOutStream = new ByteArrayOutputStream();
try (ZipOutputStream zos2 = new ZipOutputStream(zipOutStream)) {
String s = "hello world ";
ZipEntry entry = new ZipEntry("text.txt");
zos2.putNextEntry(entry);
zos2.write(s.getBytes());
zos2.closeEntry();
zos2.close();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
ZipEntry entry = new ZipEntry("text.zip");
zos.putNextEntry(entry);
zos.write(zipOutStream.toByteArray());
zos.closeEntry();
}
baos.writeTo(resultBytes);
resultBytes.writeTo(fos);
I tried to follow the solution using the 'ByteArrayOutputStream' but only manage to create corrupted zip files this way.
I ended up creating a nested ZipOutputStream directly like this:
try (FileOutputStream fos = new FileOutputStream(myZipFile); ZipOutputStream zos = new ZipOutputStream(fos)) {
ZipEntry entry = new ZipEntry("inner.zip");
zos.putNextEntry(entry);
ZipOutputStream nestedZos = new ZipOutputStream(zos);
// write stuff to nestedZos
nestedZos.finish();
zos.closeEntry();
}
The resulting zip file contains the nested structure and is valid.
For the "inner" .ZIP file, you could use a ByteArrayOutputStream instead of a FileOutputStream; then that zip will be built as data in RAM; so you can use the resulting byte array as the data for a ZipEntry in the outer .ZIP file.
I'm trying to update files .ser :
Here's a snippet, without all useless stuffs (try ...etc)
String file1 = "data.ser";
InputStream fis = this.getClass().getResourceAsStream(file1);
InputStream buffer = new BufferedInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(buffer)
ArrayList<Object[]> list = new ArrayList<>();
list = (ArrayList) ois.readObject();
//Reading works fine, I got all my data in list
/*
Some operations in list
*/
OutputStream fout;
fout = new FileOutputStream(file1);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file1));
//Here I tried to verify list; it's okay, all is there
oos.writeObject(list);
//I tried also some print just after that, and it works
This doesn't update my file; what can be the trouble?
PS: on IDE, all is fine, but when running jar, it's not; is that possible that I can't change files in jar ?!
I am trying to insert a file containing into a Sybase database. I am using JConnect-7.0.7
Here is my table:
CREATE TABLE blob_test (
blobVar IMAGE
)
I am inserting the image using:
String sql = "INSERT INTO blob_test VALUES (convert(binary,?))";
PreparedStatement stmt = conn.prepareStatement(sql);
File image = new File(filePath);
InputStream fis = new FileInputStream(image);
int ilen=(int) image.length();
stmt.setBinaryStream(1, fis, ilen);
stmt.execute();
And trying to retrieve the image using:
JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);
List<Blob> result = jdbcTemplate.query(
"SELECT blobVar FROM blob_test", new Object[] {}, new RowMapper() {
#Override
public Blob mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getBlob(1);
}
});
for(int i=0;i<result.size();i++){
Blob b = result.get(i);
BufferedOutputStream os;
os = new BufferedOutputStream(new FileOutputStream(new File("output"+i+".zip")));
os.write(b.getBytes(1, (int) b.length()));
os.flush();
os.close();
}
However, when I execute my code it outputs 1kb zip files that are corrupted. My code works exactly as it should for an oracle database.
Alternatively, I have also tried this code to retrieve the file:
JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);
List<InputStream> result = jdbcTemplate.query(
"SELECT * FROM blob_test", new Object[] {}, new RowMapper() {
#Override
public InputStream mapRow(ResultSet rs, int rowNum) throws SQLException {
return lobHandler.getBlobAsBinaryStream(rs, 1);
}
});
for(int i=0;i<result.size();i++){
InputStream in = result.get(i);
OutputStream out = new FileOutputStream(new File("outputTest"+i+".zip"));
byte[] buff = new byte[4096];
int len = 0;
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.flush();
out.close();
}
However, when I run this code I get an exception:
java.io.IOException: JZ0I9: This InputStream was closed.
at com.sybase.jdbc4.jdbc.ErrorMessage.raiseIOException(Unknown Source) at com.sybase.jdbc4.jdbc.ErrorMessage.raiseIOException(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.checkMe(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.read(Unknown Source)
at com.sybase.jdbc4.jdbc.RawInputStream.read(Unknown Source)
at blobtester.BlobTester.getOracleBlob(BlobTester.java:86)
at blobtester.BlobTester.main(BlobTester.java:34)
Again, this works for oracle. Is there anything I'm missing that is different about Sybase? Is the file being saved/retrieved correctly?
edit:
It turns out the problem was inserting the file into Sybase. I changed the code to:
File image = new File(filePath);
InputStream fis = new FileInputStream(image);
LobHandler lobHandler = new DefaultLobHandler();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("INSERT INTO blob_test VALUES (?)", new Object[] {new SqlLobValue(fis, (int)image.length(), lobHandler)}, new int[] {Types.BLOB});
And it worked for both Sybase and oracle. Thanks.
Code from this link worked: http://forum.spring.io/forum/spring-projects/data/9931-sybase-and-blob-storing
[Just adding an answer, to close the question.]
I am reading the blob data from Oracle database & writing it to a text file. I have two column in my database called Number & system. I have 100 counts in my table. But only the last row is writing in my text row. below is the code I have tried.
rs =stmt.executeQuery("select Number, system from system");
Blob lob = null;
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeBytes(test);
dos.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
In text file i am getting 100th record only other 99 rows are not writing.
You are replacing existing text each time in your while loop.
Try this:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
dos.writeBytes(test+"\n");
}
dos.close();
Replace the line in your code
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
With:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt", true);