Handle java.nio.file.AccessDeniedException - java

I'm using this code to read value from a file.
public String getChassisSerialNumber() throws IOException
{
File myFile = new File("/sys/devices/virtual/dmi/id/chassis_serial");
byte[] fileBytes;
String content = "";
if (myFile.exists())
{
fileBytes = Files.readAllBytes(myFile.toPath());
if (fileBytes.length > 0)
{
content = new String(fileBytes);
}
else
{
return "No file";
}
}
else
{
return "No file";
}
return null;
}
I get this error:
java.nio.file.AccessDeniedException: /sys/devices/virtual/dmi/id/chassis_serial
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.Files.readAllBytes(Files.java:3149)
How I can handle this error? Because now I the code stops execution? Is there some better way without interruption the code execution?

You have to use try-catch, either within getChassisSerialNumber() on when calling it. E.g.
try {
getChassisSerialNumber();
} catch (java.nio.file.AccessDeniedException e) {
System.out.println("caught exception");
}
OR
try {
fileBytes = Files.readAllBytes(myFile.toPath());
} catch (java.nio.file.AccessDeniedException e) {
return "access denied";
}
This way your program does not terminate.
For a clean design you should either return null in cases you could not read the file (returning "magic strings like "No file" or "access denied" are no good design, because you cannot differentiate if this string came from the file or not) or catch the exception outside of the method (my first example).
Btw. by just putting the content of the file into the content variable you don't return it (i.e., replace content = new String(fileBytes); with return new String(fileBytes);)
public String getChassisSerialNumber()
{
File myFile = new File("/sys/devices/virtual/dmi/id/chassis_serial");
if (myFile.exists())
{
byte[] fileBytes;
try {
fileBytes = Files.readAllBytes(myFile.toPath());
} catch (java.nio.file.AccessDeniedException e) {
return null;
}
if (fileBytes != null && fileBytes.length > 0)
{
return new String(fileBytes);
}
}
return null;
}

You should catch the exception instead of throwing it. I think that you need to put a try-catch block around the call to the method getChassisSerialNumber.
Something like this should work in your case:
String result = null;
try {
result = getChassisSerialNumber();
} catch (java.nio.file.AccessDeniedException ex) {
// do something with the exception
// you can log it or print some specific information for the user
}
return result; // if the result is null, the method has failed
In order to understand better this kind of things you should have a look to this page

Related

How to raise and handle a FileNotFoundException() error

The task is to throw a FileNotFoundException() exception and handle it. You also need to check if the file exists on the computer and read data from it.
I wrote 2 methods, one searches for a file, the second one reads, but I am completely confused how to handle this exception. Can you suggest how to refactor this code to handle FileNotFoundException. And point out the errors of the code itself, since it is very terrible (I am just starting to learn Java)
public static boolean findFile(String path, String filename) throws FileNotFoundException {
File f = new File(path + "\\" + filename);
if (f.exists()) {
System.out.println("File found");
return true;
}
else {
System.out.println("File not found, please check that you entered the correct path and file name");
throw new FileNotFoundException();
}
}
public static ArrayList<String> readFromFile(String path, String filename) throws FileNotFoundException {
if(findFile(path,filename)) {
ArrayList<String> ip = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(path + "\\" + filename))) {
String line;
ip.add(br.readLine());
while ((line = br.readLine()) != null) {
ip.add(line);
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
return ip;
}
else {
System.out.println("Failed to read the file, check the correct path and file name");
return null;
}
}
The way you've defined the findFile method, it is always going to either return true or throw an exception. So it doesn't really make any sense to test the value returned by findFile(), or for that method to even return a value. Instead, you can assume that if the method does not throw an exception, then the file was found. For the case where it wasn't, you want to catch the exception and deal with it. Here's what that all looks like:
public static void findFile(String path, String filename) throws FileNotFoundException {
File f = new File(path + "\\" + filename);
if (f.exists()) {
System.out.println("File found");
}
else {
System.out.println("File not found, please check that you entered the correct path and file name");
throw new FileNotFoundException();
}
}
public static ArrayList<String> readFromFile(String path, String filename) throws FileNotFoundException {
try {
findFile(path,filename);
// Code to read the file...
...
}
catch (FileNotFoundException ex) {
System.out.println("Failed to read the file, check the correct path and file name");
return null;
}
}
The task is to throw a FileNotFoundException() exception and handle
it.
The answer to this question depends a lot on context.
If you are running this from the command line, you will want to add a try catch for the exception and then try again if it happens
Exception e;
do {
e = null;
try {
callAMethod();
} catch(ex) {
e=ex;
}
} while (e != null);
If you are doing this from a GUI/Swing, you can re-rethrow as a RuntimeException and use Log4j or Thread.setUncaughtExceptionHandler(..) to log the error and inform the user. The user can then try again
If you are doing this as a webapp, you will want to change the response code to 404 (FileNotFound) and indicate the file that was not found
Lastly, where you throw the FileNow FoundException, you should include a message
throw new FileNotFoundException(/*incude a string with the file path*/);

How could I deal with this custom Exception?

I have this bit of code which depends from a custom Exception thrown by a function inside findID() it throws a NoClientFound Exception that I made whenever this mentioned function returns a null (The client does not exist).
The IDE suggests that I shall apply that Exception into the code, but in this bit of code, where I need the ID to be null (unique IDs) I "can't catch that exception" since if I catch it, the function will not be executed as intended.
Question: How I can manage this?
Function with the Exception problem
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
if (findID(c.getID()) == null) {
try (BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));) {
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
} catch (IOException e) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE,
null, "Error appeding data to file" + e);
}
}
} catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
} finally {
}
return addded;
}
Exception Code
public class NoClientFound extends Exception {
private String msg;
public NoClientFound() {
super();
}
public NoClientFound(String msg) {
super(msg);
this.msg = msg;
}
#Override
public String toString() {
return msg;
}
You can catch that exception and handle it accordingly. When you catch NoClientFound exception that means findID(c.getID()) is null. So without handling that in the if block you can handle that within the catch block.
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
// call the function
findID(c.getID());
} catch (NoClientFound ex) {
//handle the NoClientFound exception as you like here
BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
}catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
}finally {
}
return addded;
}
I assume you already have a null check on findID(...)
if( c == null || findID(c.getID()) == null){
throw new NoClientFound("Client not found!");
}else{
//add your file writing operation
}
and Also in NoClientFound class extend it from RuntimeException, not the Exception.
public class NoClientFound extends RuntimeException {
...
}
Caller method:
public void caller(){
Client client = new Client();
client.setId(1);
...
try{
add(client);
}catch(NoClientFound ex){
//client not found then create one for ex...
}
catch(Exception ex){
//somthing else happend
log.error(ex.getmessge());
}
}

Csv file is empty when I writing content

I am trying write to a csv file. After the execution of the code bellow the csv file is still empty.
File is in folder .../webapp/resources/.
This is my dao class:
public class UserDaoImpl implements UserDao {
private Resource cvsFile;
public void setCvsFile(Resource cvsFile) {
this.cvsFile = cvsFile;
}
#Override
public void createUser(User user) {
String userPropertiesAsString = user.getId() + "," + user.getName()
+ "," + user.getSurname() +"\n";;
System.out.println(cvsFile.getFilename());
FileWriter outputStream = null;
try {
outputStream = new FileWriter(cvsFile.getFile());
outputStream.append(userPropertiesAsString);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public List<User> getAll() {
return null;
}
}
This is a part of beans.xml.
<bean id="userDao" class="pl.project.dao.UserDaoImpl"
p:cvsFile="/resources/users.cvs"/>
Program compiles and doesn't throw any exceptions but CSV file is empty.
If you're running your app in IDE, the /webapp/resources used for running app will differ from the /webapp/resources in your IDE. Try to log full path to file and check there.
try using outputStream.flush() as the final statement in the first of the try block.
I think you're looking at the wrong file. If you specify an absolute path /resources/users.cvs, then it probably won't be written into the a folder relative to the webapp. Instead, it will be written to /resources/users.cvs
So the first step is to always log an absolute path to make sure the file is where you expect it.
Try with this code, it will at least tell you where the problem lies (Java 7+):
// Why doesn't this method throw an IOException?
#Override
public void createUser(final User user)
{
final String s = String.format("%s,%s,%s",
Objects.requireNonNull(user).getId(),
user.getName(), user.getSurname()
);
// Note: supposes that .getFile() returns a File object
final Path path = csvFile.getFile().toPath().toAbsolutePath();
final Path csv;
// Note: this supposes that the CSV is supposed to exist!
try {
csv = path.toRealPath();
} catch (IOException e) {
throw new RuntimeException("cannot locate CSV " + path, e);
}
try (
// Note: default is to TRUNCATE the destination.
// If you want to append, add StandardOpenOption.APPEND.
// See javadoc for more details.
final BufferedWriter writer = Files.newBufferedWriter(csv,
StandardCharsets.UTF_8);
) {
writer.write(s);
writer.newLine();
writer.flush();
} catch (IOException e) {
throw new RuntimeException("write failure", e);
}
}

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.

How to get over Error when Reading from File into Java

My problem is in the following code.
The problem is that when I call the alreadyUser(String username) if the file doesn't exist on the system already, it gives the FileNotFoundException. I want to get over this error and I can not figure it out.
So at startup of the app the system asks for uname and pass. Then the alreadyUser method is called and it gives the error if the file is not already created hardly (I create it manually for example). And the next time I start the program if the file is already there it must not be switched with new, because the old data will be gone ofc :)
public final class TinyBase {
final static String FILENAME = "KEYVALUES.txt";
static FileOutputStream fos = null;
static FileInputStream fis = null;
protected static void createUser(String username, String password)
protected static boolean loadUser(String username, String password)
protected static boolean alreadyUser(String username) {
String encode = new String(username);
String compare = null;
boolean flag = false; // true - ok no such user ; false - fail username
// already in use
try {
/* ERROR IS HERE */
fis = new FileInputStream(FILENAME);
/* ERROR IS HERE */
byte[] buffer = new byte[fis.available()];
while (fis.read(buffer) != -1) {
compare = new String(buffer);
if (compare.contains(encode)) {
flag = true;
break;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
return flag;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}
Check if the file exists using -
File f = new File(filePathString);
if(f.exists()) { /* do something */ }
I guess, what you need according to your snapshot, is to handle FileNotFoundCase properly :
// ....
} catch (FileNotFoundException e) {
Log.d("no settings for the user - assuming new user");
flag = true;
}
BTW, you need to fix your finally block, in case of prior exception your fis may be null, so to avoid NullPointerException you may need an extra check :
if (fis != null) {
fis.close();
}
UPDATE
Here is sketch of what you may need based on my understanding of your problem :
// ... somewhere at startup after username/pass are given
// check if file exists
if (new File(FILENAME).isFile() == false) { // does not exist
fos = new FileOutputStream(FILENAME); // will create
// file for you (not subfolders!)
// write content to your file
fos.close();
}
// by this point file exists for sure and filled with correct user data
alreadyUser(userName);

Categories

Resources