Java continue executing loop if exception was throwd - java

Example: say I want to open a file. If I get a FileNotFoundException, I need to wait for some time and try again. How can I gracefully do that? Or do I need to use nested try/catch blocks?
Example :
public void openFile() {
File file = null;
try {
file = new <....>
} catch(FileNotFoundException e) {
}
return file;
}

You could use a do { ... } while (file == null) construct.
File file = null;
do {
try {
file = new <....>
} catch(FileNotFoundException e) {
// Wait for some time.
}
} while (file == null);
return file;

public File openFile() {
File file = null;
while (file == null) {
try {
file = new <....>
} catch(FileNotFoundException e) {
// Thread.sleep(waitingTime) or what you want to do
}
}
return file;
}
Note that this is a somewhat dangerous method, since there is no way to break out unless the file eventually appears. You could add a counter and give up after a certain number of tries, eg:
while (file == null) {
...
if (tries++ > MAX_TRIES) {
break;
}
}

public File openFile() {
File file = null;
while(true){
try {
file = new <....>
} catch(FileNotFoundException e) {
//wait for sometime
}
if(file!=null){
break;
}
}
return file;
}

Related

Java ZipInputStream breaks in a thread, but not in main thread

I'm unable to wrap my head around this. The following code works perfectly:
public static void main(String[] args) {
//new Thread(() -> {
try {
Path zipFile = Paths.get("C:\\path\\to\\zipfile.zip");
Path outDir = Files.createDirectories(Paths.get("C:\\path\\to\\outDir"));
try (ZipInputStream inputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
ZipEntry entry;
while ((entry = inputStream.getNextEntry()) != null) {
Path outPath = outDir.resolve(entry.getName());
if (entry.isDirectory()) {
if (!Files.exists(outPath)) {
Files.createDirectory(outPath);
}
} else {
try (OutputStream outputStream = Files.newOutputStream(outPath)) {
inputStream.transferTo(outputStream);
}
}
System.out.println(entry.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
}
//}).start();
}
However, uncommenting the thread code causes the program to hang at the exact same file every time:
public static void main(String[] args) {
new Thread(() -> {
try {
Path zipFile = Paths.get("C:\\path\\to\\zipfile.zip");
Path outDir = Files.createDirectories(Paths.get("C:\\path\\to\\outDir"));
try (ZipInputStream inputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
ZipEntry entry;
while ((entry = inputStream.getNextEntry()) != null) {
Path outPath = outDir.resolve(entry.getName());
if (entry.isDirectory()) {
if (!Files.exists(outPath)) {
Files.createDirectory(outPath);
}
} else {
try (OutputStream outputStream = Files.newOutputStream(outPath)) {
inputStream.transferTo(outputStream);
}
}
System.out.println(entry.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
If I try to debug the program, it works fine, only when running in non-debug mode, within a thread does this occur. Furthermore, the zip extracts without issue using Windows Explorer and 7-Zip. I'm approaching hair-pull-out levels on this, any help is greatly appreciated.
For reference, the zip file I'm using for testing (I'm working on a mod launcher for 7 Days to Die) can be found here: https://github.com/KhaineGB/DarknessFallsBBM45/archive/refs/heads/master.zip

How to prevent the block from being displayed, finally, if there is no path to the file

Problem: if the path to the file was not specified in the arguments, then it still displays the phrase "The file was closed". This works 2 times. In uploadToFile and read method. I pass one path in the arguments, and the second is written in the DownloadFile
public class Task implements AutoCloseable {
public static void main(String[] args) throws IOException {
String DownloadFile = "C:\\Users\\VGilenko\\IdeaProjects\\Task\\src\\main\\resources\\Out.txt";
Map<String, Departament> departments = new HashMap<>();
String path = args.length > 0 ? args[0] : null;
read(path, departments);
transferToDepartment(departments, DownloadFile);
}
private static void uploadToFile(List download, String path) {
int i = 0;
try (FileWriter writer = new FileWriter(path, false)) {
...
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
} finally {
System.out.println("The file was closed");
}
}
public static void transferToDepartment(Map<String, Departament> departments, String downloadFile) {
List<String> download = new ArrayList<>();
...
}
uploadToFile(download, downloadFile);
}
public static void read(String path, Map<String, Departament> departments) throws IOException {
assert path != null;
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path), "CP1251")); br) {
.....
}
}
} catch (FileNotFoundException e) {
System.out.println("The file was not found, check the path");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Correct the file path, step out of the array");
} catch (NullPointerException e) {
System.out.println("You forgot to register the path to the file");
} finally {
System.out.println("The file was closed");
}
}
#Override
public void close() {
System.out.println("The file was closed");
}
}
You have your printout "The file was closed" in your finally statement. If you don't specify a file, you will catch an Exception, and your finally block will be executed.
An easy fix would be to check for the existence of the path (not being empty, not being null).

Search for string in all files inside a Directory

I want to search for particular string inside all files in a Directory.
Ex: Search for "tiger" in path D:/test/chapters/
D:/test/chapters
/chapter1.log
/chapter2.log
/chapter3.log all these sub files under D:/test/chapters/ .
Sample code I have tried :
public class Example {
public Example() {
super();
}
public int plugin_execute() {
boolean foundstring=false;
try {
File dir = new File("D:/test/chapters");
String[] children = dir.list();
if (children == null) {
System.out.println("does not exist is not a directory");
} else {
for (int i = 0; i < children.length; i++) {
String filename = children[i];
System.out.println(filename);
if (filename !=null) {
foundstring = testString(filename, "tiger");
System.out.println("failed");
}
//Search for entry in file
if (!foundstring) {
return //failuremsg
} else {
System.out.println("failed");
return //succes
}
}
}
return 1;
} catch (Exception e) {
return //error mssg
}
}
private boolean teststring(String filePath, String str) {
BufferedReader br = null;
File file = new File(filePath);
boolean result = false;
if(!file.exists())
return false;
try {
br = new BufferedReader(new FileReader(filePath));
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
if (sCurrentLine.contains(str)) {
result = true;
System.out.println(str);
System.out.println("Found entry ");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
}
It only returns the output of last file, means if it search success in last file it return success otherwise failed.
But I want success if string is found in first file. i.e chapter1 should return success, if not found in Chapter1 it should continue search in chapter2 ....
Please suggest how can I modify this code..
Problem: Simple mix-up with ! and true/false locations.
Solution: Change this
if (! foundString)
{
return // failuremsg
}
else
{
System.out.println("failed");
return // success
}
to
if (foundString)
{
// return success message
}
else
{
// return failure message
}
Another problem I believe I see in your code is that the line foundstring = findString(filename, "tiger"); calls the method findString, whereas the other method you posted in your code is testString. I assume this is a name mix up.
public void listFiles(Path dir , String text)
{
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir))
{
for (Path path : directoryStream)
{
if (Files.isRegularFile(path) && Files.isReadable(path))
{
//this.findString(path, text);
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
private boolean findString(Path file, String text)
{
//Your implementation
return true;
}

file.delete() wont delete file, java

Okay, this is going to be a bit long. So I made a junit test class to test my program. I wanted to test if a method that uses a Scanner to read a file into the program threw and exception, if the file didn't exist like this:
#Test
public void testLoadAsTextFileNotFound()
{
File fileToDelete = new File("StoredWebPage.txt");
if(fileToDelete.delete()==false) {
System.out.println("testLoadAsTextFileNotFound - failed");
fail("Could not delete file");
}
try{
assertTrue(tester.loadAsText() == 1);
System.out.println("testLoadAsTextFileNotFound - passed");
} catch(AssertionError e) {
System.out.println("testLoadAsTextFileNotFound - failed");
fail("Did not catch Exception");
}
}
But the test fails at "could not delete file", so I did some searching. The path is correct, I have permissions to the file because the program made it in the first place. So the only other option would be, that a stream to or from the file is still running. So I checked the method, and the other method that uses the file, and as far as I can, both streams are closed inside the methods.
protected String storedSite; //an instance variable
/**
* Store the instance variable as text in a file
*/
public void storeAsText()
{
PrintStream fileOut = null;
try{
File file = new File("StoredWebPage.txt");
if (!file.exists()) {
file.createNewFile();
}
fileOut = new PrintStream("StoredWebPage.txt");
fileOut.print(storedSite);
fileOut.flush();
fileOut.close();
} catch(Exception e) {
if(e instanceof FileNotFoundException) {
System.out.println("File not found");
}
fileOut.close();
} finally {
if(fileOut != null)
fileOut.close();
}
}
/**
* Loads the file into the program
*/
public int loadAsText()
{
storedSite = ""; //cleansing storedSite before new webpage is stored
Scanner fileLoader = null;
try {
fileLoader = new Scanner(new File("StoredWebPage.txt"));
String inputLine;
while((inputLine = fileLoader.nextLine()) != null)
storedSite = storedSite+inputLine;
fileLoader.close();
} catch(Exception e) {
if(e instanceof FileNotFoundException) {
System.out.println("File not found");
return 1;
}
System.out.println("an Exception was caught");
fileLoader.close();
} finally {
if(fileLoader!=null)
fileLoader.close();
}
return 0; //return value is for testing purposes only
}
I'm out of ideas. Why can't I delete my file?
EDIT: i've edited the code, but still this give me the same problem :S
You have two problems here. The first is that if an exception is thrown during your write to the file, the output stream is not closed (same for the read):
try {
OutputStream someOutput = /* a new stream */;
/* write */
someOutput.close();
The second problem is that if there's an exception you aren't notified:
} catch (Exception e) {
if (e instanceof FileNotFoundException) {
/* do something */
}
/* else eat it */
}
So the problem is almost certainly that some other exception is being thrown and you don't know about it.
The 'correct' idiom to close a stream is the following:
OutputStream someOutput = null;
try {
someOutput = /* a new stream */;
/* write */
} catch (Exception e) {
/* and do something with ALL exceptions */
} finally {
if (someOutput != null) someOutput.close();
}
Or in Java 7 you can use try-with-resources.

Why my "Save" button doesn't work?

I have one of the biggest problem in my program. I've created Save button, but it saves if the .txt file is new (Then that button does "SaveAs" function). But when I open file, then type something and trying to save and it's not saving :S. Can anyone help me?
Here's the code:
fileSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(currentFile == null) {
int saveResult = fileSelect.showSaveDialog(null);
if(saveResult == fileSelect.APPROVE_OPTION) {
saveFile(fileSelect.getSelectedFile(), field.getText());
} else {
saveFile(currentFile, field.getText());
}
}
}
});
public void saveFile(File file, String contents) {
BufferedWriter writer = null;
String filePath = file.getPath();
if(!filePath.endsWith(".txt")) {
filePath += ".txt";
}
try {
writer = new BufferedWriter(new FileWriter(filePath));
writer.write(contents);
writer.close();
field.setText(contents);
setTitle("Editex - " + filePath);
currentFile = file;
} catch (Exception e) {
}
}
You aren't handling when currentFile != null, which is what I am assuming is the case when you are trying to save a file that already has a Filename.
Do something like this:
if(currentFile == null) {
// Handle if new file
} else {
// Handle an existing file
}
Move
saveFile(currentFile, field.getText());
into the else part of the above if else.
At the moment you have it within the if(currentFile == null), and this isn't the correct place as you are calling saveFile(null, field.getText()) here.
Also
catch(Exception e) {
}
is bad, never swallow an exception and do nothing with it, you will never know if an exception happens or not, just nothing will happen.

Categories

Resources