🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.jbuilder.java.api
Article #923

Re: OutOfMemoryError

#923
From: Alan Shiers
Date: Thu, 04 Jul 2002 23:05
518 lines
17910 bytes
Hi there,

>Owen wrote:
>If you post your entire uploadFile() method (if its not too huge), it will be easier to see what's happening. 

>hth 
>Owen 

Sure, I'll provide you with the method receiveFile() which is on the
server-side app and uploadFile() which is on the client-side app.  Also,
I'll include my request_workerThread class that you might see how I'm
trying to
split the proceedure on the client-side app.  I've been working on the
request_workerThread class and have solved the "Bad descriptor file"
problem.
All I had to do was instantiate the FileInputStream object there
instead.

To reiterate, my immediate problem is just getting the while loop in the
receiveFile() method to collect all
incoming data without hanging.  It's just not getting the EOF to trigger
it to leave the loop.

You might ask, "Why am I splitting the procedure on the client side
to begin with?".  The reason is simple. You will notice in the
uploadFile() method I send the fileLengh to the server app. 
receiveFile() takes that file size value and calls another method called
isEnoughSpaceAvailable(fileLength);

isEnoughSpaceAvailable(fileLength) determines if there is enough disk
space in the user's home directory to accomodate the file being
uploaded. If there is, then a message is sent back to the client app
giving the OK to "proceed".  Otherwise, it sends a message saying that
the "WebSpaceFull".  

So, you see, request_workerThread class simply allows me to cause the
program to wait a bit for a response from the server app before
proceeding with the upload.

I digress...

Once again, all I need help with at this point is with the while loop
in receiveFile() on the server app. It keeps hanging, like I said
earlier.  

Please advise,

Alan Shiers

********************************************************
First, the receiveFile() method (server side):

private void receiveFile(String pathFilename)
  {
    //System.out.println("Incoming path: " + pathFilename);
    //this method is called when a file is being uploaded to the server
    //and is to be saved at the specified directory on the server.

    /*Before we save any file, we need to ensure there is
     *enough free space available in the user's
     *home directory to accomodate it depending on
     *how much initial space was allotted to the user via
     *his Member Profile. If there is no space left,
     *we simply return out of here.
     */

    int fileLength = 0;
    try
    {
      //System.out.println("Trying to read int");
      fileLength = input.readInt();
    }
    catch(IOException ioe){ioe.printStackTrace();}

    boolean enoughSpace = isEnoughSpaceAvailable(fileLength);
    //System.out.println("enoughSpace = " + enoughSpace);
    if (enoughSpace == false) return;

    File myFile = new File(pathFilename);
    byte[] buf;
    FileOutputStream fileOut = null;

    try
    {
       myFile.createNewFile(); //create the file
       if(myFile.exists()) //Method exists() throws a SecurityException
if
                          //there is an access violation.
       {
          try
          {
            fileOut = new FileOutputStream(myFile);
          }
          catch(FileNotFoundException fnfe)
          {
            System.out.println("receiveFile() function -
FileNotFoundException\n");
            fnfe.printStackTrace();
          }
          //We're going to read in the data in chunks of 128 bytes.
          buf = new byte[128];
          //load up the array
          int n;
          /*while((n = input.read(buf)) >= 0)
          {  System.out.print(n + ", ");
            //write it to the file
            fileOut.write(buf);
          }*/
          for(int i = 128; i <= fileLength + 128; i = i + 128)
          {
            n = input.read(buf);
            if(n == -1)
            {
              System.out.println("breaking");
              break;
            }
            fileOut.write(buf);
          }
          //Close the stream
          if(fileOut != null)
            fileOut.close();
          //System.out.println("Closed stream");
          output.writeInt(session.UPLOAD_SUCCESSFUL);
          output.flush();
       }
    }
    catch(SecurityException se)
    {
      if(DirAdmin.hasInterface)
        myServer.display("SecurityException occurred in method
ReceiveFile");
      else
        System.out.println("SecurityException occurred in method
ReceiveFile");
      try
      {
        output.writeInt(session.UPLOAD_UNSUCCESSFUL_SECURITY_EXCEPTION);
        //Close the stream
        if(fileOut != null)
          fileOut.close();
        output.flush();
      }
      catch(IOException ioe){}
    }
    catch(IOException ioe)
    {
       try
       {
         output.writeInt(session.UPLOAD_UNSUCCESSFUL);
         //Close the stream
         if(fileOut != null)
           fileOut.close();
         output.flush();
       }
       catch(IOException io){}
    }
    catch(Exception e)
    {
        try
        {
          output.writeInt(session.UPLOAD_UNSUCCESSFUL);
          //Close the stream
          if(fileOut != null)
            fileOut.close();
          output.flush();
        }
        catch(IOException io){}
     }
   }

**************************************************************


Next, the uploadFile() method (client side):

private void uploadFile(String FileToPathOnServer, String
FileFromLocalDrive)
  {
    File myFile = null;
    //Show the connection icon on the interface
    ref.showConnectionIcon();

    //Tell the server where to put the uploaded file
    try
    {
      output.writeInt(PATH);
      if(ref.serverOS.equals("Windows"))
      {
        output.writeUTF(convertSingleBackwardSlash(FileToPathOnServer));
      }
      else
      {
        output.writeUTF(FileToPathOnServer);
      }
    }
    catch(IOException ioe){System.out.println("IOException\n");
ioe.printStackTrace();}

    if(getPlatform().equals("Windows"))
    {
      String temp = convertSingleBackwardSlash(FileFromLocalDrive);
      //System.out.println(temp);
      myFile = new File(temp);
    }
    else
    {
      myFile = new File(FileFromLocalDrive);
    }

    int fileLength = 0;
    fileLength = (int)myFile.length();
    //Begin transfering the file at byte level
    try
    {
       //tell the server we're uploading a file
       output.writeInt(UPLOAD_FILE);
       /*The file size can quite possibly be quite large.
         So, we're going to set the array size to 128 bytes
         and keep sending data in chunks of 128 bytes.
       */
       output.writeInt(fileLength);
       System.out.println("Output filelength = " + fileLength);

       buf = new byte[128];

       //Wait or the signal to proceed before attempting to upload the
data.
       //We do this by invoking a worker thread which checks the
"proceed" and
       //"WebSpaceFull" flags every five seconds.
       //See request_workerThread class.
       //System.out.println("Calling timer functions.");
       ref.textLabel.setText("uploading " + myFile.getName());
       timer.setOnlyOneFile(true);
       timer.setByteArrayReference(buf, fileLength, myFile);
       timer.setThreadSuspended(false);

    }
    catch(IOException ioe){System.out.println("IOException\n");
ioe.printStackTrace();}
    catch(Exception e)
    {
       System.out.println("Exception\n");
       e.printStackTrace();
       ref.jLabel1.setText("Status: Exception in method uploadFile - You
may have lost your connection.");
       enableMenus();
    }

  }

************************************************************

Finally, the following is the request_workerThread class. Keep in mind
that I use this class to handle both the uploading of only one file from
uploadFile() and the uploading of multiple files from uploadFiles().
uploadFiles() is almost identicle to uploadFile() except that it used a
for loop to iterate through multiple
selected files. 

import java.io.*;


public class request_workerThread extends Thread
{
  private boolean threadSuspended = true; //default
  private int timeElapsed = 0;
  private request rq = null;
  private byte[] array;
  private int SizeOfFile = 0;
  private FileInputStream fin;
  private File myFile;
  private boolean onlyOneFile;
  private boolean SaveFileAs;


  public request_workerThread(request req)
  {
    //System.out.println("request_workerThread instantiated.");
    rq = req;
  }

  protected synchronized void setByteArrayReference(byte[] reference,
int fileSize, File ref)
  {
    array = reference;
    SizeOfFile = fileSize;
    myFile = ref;
  }

  protected synchronized void setByteArrayReference(byte[] reference,
boolean SavingNewFile)
  {
    array = reference;
    SaveFileAs = SavingNewFile;
  }

  protected void setOnlyOneFile(boolean value)
  {
    onlyOneFile = value;
  }

  /**
   * This class extends class Thread, therefore we must overwrite the
run() method.
   */
  public void run()
  {
     while(true)
      {
         if(threadSuspended)
         {
            synchronized(this)
            {
               try
               {
                  while(threadSuspended)
                  {
                     //System.out.println("threadSuspended = true");
                     wait();
                  }
               }
               catch(IllegalMonitorStateException imse){}
               catch(InterruptedException ie){}
            }
         }

         try
         {
            Thread.sleep(5000);  //run a 5 second timer
         }
         catch(InterruptedException e){}

         //Record time elapsed.
         timeElapsed = timeElapsed + 5;
         //System.out.println("Elapsed time = " +
String.valueOf(timeElapsed) + " seconds.");

         //Check to see if the either flag has been set.
         //If not, after thirty seconds then put this thread to sleep
again.
         //System.out.println("proceed = " + rq.proceed + " WebSpaceFull
= " + rq.WebSpaceFull);
         if(rq.proceed || rq.WebSpaceFull)
         {
            try
            {
              if(rq.proceed)
              {
                //uploading only one file
                if(onlyOneFile && SaveFileAs == false)
                {
                  System.out.println("Sending only one file");
                  //Access the file on local drive and start reading
from it.
                  try
                  {
                    fin = new FileInputStream(myFile);
                  }
                  catch(FileNotFoundException
fnfe){System.out.println("FileNotFoundException\n");
fnfe.printStackTrace();}
                  rq.ref.jProgressBar1.setMinimum(0);
                  rq.ref.jProgressBar1.setMaximum(SizeOfFile);
                  rq.ref.jProgressBar1.setStringPainted(true);
                  rq.ref.jProgressBar1.setVisible(true);
                  rq.disableMenus();

                  int n;
                  int counter = 0;
                  System.out.println("Start sending data");
                  while((n = fin.read(array)) >= 0)
                  {
                      rq.output.write(array);
                      rq.ref.jProgressBar1.setValue(counter += 128);
                  }
                  System.out.println("Finished sending data");
                  //Close the stream
                  try
                  {
                    if(fin != null)
                      fin.close();
                    System.out.println("Closed stream");
                  }
                  catch(IOException
ioe){System.out.println("IOException\n"); ioe.printStackTrace();}

                  rq.output.flush();
                  rq.ref.jProgressBar1.setVisible(false);
                  rq.enableMenus();
                  rq.proceed = false; //reset
                  timeElapsed = 0; //reset
                  setThreadSuspended(true); //reset

                }
                //we're just saving a new file
                else if(onlyOneFile && SaveFileAs)
                {
                  rq.output.write(array);
                  SaveFileAs = false; //reset
                  setThreadSuspended(true);
                }
                //uploading many files
                else
                {
                  System.out.println("Sending more than one file");
                  //Access the file on local drive and start reading
from it.
                  try
                  {
                    fin = new FileInputStream(myFile);
                  }
                  catch(FileNotFoundException
fnfe){System.out.println("FileNotFoundException\n");
fnfe.printStackTrace();}
                  System.out.println("Processing " + myFile.getName());
                  rq.output.writeUTF(myFile.getName());
                  rq.ref.jProgressBar1.setMinimum(0);
                  rq.ref.jProgressBar1.setMaximum(array.length);
                  rq.ref.jProgressBar1.setStringPainted(true);
                  rq.ref.jProgressBar1.setVisible(true);
                  int n;
                  int counter = 0;
                  System.out.println("Start sending data");
                  while((n = fin.read(array)) >= 0)
                  {
                    rq.output.write(array);
                    rq.ref.jProgressBar1.setValue(counter += 128);
                  }
                  System.out.println("Finished sending data");
                  //Close the stream
                  try
                  {
                    if(fin != null)
                      fin.close();
                    System.out.println("Closed stream");
                  }
                  catch(IOException
ioe){System.out.println("IOException\n"); ioe.printStackTrace();}

                  rq.output.flush();
                  rq.ref.jProgressBar1.setVisible(false);
                  rq.proceed = false; //reset
                  timeElapsed = 0; //reset
                  setThreadSuspended(true); //reset
                  rq.sendNextFile = true; //reset
                }
              }
              else if(rq.WebSpaceFull)
              {
                //Don't send any data!
                //System.out.println("received signal to abort upload");
                //We need to set flag: sendNextFile = true
                //if processing multiple files for upload so that we can
                //exit out of both the while and for loops in
rq.uploadFiles().
                //uploadfiles() will also attempt to reset flag:
WebSpaceFull = false.

                rq.sendNextFile = true;//reset
                rq.output.flush();
                timeElapsed = 0; //reset
                rq.WebSpaceFull = false; //reset
                setThreadSuspended(true); //reset
              }
            }
            catch(IOException ioe){ioe.printStackTrace();}
         }
         if(timeElapsed == 30)
         {
            timeElapsed = 0; //reset
            rq.ref.imageLabel.setIcon(rq.ref.blank);
            rq.ref.textLabel.setText("");
            rq.ref.jLabel1.setText("Status: Unable to complete File
Upload or File Save. Please try again.");
            rq.enableMenus();
            //System.out.println("Time elapsed is 30
seconds.\nrequest_workerThread is being reset to a suspended state.");
            /*There is a possibility that we'll have a time lapse of 30
seconds
             *and we're trying to upload multiple files. In this case,
since
             *request.uploadFiles() has a while loop in it, we need to
break
             *out of the while loop and the for loop. Therefore, we'll
set
             *both flags to true: WebSpaceFull and sendNextFile.
             */

             rq.WebSpaceFull = true;//reset
             rq.sendNextFile = true;//reset


            setThreadSuspended(true);
         }
      }
  }

  /**
   * Find out the state of threadSuspended.
   */
  public boolean getThreadSuspended()
  {
      return threadSuspended;
  }

  /**
   * Set the value of threadSuspended.
   * @param A boolean value.
   */
  public synchronized void setThreadSuspended(boolean value)
  {  //System.out.println("threadSuspended being set to " +
String.valueOf(value));
     threadSuspended = value;
     if(value == false)//we want to wake up this thread
        notify();
  }
}
Technical Details
Message-ID: <3D24D4AC.1B1BFBBC@hfx.eastlink.ca>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!supernews.com!iad-peer.news.verio.net!news.verio.net!news.maxwell.syr.edu!nntp-relay.ihug.net!newsfeeds.ihug.co.nz!ihug.co.nz!dnews
References: <3D20CC5D.B70473C9@hfx.eastlink.ca> <MPG.178acb912dba8f7998b79d@newsgroups.borland.com> <3D21C1CA.F2D953E2@hfx.eastlink.ca> <3d21bb44_1@dnews> <3D21EC78.228A5CD3@hfx.eastlink.ca> <3d21e07b_2@dnews> <3D226288.1C7C905@hfx.eastlink.ca> <3d22ec28_1@dnews> <3D233ADD.C365148D@hfx.eastlink.ca> <3d245dff_2@dnews>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 1089d0,28eab50e784856ac
X-Google-Attributes: gid1089d0,public
X-Google-ArrivalTime: 2002-07-04 15:06:53 PST
Message-ID: <3D24D4AC.1B1BFBBC@hfx.eastlink.ca>
Date: Thu, 04 Jul 2002 19:05:16 -0400
From: Alan Shiers <ashiers@hfx.eastlink.ca>
Organization: Mustard Seed Software
X-Mailer: Mozilla 4.78 [en] (Win98; U)
X-Accept-Language: en
MIME-Version: 1.0
Newsgroups: borland.public.jbuilder.java.api
Subject: Re: OutOfMemoryError
References: <3D20CC5D.B70473C9@hfx.eastlink.ca> <MPG.178acb912dba8f7998b79d@newsgroups.borland.com> <3D21C1CA.F2D953E2@hfx.eastlink.ca> <3d21bb44_1@dnews> <3D21EC78.228A5CD3@hfx.eastlink.ca> <3d21e07b_2@dnews> <3D226288.1C7C905@hfx.eastlink.ca> <3d22ec28_1@dnews> <3D233ADD.C365148D@hfx.eastlink.ca> <3d245dff_2@dnews>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 24.222.101.2
X-Trace: dnews 1025820163 24.222.101.2 (4 Jul 2002 15:02:43 -0700)
Lines: 518
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!supernews.com!iad-peer.news.verio.net!news.verio.net!news.maxwell.syr.edu!nntp-relay.ihug.net!newsfeeds.ihug.co.nz!ihug.co.nz!dnews