Reputation: 70
my program is meant to load an image, resize it, save it, send it to FTP server and then delete resized image. Full code - HERE
The problem I am encountering is after pressing a finish button from the file named AddBreedBuilder.java: program sends resized file to server, freeze for ~1 sec, and it is trying to remove resized file (but it is not possible).
I tried to use (at the moment this part is deleted from java file, line 165): File fileToDelete = new File(imgPath);
boolean success = fileToDelete.delete();
but success
is always false
. Only way to delete this file is to not run sendToFTP()
.
From what I think, my program is using this file during file delete operation, so it cannot be deleted.
My question is: is it possible to delay file delete till program unfreeze? Or maybe there is way to send resized file without saving it?
Upvotes: 0
Views: 786
Reputation: 151
Beyond the questions you've asked, a few things are wrong with the code itself and it affects the answers to the questions. I'll address these later. However, to directly address your questions first:
Yes. You can do this by starting a new thread that handles the FTP transmission, since the transmission is initiated as the result of a GUI event, so that it doesn't freeze your application. (The event dispatch thread that handles the GUI only starts the new thread without waiting for it to finish.) In sendToFTP()
, do:
public static void sendToFTP(String fileName, String name) {
Thread sender = new Thread() {
public void run() {
FTPClient client = new FTPClient();
try {
FileInputStream fis = new FileInputStream(new File(fileName));
client.connect("serwer1978625.home.pl");
client.login("[email protected]", MyBreed.getPassword());
client.changeWorkingDirectory("/breeds");
client.setFileType(FTP.BINARY_FILE_TYPE);
client.storeFile(name, fis);
// client.rename(fileName, name); // not necessary
client.logout();
// At this point you must close the FileInputStream, since that is what is using the file, as you noticed.
fis.close();
// TODO: your code to delete the file comes in here, if everything goes well
// Alternatively, you could do these in the finally block to run irrespective of how the above code executes
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
client.disconnect();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
};
// the event dispatch thread only starts the sender thread and exits this function,
// hence no freezing occurs
sender.start();
}
Then in the calling function, buildAdd()
// ...
sendToFTP(imgPath, userBreedInfo[0] + ".jpg");
// ...
You can definitely send the file (more precisely, the file contents) without having to produce the file at all. You can instead supply the BufferedImage
directly to the sendToFTP()
method, and then transform that to the required InputStream
for client.storeFile()
. In this case you don't even need to store the file at all in the first place if you don't need it on the local machine.
public static void sendToFTP(BufferedImage bimage, String name) {
// ... some code
// Here we need an input stream for storeFile(), so we get that from an output stream
// produced in turn by the buffered image
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ImageIO.write(bimage, "png", outStream);
InputStream is = new ByteArrayInputStream(outStream.toByteArray());
// ... some code
client.storeFile(name, is);
// ... rest of code
}
Then in the calling function, buildAdd()
// ...
sendToFTP(bimage, userBreedInfo[0] + ".jpg");
// ...
Notice the change in the signature of the second version of sendToFTP()
. You could play with this idea in a different way, and rather replace the file writing call in buildAdd()
with this InputStream
, and then pass the stream to sendToFTP()
.
Note You can use the try-with-resources idiom for ensuring the streams used above are automatically closed: see here for example.
Other issues addressed:
buildAdd()
).Upvotes: 2
Reputation: 718698
From what I think, my program is using this file during file delete operation, so it cannot be deleted.
That is correct.
The reason is that your sendToFTP
method opens the file that it is sending to the server, but it doesn't (ever) close it. Since the file is still open, Windows won't let the app delete it
Solution: modify your sendToFTP
method so that the FileInputStream
is always closed.
Upvotes: 1