내 응용 프로그램에서 상황은 다음과 같습니다. 병렬로 실행되는 2 개의 스레드가 있습니다. 스레드 중 하나의 목적은 스크린 샷을 캡처하는 것이고 두 번째 스레드의 목적은 특정 폴더에 저장된 스크린 샷의 이름을 바꾸는 것입니다. 첫 번째 스레드 - 다음과 같이 응용 프로그램의 코드는 - :java를 사용하여 폴더에 대한 액세스를 동기화하는 방법은 무엇입니까?
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();
}
}
}
}
나는 폴더에 액세스하려는 그 하나 개의 프로세스가 다른 프로세스를해야한다고 한 후 폴더에 이미지를 기록 할 때입니다 동기화하기 폴더의 이미지 이름을 바꿀 수 있습니다. 그러나 스크린 샷을 쓰고 읽는 폴더에 대한 액세스를 동기화 할 수는 없습니다. 위의 코드를 사용하여 어떤 시점에서 파일을 사용중인 다른 프로세스에서 FileNotFoundException 오류가 발생합니다. 이 문제를 어떻게 해결할 수 있습니까?
미리 감사드립니다.
LinkedBlockingQueue가 메모리 공간을 차지하면 모든 파일이 주 메모리 공간을 차지하므로 좋은 해결책이되지 않을 것입니다. 수십억 개의 이미지가 있다면 확실하게 이해할 수 없습니다. – AnkitSablok
'File' 개체가 있습니다. 간단히 말해서 일부 파일의 간단한 설명자 (간단히 말해서 디스크의 이름과 경로 만 포함하는 래퍼와 같은 것으로 간주합니다). 그것은 많은 기억을 먹지 않을 것입니다. – Andremoniy
글쎄, 링크 된 블로킹 큐는 반드시 파일 디스크립터를 참조로 저장합니다. 10 억 개의 레퍼런스를 사용하고 있다면 무슨 일을했는지 여전히 기억 문제가 될 것입니다. 또한 하위 폴더를 만드는 것에 대한 해결 방법은 내 일을 복잡하게 만들지 않을 것입니다. 아웃. – AnkitSablok