9 Replies Latest reply: Nov 23, 2007 1:25 AM by 807603 RSS

    FileOutputStream.close() not working?

    807603
      Howdy yall.

      I'm having problems with reading and writing files using java, It seems even though im calling fout.close(); the streams are not closing?, causing the file to not be written to the disk.

      When i close the program, the file is then written to the disk.

      Is there someway i can avoid this behaviour?. If it's trying to be more efficient in writing (eg one write instead of 30-50 small ones). Is there someway i can trigger this after the loop? rather than exiting my program.

      It's a real shit if someone tries to use the files if the program hasn't been closed. A "indeterminate state" odf is made. It's workable but does not contain the data i wrote into it. It only updates once the program has closed.

      You can see how much of a prick this is.

      PS. im using truezip6.6
       for(int i=0;i<valuemodel.getSize();i++){
                  progress=i*100/(valuemodel.getSize()-1);
                  jProgressBar1.setValue(progress);
                  System.out.print(progress);
                  System.out.println();
                  
                  data currentdata = (data) valuemodel.getElementAt(i);
                  String Output= "/"+outdir+"/"+currentdata.surname+" "+currentdata.name+".odt";
                  File templatecontents = new File(template,"content.xml");
                  //This code copied the bulk of the file from template
                   try{ 
      
                     File foutall = new File(Output);
                     copy(template,(File) foutall);
                   }
                   catch(java.io.IOException e){
                       javax.swing.JOptionPane.showMessageDialog(EmailConverterGUI.this, "IOException #1. Creation of Output failed");
                   }
      
                  //This creates the new content.xml
                   try{
                      FileInputStream fin = new FileInputStream(templatecontents);
                      FileOutputStream fout = new FileOutputStream(Output+"/content.xml");
                          String str;
                          while((str= new DataInputStream(fin).readLine()) !=null){
                              str= replacetemplate(str,currentdata);
                              new DataOutputStream(fout).writeBytes(str); 
                          }
                          fout.close();
                          fin.close();
                          fout.flush();
                   }
                   catch(java.io.IOException e){ 
                      javax.swing.JOptionPane.showMessageDialog(EmailConverterGUI.this, "IOException #2. Error creating content.xml");
                      e.printStackTrace();
                  } 
          }
        • 1. Re: FileOutputStream.close() not working?
          807603
          Your problem is almost certainly caused by this line
                                 new DataOutputStream(fout).writeBytes(str); 
           
          where for some reason you create a new DataOutputStream each time round the loop.

          Why not just create it once so that it wraps the FileOutputStream and then keep writing to it. When you have finished writing all your data you should call close() on the DataOutputStream (not on the FileOutputStream).

          P.S. I don't see why you need either DataInputStream or DataOutputStream if you are only processing bytes as bytes. Just read from and write to the FileInputStream and FileOutputStream (maybe wrapping them ion BufferedInputSteam and BufferedOutptuStream).

          Edited by: sabre150 on Nov 22, 2007 4:31 PM
          • 2. Re: FileOutputStream.close() not working?
            DrClap
            new DataOutputStream(fout)
            Here's the thing you should be closing but you aren't closing.
            • 3. Re: FileOutputStream.close() not working?
              807603
              close the stream before you create the new one.
              • 4. Re: FileOutputStream.close() not working?
                EJP
                (a) You shouldn't create either the DataInputStream or the DataOutputStream once per line. You are in danger of losing data at both steps. Create them both at the same time you create the FileInputStream and FileOutputSream.

                (b) Unless you are certain all the files contain lines, you should be reading and writing byte arrays, not lines. As you can't in general be certain of that, and as copying bytes works for all files, just do that.

                (c) Close the outermost output stream, in this case the DataOutputStream, not e.g. the FileOutputStream it wraps. You don't need the flush() at all, but if you did it would need to be before the close, not afterwards, and again it would need to be the DataOutputStream that you flush, not the FileOutputStream.
                • 5. Re: FileOutputStream.close() not working?
                  807603
                  You guys meant something like this right?

                  Both blocks of new code give the same characteristics as the old stuff.

                  And the files i am writing are content.xml's. They are files contained in the Open Office File format. I kinda read all the data (2 lines) into strings. Edit the second line (where the stuff i need to change is), and then re-insert it into the content.xml


                  try{
                                  FileInputStream fin = new FileInputStream(templatecontents);
                                  FileOutputStream fout = new FileOutputStream(Output+"/content.xml");
                                  DataInputStream din = new DataInputStream(fin);
                                  DataOutputStream dout =new DataOutputStream(fout);
                                      String str;
                                      while((str= din.readLine()) !=null){
                                          str= replacetemplate(str,currentdata);
                                          dout.writeBytes(str); 
                                      }
                                      din.close();
                                      dout.flush();
                                      dout.close();
                                      fout.flush();
                                      fout.close();
                                      fin.close();
                                      ;
                               }
                  ...................
                                      }
                                      din.close();
                                      dout.flush();
                                      dout.close();
                                      /*fout.flush();
                                      fout.close();
                                      fin.close();*/
                                      ;
                               }
                  • 6. Re: FileOutputStream.close() not working?
                    EJP
                    din.close();
                    dout.flush();
                    dout.close();
                    fout.flush();
                    fout.close();
                    fin.close();
                    Closing 'din' closes its nested input stream, i.e. 'fin'.
                    Closing an output stream that extends FilterOutputStream flushes it first unless its close() method specifies otherwise, which it doesn't in this case.
                    Flushing an output stream that extends FilterOutputStream flushes its nested stream, in this case 'fout', unless its flush() method specifies otherwise, which it doesn't in this case.
                    Closing 'dout' closes its nested output stream, i.e. 'fout'.
                    So you can reduce all that to:
                    din.close();
                    dout.close();
                    • 7. Re: FileOutputStream.close() not working?
                      807603
                      Yeah i thought as much, but havign the extra stuff didn't seem to hurt.

                      I fixed it now!! YAY.

                      It all lies in truezip 6's and it's mechanics.

                      I'll save the long winded story. but your need to have code similar to this
                      try{
                              File.umount();
                          }
                          catch (ArchiveWarningException e){
                              javax.swing.JOptionPane.showMessageDialog(EmailConverterGUI.this, "ArchiveWarning Exception");
                          }
                          catch (ArchiveException e){
                             e.sortAppearance().printStackTrace();
                             javax.swing.JOptionPane.showMessageDialog(EmailConverterGUI.this, "Archive Exception. Big Problem");
                          }  
                      which forces the zip files close (they are mounted with vfs or something). so it write to disk.

                      Cheers yall.
                      • 8. Re: FileOutputStream.close() not working?
                        EJP
                        havign the extra stuff didn't seem to hurt
                        It doesn't help either. It just sits there to confuse future maintainers, and presents a strong temptation to delete the redundant lines and possibly make a mistake in the process. Get rid of it now.
                        • 9. Re: FileOutputStream.close() not working?
                          807603
                          actually already long gone.

                          I deleted it before i posted, i don't what extra crap i don't need to have there :P