how to catch exceptions and continue the processing in Java - java

I have an applicaton where I am processing 5000 files to 6000 files during a loop.
In a try and catch block I am reading the excel file and processing each individual cell.
Of course all the Files are in the same format, but In some files the data in the cell in may vary it may contain data or not
when ever there is an exception while processing 100th file,
the whole processing is stopped and exception is thrown,
But I dont want that scenario, instead if there is an exception at 100th file, the iteration should continue with 101th file.
And in the end I should know which file is processed succesfully and which one is failed.
Exception which I am gettng are
NumberFormatException and NullPointerExceptions
How to hand that scenario?

The basic idea is to put the try-catch block inside the loops.
for (File file : files) {
try {
parseExcelFile(file); // Do whatever you want to do with the file
}
catch (Exception e) {
logger.warn("Error occurs while parsing file : " + file, e);
}
}

The way I would do it is to create a Map using the filename as a key and in your loop for each exception you could store the exception under the filename. You'd know which exceptions you caught and the files they were associated with.
Map fileExceptions = new HashMap<String, Exception>();
for(File file : files){
try{
<file processing>
}
catch(NumberFormatException e){
fileExceptions.put(fileName, e);
}
catch(NullPointerException e){
fileExceptions.put(fileName, e);
}
}

It's hard to be more specific without seeing some code, but this could be a possible approach:
public void processFiles(List<File> fileList)
{
for (File thisFile : fileList) {
try {
processOneFile(thisFile);
}
catch (Exception ex) {
printLogMessage(thisFile.getName());
}
}
}

Related

file.delete() returning false even file is writable

I'am trying to copy a file to a directory and then deleting it, but file.delete() keeps returning false
Here is my code:
for (File file : list) {
if (!file.isDirectory()) {
try {
FileUtils.copyFileToDirectory(file, path);
file.setWritable(true);
System.out.println(file.delete());
if(file.exists()){
file.deleteOnExit();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
Few ideas that you can work it out.
If you want to delete file first close all the connections and streams. after that delete the file
Make sure you have the delete permissions for the file
Make sure you are in right directory. Try using absolute path for deleting the file, in case delete is not working. Path might not be correct for the file.
Use Files.delete. The delete(Path) method deletes the file or throws an exception if the deletion fails. For example, if the file does not exist a NoSuchFileException is thrown. You can catch the exception to determine why the delete failed as follows: See Oracle docs here
try {
Files.delete(path);
} catch (NoSuchFileException x) {
System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
System.err.format("%s not empty%n", path);
} catch (IOException x) {
// File permission problems are caught here.
System.err.println(x);
}

why AsynchronousFileChannel for multi-thread I/Os throws java.nio.file.FileSystemException?

I want to have a class which instances from different threads will write or read from the same file. Below is pretty much the write operation but I get a java.nio.file.FileSystemException. I am using 2 instances as a trivial multi-thread access but I can't make it work
try {
fileChannel = AsynchronousFileChannel.open(Paths.get("Filename.txt"),
StandardOpenOption.READ,
StandardOpenOption.WRITE);
} catch (IOException e) {
e.printStackTrace();
}
Future<Integer> writeFuture =
fileChannel.write(ByteBuffer.wrap(obj.toString().getBytes()), position);
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
EDIT:
The stacktrace:
java.nio.file.FileSystemException: C:\Documents and Settings\Administrator\workspace\TileMap\FileMap.txt: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:90)
at sun.nio.fs.WindowsChannelFactory.newAsynchronousFileChannel(WindowsChannelFactory.java:199)
at sun.nio.fs.WindowsFileSystemProvider.newAsynchronousFileChannel(WindowsFileSystemProvider.java:138)
at java.nio.channels.AsynchronousFileChannel.open(AsynchronousFileChannel.java:248)
at java.nio.channels.AsynchronousFileChannel.open(AsynchronousFileChannel.java:300)
at slick.FileMap.updateFiguredMap(FileMap.java:84)
at agents.PlayerMap.seeFiguredMap(PlayerMap.java:196)
at agents.TickerExplorerRandomMapFile.seeFiguredMap(TickerExplorerRandomMapFile.java:206)
at agents.TickerExplorerRandomMapFile$1.onTick(TickerExplorerRandomMapFile.java:236)
at jade.core.behaviours.TickerBehaviour.action(TickerBehaviour.java:72)
at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:344)
at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1532)
at jade.core.Agent.run(Agent.java:1471)
at java.lang.Thread.run(Thread.java:722)
When your thread are finished updating the file, then it should close the stream. If a thread has an active file handle or it has not release the handle after finishing the update, then other thread will not be able to get the file handle. Most probably, that is the reason why you are getting the exception saying
"The process cannot access the file because it is being used by
another process."

Multiple Threads downloading same file from sftp server

I have a system that, when files of a certain type are found, I download, encode, and upload them in a separate thread.
while(true) {
for(SftpClient c : clients) {
try {
filenames = c.list("*.wav", "_rdy_");
} catch (SftpException e) {
e.printStackTrace();
}
if(filenames.size() > 0) {
//AudioThread run() method handles the download, encode, and upload
AudioThread at = new AudioThread(filenames);
at.setNode(c.getNode());
Thread t = new Thread(at);
t.start();
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
The run method from AudioThread
public void run() {
System.out.println("Running...");
this.buildAsteriskMapping();
this.connectToSFTP();
ac = new AudioConvert();
this.connectToS3();
String downloadDir = "_rough/" + getNode() + "/" + Time.getYYYYMMDDDate() + "/";
String encodeDir = "_completed" + getNode() + "/" + Time.getYYYYMMDDDate() + "/";
String uploadDir = getNode() + "/" + Time.getYYYYMMDDDate() + "/";
System.out.println("Downloading...");
try {
sftp.get(filenames, downloadDir);
} catch (SftpException e) {
//download failed
System.out.println("DL Failed...");
e.printStackTrace();
}
System.out.println("Encoding...");
try {
ac.encodeWavToMP3(filenames, downloadDir, encodeDir);
} catch (IllegalArgumentException | EncoderException e) {
System.out.println("En Failed...");
e.printStackTrace();
}
System.out.println("Uploading...");
try {
s3.upload(filenames, encodeDir, uploadDir);
} catch (AmazonClientException e) {
System.out.println("Up Failed...");
e.printStackTrace();
}
}
The download method:
public void get(ArrayList<String> src, String dest) throws SftpException {
for(String file : src) {
System.out.println(dest + file);
channel.get(file, dest + file);
}
}
The encode method:
public void encodeWavToMP3(ArrayList<String> filenames, String downloadDir, String encodeDir) throws IllegalArgumentException, EncoderException {
for(String f : filenames) {
File wav = new File(downloadDir + f);
File mp3 = new File(encodeDir + wav.getName().replace(".wav", ".mp3"));
encoder.encode(wav, mp3, attrs);
}
}
The upload method:
public void upload(ArrayList<String> filenames, String encodeDir, String uploadDir) throws AmazonClientException, AmazonServiceException {
for(String f : filenames) {
s3.putObject(new PutObjectRequest(bucketName, uploadDir, new File(encodeDir + f)));
}
}
The issue is I keep downloading the same files (or about the same files) for every thread. I want to add a variable for each client that holds the files that are being downloaded but I don't know how to remove the lists/filenames from this variable. What would be a solution? My boss would also like to only allow x amount of threads to run.
It's kind of hard to see the problem, as the code that actually does the download is missing :P
However, I would use some kind of ExecutorService instead.
Basically, I would add each download request to the service (wrapped in a "DownloadTask" with a reference to the file to be downloaded and any other relevant information it might need to get the file) and let the service take care of the rest.
The download tasks could be coded to take into account existing files as you see fit.
Depending on your requirements, this could be a single thread or multi-threaded service. It could also allow you to place upload quests in it as well.
Check out the Executors trail for more info
The general idea is to use a kind of producer/consumer pattern. You would have (at least) a thread that would look up all the files to be downloaded and for each file, you would add it to the executor service. After the file has been downloaded, I would queue and upload request into the same service.
This way, you avoid all the mess with synchronization and thread management :D
You could use the same idea with the scan tasks, for each client, you could a task to a separate service
There is a problem in your code where you instantiate AudioThread in a while loop.
Note that after you create a thread and do a t.start(), all downloading, encoding and uploading happens asynchronously. Therefore, after you start the thread the loop continuous to do another call to c.list(...) while the first thread you created is still processing the first set of files. Most probably the same set of files is returned in the succeeding c.list() calls since you specified a file pattern in the call and there is no code which marks which files are currently being processed.
My suggestion:
Use Executors.newFixedThreadPool(int nThreads) as mentioned in previous post. And specify the number of threads to the number of processors in your machine. Do this before your while loop.
For each filename you retrieved from ftp s.list(), create a Callable class and call ExecutorService.invokeAll(Collection<Callable<T>> tasks). The code in the Callable you will create is your AudioThread code. Modify AudioThread code to only process one file at at time (if possible), this way you are doing downloads,uploads, encoding in parallel for each file.
Add code which marks which files were already processed. I would suggest adding a code which renames the files you have processed to a different name to avoid getting returned in the next c.list() call.
Call ExecutorService.shutdown(...) after your while loop block

Unable to delete files using Java

I have written the following code to merge and delete the source files,but somehow the source files are not getting deleted.Can any one please throw some light on what i 'm missing here.
public void doDelete(List<String> dID)throws IOException {
String DID=null;
try{
for( ListIterator<String> iterator = dID.listIterator(); iterator.hasNext();)
{
DID= (String) iterator.next();
System.out.println("Deleting PDF" +DID);
File f =new File("E:\\TestFolder"+ "\\" +DID+".pdf");
if (!f.exists()) {
System.err.println("File " + f
+ " not present to begin with!");
return;
}
System.out.println(f.length());
System.out.println(f.getAbsolutePath());
boolean success = f.delete();
if (!success){
System.out.println("Deletion failed.");
}else{
System.out.println("File deleted."+DID);
}
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
TL;DR but file deletion failures is usually due to the file still being open. Especially as you are running it on Windows.
If you would like to get a reason for the delete failure you can use the Java 7 file API instead, it will give you the deletion failure reason as an exception.
java.nio.Files.delete(...)
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#delete(java.nio.file.Path)
In your createFileFromBlob method you are opening multiple FileOutputStreams (for each element of dID.listIterator()) but only closing the last one in your finally block. This will leave an open handle to all files other than the last, preventing them from being deleted as per Pulsar's answer.

Java isn't getting files in a directory

System.out.println("READ");
String currentWorldName = "RANDOM";
String propertiesFileDirectory = propertiesFolder + currentWorldName + "/props.properties";
String entitiesFolderDirectory = propertiesFolder + currentWorldName + "/Entities";
try
{
properties.load(new FileInputStream(propertiesFileDirectory));
}
catch (FileNotFoundException e)
{
//Since it doesn't exist either it was deleted by the user or hasn't been created yet.
createNewPropertiesFile();
}
catch (IOException e)
{
outputToLog("IOException when loading properties file for the world: '" + currentWorldName + "'.\n" + e.getStackTrace().toString());
}
//getting values from properties
//Now to read each properties file in Entities
File entitiesFolder = new File(entitiesFolderDirectory);
try
{
List<String> entitiesDirectoryContents = Arrays.asList(entitiesFolder.list());
//Read each file in the entities directory and load it into memory.
for (String entityPropertiesFileName : entitiesDirectoryContents)
{
if (propertiesBelongsToEntityCH(entityPropertiesFileName))
{
//Get properties one way
}
else //The properties file we're working does not belong to CH.
{
//Get properties from the same file a different way
}
}
//This should never be hit since we have the file to read.
catch (FileNotFoundException e)
{
outputToLog("FileNotFoundException when loading entity properties file." + e.getMessage().toString());
}
//I don't know when/if this would be hit. It hasn't happened.
catch (IOException e)
{
outputToLog("IOException when loading entity properties file." + e.getMessage().toString());
}
catch (NullPointerException e)
{
entitiesFolder.mkdirs();
}
This HAS been working, I swear. It just started doing this.
Java keeps claiming that the "entitiesFolder" directory doesn't exist (I check with entitiesFolder.exists()). I have a solution for when that happens as you can see, because while my program is running it definitely can happen. Well it still claims that the folder doesn't exist, over and over.
I'm absolutely positive that it's the right directory because I print the "entitiesFolderDirectory" out to the console. It's correct. I can also be looking at the files inside of that folder and when mkdirs() runs it just deletes them all.
Java bug? This has completely broken my program.
I would write it without throwing a NullPointerException.
File entitiesFolder = new File(entitiesFolderDirectory);
entitiesFolder.mkdirs();
for (String entityPropertiesFileName : entitiesFolder.list()) {
//Do stuff
}
This will always work unless the folder could not be created.
What is the problem with this code? only one curly braces i found is missing else it is working fine.
This will create a dir test in c drive if does not exist else it will list the files in test dir over n over again
String entitiesFolderDirectory = "C:\\test";
File entitiesFolder = new File(entitiesFolderDirectory);
try
{
List<String> entitiesDirectoryContents = Arrays.asList(entitiesFolder.list());
for (String entityPropertiesFileName : entitiesDirectoryContents)
{
System.out.println(entityPropertiesFileName);
}
}catch (NullPointerException e)
{
System.out.println("creating new folder");
entitiesFolder.mkdirs();
}

Categories

Resources