Hello everybody,

For a school assignment I need to save images to .ser files. Could someone explain me how i get it succesfull. The program itself creates a .ser but the content is useless (’ NUL ENQ). Thanks in advance :). This is the method i came up with:

public void savePhoto() {
        
    try	{		// Write to disk with FileOutputStream
                FileOutputStream fOut = new FileOutputStream(photoDir);
                // Write object with ObjectOutputStream
                ObjectOutputStream objOut = new ObjectOutputStream(fOut);

                //locaties is the array which holds the images
                for(int x = 0; x < locaties.size(); x++) {   

                    //I don't know what Serialize has to be an array and if so what kind? 
                    Serialize[x].writeImageObject(objOut);
                }
                System.out.println("File Saved!");
                }	catch (FileNotFoundException e)	{
                    System.out.println("Error : Cannot save file.");
                    e.printStackTrace();
                }	catch (IOException e)	{
                    System.out.println("Error : Cannot write file.");
                    e.printStackTrace();	
         }
    }

Sorry i meant that locaties is a arraylist instead of an array

A serialized image written to a file is not the same as an image written to a file. Java serialization uses a specific binary format for writing out Java objects. Also, your post isn't clear. What exactly does "serialize[x]" contains i.e. what kind of object? What is locaties?

Locaties is dutch for locations it means the source of the image C:/users/user/desktop/image.jpg. Locaties is an arraylist. I found some code on the internet and put it all together. I don't know which kind of array he needs @ Serialize[x]. Can you maybe give me some advice how i could achieve it to write images to .ser files. If the code I wrote is bad we could skip that.

Three ways I can think of:

  • Read the image as a normal file, extract the bytes from that file and write the given byte array to the ObjectOutputStream. This is the quick and dirty way of doing it but you won't have the image details (the image name, format etc.) since you are writing out raw bytes
  • Create a custom image class having a byte array field, name and format field, make that class implement Serializable and write the object of that class.
  • Use the ImageIO clas for read the file as a BufferedImage and write the image to the ObjectOutputStream using the write() method of ImageIO. Roundabout way and not recommended.

I would personally go with the second method.

Ok I follow your choice and I also choose method 2. this is what i have till now.
What kind of methods do I need to accomplish this. I have never worked with serialization.

package view;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javax.imageio.ImageIO;

public class Serialize implements Serializable {

    //Create a custom image class having a byte array field, 
    //name and format field, make that class implement Serializable 
    //and write the object of that class.
    
    private byte [] byteImage = null;
    private byte [] name = null;
    private byte [] format = null;
    
}

Rename the class to something more logical rather than naming it Serialize. Ensure that your class has a serialVersionUID field (google for it). Also, no need to make name and format as a byte array, let them be strings. As far as writing images to ser file is concerned:

  • Create a file object from the image path
  • Create a new Image (your class) object and set the name (retrieve from file object), format (png, jpg) and bytes (google for reading bytes from a file).
  • Create an ObjectOutputStream and use the writeObject method of this stream to write your Image objects

This is what I came up with. Found some cool script on the internet.
But how can i access the bytearray from the read method in the write method?

package view;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.*;

import javax.imageio.ImageIO;

public class PhotoFile implements Serializable {

    //Create a custom image class having a byte array field,
    //name and format field, make that class implement Serializable
    //and write the object of that class.

//    Create a file object from the image path
//Create a new Image (your class) object and set the name (retrieve from file object), format (png, jpg) and bytes (google for reading bytes from a file).
//Create an ObjectOutputStream and use the writeObject method of this stream to write your Image objects

    private byte [] byteImage = null;
    private String name = "nature";
    private String format = ".jpg";
    private File file;
    private String fileDir = "C:/users/patrick/desktop/";
    private String path = fileDir + name + format;

    public static final long serialVersionUID = 1L;


    public static byte[] getBytesFromFile(File file) throws IOException {
        
    InputStream is = new FileInputStream(file);

    // Get the size of the file
    long length = file.length();

    // You cannot create an array using a long type.
    // It needs to be an int type.
    // Before converting to an int type, check
    // to ensure that file is not larger than Integer.MAX_VALUE.
    if (length > Integer.MAX_VALUE) {
        // File is too large
    }

    // Create the byte array to hold the data
    byte[] bytes = new byte[(int)length];

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }

    for (int i = 0; i<bytes.length; i++){
        System.out.println(bytes[i]);
    }

    // Ensure all the bytes have been read in
    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    // Close the input stream and return bytes
    is.close();
    return bytes;
    }

    public static void writeBytesToFile() throws IOException {

        String strFilePath = "C:/Users/Patrick/Desktop/Photo.ser";

     try
     {
      FileOutputStream fos = new FileOutputStream(strFilePath);
      //String strContent = "Write File using Java FileOutputStream example !";

      /*
       * To write byte array to a file, use
       * void write(byte[] bArray) method of Java FileOutputStream class.
       *
       * This method writes given byte array to a file.
       */
      
      fos.write(bytes);

      /*
       * Close FileOutputStream using,
       * void close() method of Java FileOutputStream class.
       *
       */

       fos.close();

     }
     catch(FileNotFoundException ex)
     {
      System.out.println("FileNotFoundException : " + ex);
     }
     catch(IOException ioe)
     {
      System.out.println("IOException : " + ioe);
     }


    }
        
    

}

I personally don't like placing the image writing code in the PhotoFile class. Plus, you should not write raw bytes but the PhotoFile object to the ObjectOutputStream. The algorithm for writing should be:

  • Start the main method by looping over the image files
  • Create a new ObjectOutputStream instance outside the loop
  • For each image file, read the file details (name, format and bytes)
  • Create a new PhotoFile object based on the above details
  • write the PhotoFile instance to the OOS (object output stream) object

For reading:

  • Open the ObjectInputStream using the .ser file you just created
  • Keep on invoking readObject() method and reading in PhotoImage objects as long as an exception is not thrown (there are better ways of doing this, but do this for the time being)

I fixed it thank you very much for your help.

/**
     * The method serSetImage makes from an image a serialized file.
     * Extension .ser
     */

    public void serSetImage() {
        FileOutputStream fout = null;
        ObjectOutputStream ob = null;
        try {
            fout = new FileOutputStream(photoDir);
            ob = new ObjectOutputStream(fout);
            ob.writeObject(fotos.get(0));
            
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
          
            try{
              fout.close();
              ob.close();
            }catch(IOException ex){
               ex.printStackTrace();
            }
        }
    }

    /**
     * The method serReadImage reads a .ser file and adds the image to the
     * array fotos.
     */

    public void serReadImage() {

        FileInputStream fout = null;
        ObjectInputStream ob = null;
        Photo foto = null;

        try {

            fout = new FileInputStream(photoDir);
            ob = new ObjectInputStream(fout);
            foto = (Photo) ob.readObject();


            
        } catch (ClassNotFoundException exc) {
            //
        } catch (FileNotFoundException ex) {
            System.out.println("File can not be found: " + ex);
        } catch (IOException ex) {
            System.out.println("There went something wrong with the input or output: " + ex);
        } catch (IndexOutOfBoundsException ex) {
            System.out.println("There are too many characters to read!" + ex);
        } finally {
            try{
            ob.close();
            } catch (IOException exc){
                System.out.println("There went something wrong!");
            }
            fotos.add(foto);
        }


    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.