The situation is as follows in my application I have 2 threads that run parallely, the purpose of one of the threads is to capture screenshots and the purpose of the second thread is to rename the screenshots that have been saved in a specific folder by the first thread – the code for the application is as follows -:
CapturingAndRenamingSimultaneously.java
/**
* Created with IntelliJ IDEA.
* User: AnkitSablok
* Date: 15/1/13
* Time: 1:03 PM
* To change this template use File | Settings | File Templates.
*/
package com.tian.screenshotcapture;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class CapturingAndRenamingSimultaneously {
public static void main(String[] args) {
// we use the linked blocking queue here to resolve the concurrency issues
final BlockingQueue<File> queue = new LinkedBlockingQueue<File>(1024);
new Thread(new Runnable() {
@Override
public synchronized void run() {
try {
System.out.println("In the capture thread now");
CaptureScreenshots.captureScreenshots(queue);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public synchronized void run() {
try {
while (true) {
System.out.println("In the rename thread now");
RenameScreenShots.renameScreenshots(queue);
Thread.sleep(5000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
CaptureScreenshots.java
/**
* Created with IntelliJ IDEA.
* User: AnkitSablok
* Date: 15/1/13
* Time: 12:35 PM
* To change this template use File | Settings | File Templates.
*/
// this code is used to capture the screenshots
package com.tian.screenshotcapture;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class CaptureScreenshots {
// this code is used to capture the screen shots
public static void captureScreenshots(BlockingQueue<File> queue) throws Exception {
String fileName = "C:\\Users\\ankitsablok\\Desktop\\Screenshots";
int index = 0;
for (; ; ) {
++index;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, "jpg", new File(fileName + "\\i" + index + ".jpg"));
queue.put(new File(fileName + "\\i" + index + ".jpg"));
Thread.sleep(1000);
}
}
}
RenameScreenShots.java
/**
* Created with IntelliJ IDEA.
* User: AnkitSablok
* Date: 15/1/13
* Time: 12:49 PM
* To change this template use File | Settings | File Templates.
*/
package com.tian.screenshotcapture;
import java.io.*;
import java.util.concurrent.BlockingQueue;
public class RenameScreenShots {
public static void renameScreenshots(BlockingQueue<File> queue) throws IOException, InterruptedException {
for (int i = 0; i < queue.size(); ++i) {
File sourceFile = queue.take();
System.out.println("The filename is : " + sourceFile.getName());
if (sourceFile.getName().contains("sent")) {
} else {
System.out.println("The modified name of the source file is :" + sourceFile.getName().substring(0,
sourceFile.getName().indexOf('.'))
+ "sent" + ".jpg");
File newFile = new File(sourceFile.getParent() + "/" + sourceFile.getName().substring(0,
sourceFile.getName().indexOf('.'))
+ "sent" + ".jpg");
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(newFile);
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
System.out.println("The file was deleted successfully : " + sourceFile.delete());
fis.close();
fos.close();
}
}
}
}
I want the access to the folder to be synchronized that is when one process writes the images to the folder after that the other process should be able to rename the images in the folder. But I am not able to synchronize access to the folder in which the screenshots are written and read, at some point of time using the above code gives a FileNotFoundException with the error that some other process is using the file. How can I resolve this problem.
Thanks in advance.
Create a shared queue between two threads
LinkedBlockingQueue.From the thread
CaptureScreenshotsput into this queue the newly createdFileobjects.From the thread
RenameScreenShotssequentially read from this queue preparedFileobjects and process them.UPD: If you are afraid of that billions of image file will eat a lot of memory by their
Filedescriptor, you can apply such an algorithm enhancing:Create subfolders in a folder, which contains your image files and put image files into this subfolders.
Name those subfolders with integer names:
1,2,3, … ,89.Artificially limit number of files in each subfolder. When the number of files reaches the limit, just increase the name-number of the subfolder, create a new one and go on.
Instead of putting
Filedescriptor for each image file toLinkedBlockingQueue, put thereIntegerobjects, where each will correspond to filled subfolder with same name.Inside
RenameScreenShotstake new element fromLinkedBlockingQueue, consider this element as a subfolder name and process all quietly files within this subfolder.UPD-2 The scheme introduced in my
UPD-1could be more easily implemented using a sharedsynchornizedgetter of some integer value, which will correspond to the last number of the processed subfolder.