Results 1 to 6 of 6
  1. #1
    hei1233212000 is offline Member
    Join Date
    Jul 2010
    Posts
    36
    Rep Power
    0

    Default Question about File I/O

    Hi,

    I am doing an exercise in "java how to program 6/e" Ch14 which is about File I/O.

    The question:
    Modify Exercise 11.18 to allow the user to save a drawing into a file or load a prior drawing from a file using object serialization. Add buttons Load (to read objects from a file) and Save (to write objects to a file). Use an ObjectOutputStream to write to the file and an ObjectInputStream to read from the file. Write the array of MyShape objects using method writeObject (class ObjectOutputStream), and read the array using method readObject (ObjectInputStream). Note that the object-serialization mechanism can read or write entire arrays—it is not necessary to manipulate each element of the array of MyShape objects individually. It is simply required that all the shapes be Serializable. Because the array of MyShape objects has 100 elements and the array is not necessarily filled with shapes drawn by the user, you may also want to store to the file the number of shapes drawn so far. For both the Load and Save buttons, use a JFileChooser to allow the user to select the file in which the shapes will be stored or from which they will be read. When the user first runs the program, no shapes should be displayed on the screen. The user can display shapes by opening a previously saved file of shapes or by drawing their own shapes. Once there are shapes on the screen, users can save them to a file using the Save button.


    I think I did everything correctly except there is a problem when I save and open file.

    I found that there is an IOExcetption when I write "shapes", which is an array of "MyShape()", into file(".ser").
    Also, there is an IOExcetption when I read "shapes" from file(".ser").
    See the code which is red in color.

    However, the problem only occurs when "shapes" contains elements.
    I mean:
    If I didn't draw anything and then I save the drawing into ".ser" file, it works. On the other hand, it also works when I open a ".ser" file which contains an EMPTY "shapes".

    Java Code:
    // ActionListener for menuItemSave
    saveFile = new ActionListener() //******
    {
    	public void actionPerformed( ActionEvent event )
    	{
    		// initialize the out stream
    		ObjectOutputStream output = null;
    		
    		try
    		{
    			// use JFileChooser to select file
    			JFileChooser fileChooser = new JFileChooser();
    		        fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 
    			
    			// set the title
    			fileChooser.setDialogTitle ( "Save File" );
    				
    			// Start in current directory
    			fileChooser.setCurrentDirectory ( new File ( "." ) );
    			
    			// get the result of the fileChooser
    			int result = fileChooser.showSaveDialog( DrawFrame.this );
    			
    			// if user clicked Cancel button on dialog, return
    			if( result == JFileChooser.CANCEL_OPTION )
    				return; // do nothing
    			
    			// get selected file
    			File fileName = fileChooser.getSelectedFile();
    			
    			// display error if invalid
    			if( ( fileName == null ) ||
                                   ( fileName.getName().equals( "" ) ) )
    			{
    				// display error message
    				JOptionPane.showMessageDialog( DrawFrame.this,											     
                                                    "Invalid File Name", "Invalid File Name",											
                                                          JOptionPane.ERROR_MESSAGE );
    				return; // do nothing
    			}
    			
    			// check the file extension e.g. ".ser"
    			String[] splits = fileName.getName().split( "\\."); 
    			String extension = splits[ splits.length - 1 ]; 
    			
    			if( !extension.equals( "ser" ) ) // Not "ser" type
    			{
    				// display error message
    				JOptionPane.showMessageDialog( DrawFrame.this,
    				      "It is only allowed to save a file in \".ser\" type.",
    				      "Invalid File Type",												
                                          JOptionPane.ERROR_MESSAGE );
    			}
    			else
    			{
    				if( fileName.exists() ) // if the file is already existed
    				{
    					// get the response from the JOptionPane
    					int response = 
    							JOptionPane.showConfirmDialog ( 
                                                                       DrawFrame.this, 
                                                                       "Overwrite existing file?", 
                                                                       "Confirm Overwrite",															
                                                                    JOptionPane.YES_NO_OPTION,															
                                                            JOptionPane.QUESTION_MESSAGE );
    					// if the user clicked NO or CLOSE
    					if ( ( response == JOptionPane.NO_OPTION )||
                                             ( response == JOptionPane.CLOSED_OPTION ) )
    					{
    						return; // do nothing
    					}
    				}	
    				
    				// open file for output
    				output =  new ObjectOutputStream( new FileOutputStream( fileName ) );
    				
    				// write number of shapes to file
    				output.writeObject( panelDraw.getShapeCount() );
    				
    				[COLOR="Red"]// write shapes to file using serialization
    				output.writeObject( panelDraw.getShapes() );[/COLOR]
    				
    				// show the file is saved
    				JOptionPane.showMessageDialog( DrawFrame.this, 
                                                                      "File is saved",
    								  "File is saved",							
                                                       JOptionPane.INFORMATION_MESSAGE );
    			}
    		} // end try
    		catch( IOException ioException )
    		{
    			// display error message
    			JOptionPane.showMessageDialog( DrawFrame.this,
    								"Error opening file.", "Error",											
                                                                JOptionPane.ERROR_MESSAGE );
    		} // end catch
    		finally
    		{
    			try
    			{
    				// close file and stream
    				if( output != null )
    					output.close();
    			} // end try
    			catch( IOException ioException )
    			{
    				// display error message
    				JOptionPane.showMessageDialog( DrawFrame.this,
    								"Error closing file.", "Error",											
                                                                 JOptionPane.ERROR_MESSAGE );
    			} // end catch
    		} // end finally
    	} // end method actionPerformed
    }; // end generate ActionListener menuItemSave
    As the entire program have several class, so I only post the actionListener for saving file to make the code more readable.

    I hope someone can help me.
    Thank you.

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,008
    Rep Power
    20

    Default

    What does the IOException say?
    At the very least you should be printing the stakc trace for the exception.

  3. #3
    hei1233212000 is offline Member
    Join Date
    Jul 2010
    Posts
    36
    Rep Power
    0

    Default

    Quote Originally Posted by Tolls View Post
    What does the IOException say?
    At the very least you should be printing the stakc trace for the exception.
    First of all, thank you for your help.
    Now, I know the source of the problem.

    Java Code:
    java.io.NotSerializableException: java.awt.BasicStroke
    	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    	at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    	at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    	at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    	at java.io.ObjectOutputStream.writeArray(Unknown Source)
    	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    	at java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.awt.BasicStroke
    	at DrawFrame$9.actionPerformed(DrawFrame.java:481)
    	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    	at javax.swing.AbstractButton.doClick(Unknown Source)
    	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    	at java.awt.Component.processMouseEvent(Unknown Source)
    	at javax.swing.JComponent.processMouseEvent(Unknown Source)
    	at java.awt.Component.processEvent(Unknown Source)
    	at java.awt.Container.processEvent(Unknown Source)
    	at java.awt.Component.dispatchEventImpl(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Window.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.EventQueue.dispatchEvent(Unknown Source)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.run(Unknown Source)

    It is because the "shapes" contains non-serializable element, "BasicStroke".
    However, how can I store a non-serializable "BasicStroke" into ".ser" file?

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,008
    Rep Power
    20

    Default

    You can't.
    Your only option is to make it transient (I think I got the right keyword there, it's early!), which means it won't be serialised.

  5. #5
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Yup, transient is the keyword.

    There are ways around it, but you'd need to read a detailed tutorial on serialization and what methods it will call if they are present. There's a good tutorial on the Sun Website.

    Your best bet would probably be to set it as transient for now - trying to convert non-serializable objects into a serializable form is difficult.
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  6. #6
    hei1233212000 is offline Member
    Join Date
    Jul 2010
    Posts
    36
    Rep Power
    0

Similar Threads

  1. Question about creating jar file
    By hei1233212000 in forum New To Java
    Replies: 3
    Last Post: 10-27-2010, 02:41 PM
  2. java question output file
    By dazednconfused in forum New To Java
    Replies: 3
    Last Post: 09-17-2009, 03:07 PM
  3. [SOLVED] File reading question
    By wiz0r in forum New To Java
    Replies: 5
    Last Post: 04-19-2009, 01:21 AM
  4. Basic File Question
    By McChill in forum New To Java
    Replies: 6
    Last Post: 03-20-2009, 08:21 AM
  5. file/ array question
    By mayhewj7 in forum New To Java
    Replies: 10
    Last Post: 02-18-2009, 03:54 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •