Article View: borland.public.jbuilder.java.api
Article #923Re: OutOfMemoryError
From: Alan Shiers
Date: Thu, 04 Jul 2002 23:05
Date: Thu, 04 Jul 2002 23:05
518 lines
17910 bytes
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!dnewsReferences:
<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