Using bytes to save object data from table to database in java - java

After some research it seems that I should be modifying my Object into bytes before sending. As my code is rather extensive i will give it in demonstrative pieces. I have the problem that nothing happens on successful completion of the program.
SAVE and SET variables are named in the following manner within the private void
int count = jTable1.getRowCount();
for(int i=0;i<count;i++){
//SET0
SET0 = new Object[1][count];
SET0[0][i] = txt.getText();
ByteArrayOutputStream baosSET0 = new ByteArrayOutputStream();
ObjectOutputStream oosSET0 = new ObjectOutputStream(baosSET0);
oosSET0.writeObject(SET0.toString());
byte[] SET0asBytes = baosSET0.toByteArray();
ByteArrayInputStream baisSET0 = new ByteArrayInputStream(SET0asBytes);
AND
SAVE = new Object[1][count];
SAVE[0][i] = jTable1.getModel().getValueAt(i,0);
ByteArrayOutputStream baosSAVE = new ByteArrayOutputStream();
ObjectOutputStream oosSAVE = new ObjectOutputStream(baosSAVE);
oosSAVE.writeObject(SAVE.toString());
byte[] SAVEasBytes = baosSAVE.toByteArray();
ByteArrayInputStream baisSAVE = new ByteArrayInputStream(SAVEasBytes);
Which leads into my SQL query:
String sqla1 = "INSERT INTO MIT(MTY_KOD,MTY_TYY,MTY_ALU,MTY_PAR1,MTY_PAR2,MTY_TOL,MTY_KAN,MTY_DATE) values(?,?,?,?,?,?,?,?);";
try{
pst = conn.prepareStatement(sqla1);
pst.setBinaryStream(1, baisSET0 , SET0asBytes.length);
pst.setBinaryStream(2, baisSET2, SET2asBytes.length);
pst.setBinaryStream(3, baisSET1, SET1asBytes.length);
pst.setBinaryStream(4, baisSAVE, SAVEasBytes.length);
pst.setBinaryStream(5, baisSAVE3, SAVE3asBytes.length);
pst.setBinaryStream(6, baisSAVE5, SAVE5asBytes.length);
pst.setBinaryStream(7, baisSET3, SET3asBytes.length);
pst.setBinaryStream(8, baisSET2, SET2asBytes.length);
pst.executeUpdate();}
catch (Exception e) {
System.out.println(e);
}
Event is triggered from:
if(txt.getText().isEmpty()){
}else{
try{
INSERT();}
catch(IOException ex){
System.out.println(ex);
}
}
The error i get is:
com.microsoft.sqlserver.jdbc.SQLServerException: The stream value is not the specified length. The specified length was 35, the actual length is 0.
Can anyone direct me on how to fix this error... or a different method of saving the information? Thank you.

I suspect you need to close your ObjectOutputStream.
From the doc:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Date());
oos.close(); // <-- my emphasis!

Related

Load Lists from Serialized file

For a college project i have to save a hashmap of Lists to a binary file. Then i have to be able to load it again but im having a bit of trouble. It will save my file but will not load it. Here is my code:
This is Saving:
private static void storeRec()
{
try
{
File f = new File("recommendation.dat");
if(!f.exists())
{
f.createNewFile();
}
FileOutputStream fos=new FileOutputStream(f);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(localStore);
oos.flush();
oos.close();
fos.close();
System.out.println("Recommendation read to File");
}
catch (IOException ex)
{
Logger.getLogger(Project2.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the loading code :
List<Recommendation> newmovies = new ArrayList<>();
try
{
File f = new File("recommendation.dat");
if(f.exists())
{
DataInputStream dis = new DataInputStream(new FileInputStream(f));
/*FileInputStream streamIn = new FileInputStream(f);
ObjectInputStream dis = new ObjectInputStream(streamIn);*/
while(dis.available()>0)
{
byte[] titleBytes = new byte[32];
dis.read(titleBytes);
String title = new String(titleBytes);
byte[] queryBytes = new byte[32];
dis.read(queryBytes);
String query = new String(queryBytes);
byte[] directorBytes = new byte[32];
dis.read(directorBytes);
String director = new String(directorBytes);
byte[] summaryBytes = new byte[64];
dis.read(summaryBytes);
String summary = new String(summaryBytes);
byte[] categoryBytes = new byte[18];
dis.read(categoryBytes);
String category = new String(categoryBytes);
//String category = dis.readUTF();
double rating = dis.readDouble();
int release = dis.readInt();
byte[] castBytes = new byte[64];
dis.read(castBytes);
String cast= new String(castBytes);
ArrayList<String> castArrayList = new ArrayList<>(Arrays.asList(cast.split(",")));
int myRating = dis.readInt();
byte[] commentsBytes = new byte[32];
dis.read(commentsBytes);
String myComments = new String(commentsBytes);
newmovies.add(new Recommendation(title,query,director,summary,release,category,rating,castArrayList,myRating,myComments));
//System.out.println(newmovies);
localStore.put(query, newmovies);
}
}
LocalStore is a hashmap i would like to add the data from the file to. The key is the Query. For some reason it will not add to the map
Any help would be very much appreciated.
You have to use an ObjectInputStream on a file created by ObjectOutputStream, and readObject()to read an object written by writeObject().
And available() is not a valid test for end of stream. See the Javadoc. You have to catch EOFException.

ObjectOutputstream overwriting old object without closing stream

What I want to achieve: When I save an Integer object to a file using the writeObject() method from ObjectOutputstream class, I want to overwrite the old Integer object and replace it with the new one. But I don't want to close and open again the stream every time I want to put a new Integer object. I just want to update it with new values.
The solution that I come up with didn't work for me. Here is the code:
ObjectOutputStream stream1 = new ObjectOutputStream(new FileOutputStream(new File("ClientBase"), false));
stream1.writeObject(new Integer(2));
stream1.flush();
stream1.reset();
stream1.writeObject(new Integer(9));
stream1.close();
When I read this, I have two Integer objects instead of an Integer with value 9 replaced by Integer with value 2.
If I put it like this, it works.
ObjectOutputStream stream1 = new ObjectOutputStream(new FileOutputStream(new File("ClientBase"), false));
stream1.writeObject(new Integer(2));
stream1.close();
stream1 = new ObjectOutputStream(new FileOutputStream(newFile("ClientBase"), false));
stream1.writeObject(new Integer(9));
stream1.close();
My question: Am I using the reset() method in a wrong way and is there any other way to achieve overwriting without closing/opening stream?
This is what I tried.
However, note that I'm not sure this code is safe...:
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("objects.file");
ObjectOutputStream os = new ObjectOutputStream(fos)) {
long position = fos.getChannel().position();
os.writeObject(new Integer(2));
os.flush();
os.reset(); // added line
fos.getChannel().position(position);
os.writeObject(new Integer(9));
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

how to set and take in a integer to/from a file in java

So this is a very simple question. I have been trying to research it, and yes I have slightly found some answers but i can't find out how it works so i have come to this.
I am making a simple game in java (pong) and their is a high score integer that i would like to be able save and load from a file (I have heard a lot about using a txt file so probably that, but i have also heard about using a xml i believe is what it is, but i did not look into that as much). How exactly do i program this?
Thank you to all who answer.
PS
I have looked into this code but I don't understand how it's workings
String strFilePath = "C://FileIO//WriteInt.txt";
try {
//create FileOutputStream object
FileOutputStream fos = new FileOutputStream(strFilePath);
DataOutputStream dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
dos.close();
} catch (IOException e) {
System.out.println("IOException : " + e);
}
The most simplest way is to create a file, i.e.
write the score to a file, e.g.
String user = "John";
int score = 100;
f = new BufferedWriter(new FileReader(filepath));
f.write(user + "=" + score); // assuming "=" is not inside the user name
f.close();
then read from the file when you need it, e.g.
f = new BufferedReader(new FileReader(filepath));
String line = f.readLine().trim();
String[] temp = line.split("="); // now temp is of the form ["John", "100"]
String user = temp[0];
int score = Integer.parseInt(temp[1]);
f.close();
I think you can solve this encoding the object into a file,but it wont be an xml, it will be a custom file that only your app will be able to open
public void save(Integer ... integersToEncode){
try{
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream (new File(/*yourFileName*/)));
for(Integer encoding : integersToEncode)
output.writeObject(encoding);
output.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
}
For reading
public Integer[] read(int size){
Integer[] objects = new Integer[size];
try{
ObjectInputStream input = new ObjectInputStream(new FileInputStream (new File(/*yourFileName*/)));
for(int i = 0; i < size ; i++)
objects[i] = (Integer)input.readObject();
input.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
return objects;
}
Maybe you were confused by the way the original code you posted was printing the char 'd' to the output file. This is the character's ASCII value, as you may know. The following modifications to your code make it work the way you were orginally looking at:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Game {
public static void main(String[] args) throws IOException {
Game game = new Game();
game.writeHighScore();
}
public void writeHighScore() throws IOException{
String strFilePath = "C:/Users/User/workspace/HighScore.txt";
FileInputStream is = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try
{
//create FileOutputStream object
fos = new FileOutputStream(strFilePath);
dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
System.out.println("New High Score saved");
dos.close();
// create file input stream
is = new FileInputStream(strFilePath);
// create new data input stream
dis = new DataInputStream(is);
// available stream to be read
while(dis.available()>0)
{
// read four bytes from data input, return int
int k = dis.readInt();
// print int
System.out.print(k+" ");
}
}catch(Exception e){
// if any error occurs
e.printStackTrace();
}finally{
// releases all system resources from the streams
if(is!=null)
is.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
}
}
}

Android read large files crashing app

Hello as you can see below I m trying to make a (android) app which check md5 hash of file
this code works only for small files
can someone help me?
final TextView informations = (TextView) findViewById(R.id.Informations);
final EditText input = (EditText) findViewById(R.id.ToCrack);
String filepath = data.getDataString();
String rawtext;
String hash;
StringBuilder text = new StringBuilder();
filepath = filepath.split("//")[1];
File file = new File(filepath);
Toast.makeText(getApplicationContext(),"Loading: "+filepath,Toast.LENGTH_LONG).show();
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
try{
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while (dis.available() != 0){
text.append(dis.readLine()+"\n");
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
try{
fis.close();
bis.close();
dis.close();
}
catch (IOException ex){
ex.printStackTrace();
}
}
rawtext = text.toString().substring(0, text.length()-1);
hash = new MD5(rawtext).hexdigest();
if (hash.equals(input.getText().toString())){
informations.setText("Hash correspond with the file!");
}
else{
informations.setText("File hash= "+hash+"\nHashes does not correspond :(");
}
Toast.makeText(getApplicationContext(),"Copied file hash to clipboard.",Toast.LENGTH_LONG).show();
Mobile device environments such as Android have limitations w.r.t the amount of memory that can be consumed by an application. Hence, reading large files to an in-memory data store as done in your code (using StringBuffer) is going to throw an OutOfMemory error.
Take a look at this question to know how you can overcome the problem.

Blob object not working properly even though the class is seralized

I have class which is seralized and does convert a very large amount of data object to blob to save it to database.In the same class there is decode method to convert blob to the actual object.Following is the code for encode and decode of the object.
private byte[] encode(ScheduledReport schedSTDReport)
{
byte[] bytes = null;
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(schedSTDReport);
oos.flush();
oos.close();
bos.close();
//byte [] data = bos.toByteArray();
//ByteArrayOutputStream baos = new ByteArrayOutputStream();
//GZIPOutputStream out = new GZIPOutputStream(baos);
//XMLEncoder encoder = new XMLEncoder(out);
//encoder.writeObject(schedSTDReport);
//encoder.close();
bytes = bos.toByteArray();
//GZIPOutputStream out = new GZIPOutputStream(bos);
//out.write(bytes);
//bytes = bos.toByteArray();
}
catch (Exception e)
{
_log.error("Exception caught while encoding/zipping Scheduled STDReport", e);
}
decode(bytes);
return bytes;
}
/*
* Decode the report definition blob back to the
* ScheduledReport object.
*/
private ScheduledReport decode(byte[] bytes)
{
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ScheduledReport sSTDR = null;
try
{
ObjectInputStream ois = new ObjectInputStream(bais);
//GZIPInputStream in = new GZIPInputStream(bais);
//XMLDecoder decoder = new XMLDecoder(in);
sSTDR = (ScheduledReport)ois.readObject();//decoder.readObject();
//decoder.close();
}
catch (Exception e)
{
_log.error("IOException caught while decoding/unzipping Scheduled STDReport", e);
}
return sSTDR;
}
The problem here is whenver I change something else in this class
means any other method,a new class version is created and so the new version the class is unable to decode the originally encoded blob object. The object which I am passing for encode is also seralized object but this problem exists. Any ideas thanks
Yup, Java binary serialization is pretty brittle :(
You can add a static serialVersionUID field to the class so that you can control the version numbers... this should prevent problems due to adding methods. You'll still run into potential issues when fields are added though. See the JavaDocs for Serializable for some more details.
You might want to consider using another serialization format such as Protocol Buffers to give you more control though.
You can implement java.io.Externalizable so that you are able to control what is serialized and expected in deserialization.

Categories