Scanner throws FileNotFoundException but using bufferedreader and inputstream doesn't? - java

I am trying to write code for a word guessing game, and it works well when I use bufferedreader and inputstream combined. But when I try it using scanner, it cannot find the file, even though in both instances the file is in the same folder. It is in a folder called res under the src folder in my project folder(I am coding in eclipse).
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
public class WordGen {
private final String filename = "/res/words.txt";
File file = new File(filename);
Scanner input = null;
private ArrayList<String> list = new ArrayList<>();
public WordGen() {
try {
input = new Scanner(file);
while (input.hasNextLine()) {
String w = input.nextLine();
list.add(w);
}
} catch (Exception ex) {
System.out.println("File not found.");
}
}
public String getword() {
if (list.isEmpty()) {
return "NOTHING";
}
return list.get((int) (Math.random() * list.size()));
}
}
public class test {
public static void main(String[] args) {
WordGen wordgen = new WordGen();
System.out.println(wordgen.getword());
}
}
I tried searching for this problem but couldn't find it here. I am guessing it's a very small error which I cannot figure out. Thanks and regards.
EDIT: Here's the other code that worked(Everything else same as before):
public WordGenerator()
{
try(InputStream input = getClass().getResourceAsStream(fileName);
BufferedReader bfreader = new BufferedReader(new InputStreamReader(input)))
{
String line = "";
while ((line = bfreader.readLine()) != null)
words.add(line);
}
catch (Exception e)
{
System.out.println("Couldn't find file");
}
}

Scanner is trying to load a file - and you're providing an absolute filename, /res/words.txt.
In order to create an InputStream, you're loading a resource, giving it an absolute resource name, even though you've called the variable fileName:
getClass().getResourceAsStream(fileName)
That works because it can load a resource called /res/words.txt from the classpath, but it's not loading a file with a filename of /res/words.txt.
You could use a filename of res/words.txt, if you run the code from the src directory... or you could just stick to using getResourceAsStream, which is probably a better idea as it doesn't rely on your working directory, and will continue to work even if your code and resources are packaged up into a jar file.
If you really want to use Scanner, you could always use new Scanner(input) - there's a Scanner constructor accepting an InputStream.

Related

It says Process Finished but there is no output

I'm new to java and I'm having a little problem with my code. There's no error and such, it just keeps saying process finished but no output was displayed. The filename is correct as I've checked.
import java.nio.file.;
import java.io.;
public class GuessingGame {
public GuessingGame() {
String filename = "C:\\Users\\angela\\Documents\\words.txt";
Path path = Paths.get(filename.toString());
try {
InputStream input = Files.newInputStream(path);
BufferedReader read = new BufferedReader(new InputStreamReader(input));
String word = null;
while((word = read.readLine()) !=null) {
System.out.println(word);
}
}
catch(IOException ex) {
}
}
public static void main (String[] args) {
new GuessingGame();
}
}
You are ignoring the exception and you don't close the file. Save some typing by using the built-in input.transferTo() for copying the file to System.out, and pass on the exception for the caller to handle by adding throws IOException to constructor and main.
Replace your try-catch block with this try-with-resources, which handles closing the file after use:
try (InputStream input = Files.newInputStream(path)) {
input.transferTo(System.out) ;
}
You managed to call the intended class, but you also needed to specify the specific function which you have declared in the function. Like so:
public static void main (String[] args) { GuessingGame gg = new GuessingGame; gg.GuessingGame(); }

Java error: getting FileNotFoundException

I´m trying to read from a file teste.txt but I only got FileNotFoundException.
(file teste.txt is located on c:\Java\teste.txt)
Here is a snippet of the code:
public class principal {
public static void main(String args[]) {
String test;
BufferedReader in = FileIO.getReader("c:\\Java\\teste.txt");
test = FileIO.getLine(in);
System.out.println(test);
}
}
public class FileIO {
public static BufferedReader getReader(String name) {
BufferedReader in = null;
try {
File file = new File (name);
String filePath = file.getAbsolutePath();
in = new BufferedReader(new FileReader(filePath));
}
catch (FileNotFoundException e) {
System.out.println("Arquivo não encontrado");
System.exit(0);
}
return in;
}
}
Could anybody help me...
Thanks
In order to debug this, you can use a utility method called
Path path = Paths.get("does-not-exist.txt");
boolean val = Files.exists(path);
You can use built-in methods of the java.nio.file package, instead of doing that BufferedReader thing you are doing.

Create a file which cannot be deleted by file.delete()

Note: I am aware there are several questions similar to this one, however, I cannot find any which explain how to resolve the situation I am trying to resolve. I will ask this question with a specific example, for which I need a solution.
Consider the code:
private final void writeToFile(final File parent, final String filename, final Charset charset, final String content) throws IOException {
final File file = new File(parent, filename);
if (file.exists()) {
LOG.warn("File {} already exists, file will be replaced.", file.getCanonicalPath());
if (!file.delete()) {
logAndThrow(String.format("Cannot delete file '%s'.", file.getCanonicalPath()), null);
}
}
try (final FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(fos, charset)) {
writer.write(content);
}
}
I am trying to write a unit test to provoke the IOException being thrown when the code cannnot delete the file. The unit test I have tried is as follows:
#Test public void testFileNotDeletable() throws IOException {
final File file = new File(folder.getRoot(), formattedFile.getMetaData().getFormattedCaptureFileName());
file.createNewFile();
try {
file.setReadOnly();
exception.expect(IOException.class);
exception.expectMessage(String.format("Cannot delete file '%s'.", file.getCanonicalPath()));
writer.write(formattedFile);
} finally {
file.setWritable(true);
}
}
I have also tried locking the file:
#Test public void testFileNotDeletable() throws IOException {
final File file = new File(folder.getRoot(), formattedFile.getMetaData().getFormattedCaptureFileName());
file.createNewFile();
try (FileInputStream fis = new FileInputStream(file)) {
final FileLock lock = fis.getChannel().tryLock(0L, Long.MAX_VALUE, true);
try {
exception.expect(IOException.class);
exception.expectMessage(String.format("Cannot delete file '%s'.", file.getCanonicalPath()));
writer.write(formattedFile);
} finally {
lock.release();
}
}
}
No matter what I try, the file.delete() successfully deletes the file, and the test fails, as the expected IOException was not thrown.
Any help greatly appreciated.
Note: Added for clarification, some extra code that shows that the File object is completely separate in the environments. The formattedFile being passed to the write method is not a File or sub-class of File, it is one of our internal classes. The File in the JUnit test is using a TemporaryFolder for the root, the formattedFile has a MetaData item, which determines the filename. In my JUnit test I am trying to create an empty file, which cannot be deleted, in the location that my actual code will attempt to write the file. I need file.delete() to return false, so that I can test the exception is being thrown. I therefore cannot mock a File object.
There are two solutions to your question, I recommend the first one.
Solution 1
You are not testing the java file I/O operations/class here, you are testing your code's functional behaviour in response to file operation. So, ideally in your JUnit you should be mocking the File object & its respective calls, and only focus on testing your code.
Solution 2
If you still wish to test full integration with java file IO, open file in write mode before attempting to delete, and it will take care of your test case.
NOTE: Code tested in CENTOS, WINDOWS, UBUNTU, MAC OS-X
Subject Class:
public class FileSolution {
public void fileHandler(File file) throws IOException, Exception {
if (file.exists()) {
LOG.warn("File {} already exists, file will be replaced.",
file.getCanonicalPath());
if (!file.delete()) {
logAndThrow(String.format("Cannot delete file '%s'.",
file.getCanonicalPath()),
new IOException(String.format("Cannot delete file '%s'.",
file.getCanonicalPath())));
}
}
}
}
Subject Uner Test:
import static org.mockito.BDDMockito.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class FileSolutionTest {
#Rule
public final ExpectedException exception = ExpectedException.none();
/**
* Solution 1
*
* #throws Exception
*/
#Test
public void testFileNotDeletableWithMock() throws Exception {
final File file = mock(File.class);
file.createNewFile();
// mock file & IO operations
given(file.exists()).willReturn(true);
given(file.delete()).willReturn(false);
given(file.getCanonicalPath()).willReturn("test.txt");
exception.expect(IOException.class);
exception.expectMessage(String.format("Cannot delete file '%s'.", file.getCanonicalPath()));
new FileSolution().fileHandler(file);
}
/**
* Solution 2
*
* #throws Exception
*/
#Test
public void testFileNotDeletable() throws Exception {
File file = null;
FileWriter fileWriter = null;
try{
file = new File("test.txt");
file.createNewFile();
file.deleteOnExit();
exception.expect(IOException.class);
exception.expectMessage(String.format("Cannot delete file '%s'.", file.getCanonicalPath()));
// open file with another process for writing
fileWriter = new FileWriter(file, true);
new FileSolution().fileHandler(file);
} finally{
if(fileWriter != null){
fileWriter.flush();
fileWriter.close();
}
}
}
}
I totally agree with Turing85 about using mockito.
Let's imagine you have an original class with a method similar to the one you want to test:
public class FileDel {
public void logOnIOException(File file) throws IOException {
if (file.exists()) {
LOG.warn("File {} already exists, file will be replaced.", file.getCanonicalPath());
if (!file.delete()) {
logAndThrow(String.format("Cannot delete file '%s'.", file.getCanonicalPath()), null);
}
}
}
public void logAndThrow(String msg, String s) {
//Do nothing
}
private static class LOG {
public static void warn(String msg, String path) {
}
}
}
Then you can trigger an inner exception in this way:
#RunWith(MockitoJUnitRunner.class)
public class FileDelTest {
#Test(expected = IOException.class)
public void testFileNotDeletable() throws IOException {
File file = mock(File.class);
when(file.exists()).thenReturn(true);
when(file.delete()).thenAnswer(new Answer<Boolean>() {
#Override
public Boolean answer(InvocationOnMock iom) throws Throwable {
throw new IOException();
}
});
FileDel f = new FileDel();
try {
f.methodToTest(file);
} finally {
}
}
}
What about open InputStream for this file and do not close it. Until file's descriptor will not be closed, file will not be deleted.
In order to prevent a file from being deleted you have to deny the security permission in windows. From the UI we would need to do something like
Right-click the file or document in your PC => Choose Properties;
In Security, tab Edit to change permission => Select Add and enter Everyone;
Press OK and select the group to change Full control permission to Deny;
Press Yes to confirm.
The only way I know of to change file permissions with Java are:
file.setExecutable(true|false);
file.setReadable(true|false);
file.setWritable(true|false);
and
File file = new File("test.txt");
if(file.exists())
{
//Setting file permissions for owner, group and others using PosixFilePermission
HashSet<PosixFilePermission> set = new HashSet<PosixFilePermission>();
//Adding owner's file permissions
set.add(PosixFilePermission.OWNER_EXECUTE);
set.add(PosixFilePermission.OWNER_READ);
set.add(PosixFilePermission.OWNER_WRITE);
//Adding group's file permissions
set.add(PosixFilePermission.GROUP_EXECUTE);
set.add(PosixFilePermission.GROUP_READ);
set.add(PosixFilePermission.GROUP_WRITE);
//Adding other's file permissions
set.add(PosixFilePermission.OTHERS_EXECUTE);
set.add(PosixFilePermission.OTHERS_READ);
set.add(PosixFilePermission.OTHERS_WRITE);
Files.setPosixFilePermissions(Paths.get("test.txt"), set);
}
else
{
System.out.println("Sorry...File doesn't exist.");
}
So, preventing a file from being deleted I would assume would have to do with file writing permissions. Try disabling the writable and maybe the executable permissions before trying to delete the file.
If this doesn't work then I do not believe it can be done with the Java language yet as these are the only methods available at the moment for changing file permissions. I could be wrong, but I have been unable to find anything else.
UPDATE
For Linux try the following:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ExecuteShellComand {
public static void main(String[] args) {
ExecuteShellComand obj = new ExecuteShellComand();
String command = "sudo chattr +i /backups/passwd";
// OR try
//String command = "sudo chattr +i -V /backups/passwd";
String output = obj.executeCommand(command);
System.out.println(output);
}
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}
The above makes /backups/passwd file immutable (or undeletable). This implies that the file can’t be modified in any way: it can’t be deleted or renamed. You can’t even create a link to it and no data can be written to the file as well.
That's about the only thing I can think of.
Hope this helps.
In Linux you can, with the chattr command set a file that is "immutable" that cannot be deleted even by root. Someone else said "set file permissions" which is right, but did not give specific detail.
Cheers
D

Stream to file from class

I am trying to work with file stream and i have a problem.
This is my code :
import java.io.*;
import java.util.*;
public class FileIO {
public static void main(String[] args) {
FileOperations myFile = new FileOperations("C:\\My_Programs\\eclipse\\MyJavaFiles\\myFile.txt");
}
private static class FileOperations {
String fileName;
// constructor without argument
FileOperations() {
fileName = "default";
}
/*
* constructor with argument
* argument is assinged into fileName
* fileName is used to open stream for input and output
*/
FileOperations(String argfileName) {
fileName = argfileName;
try {
// open ouput stream
PrintWriter fileOutput = new PrintWriter(new FileOutputStream(fileName));
// open input stream
BufferedReader fileInput = new BufferedReader(new FileReader(fileName));
} catch (IOException v) {
System.out.println(v);
}
}
}
}
My problem is, that if i implement whole FileOperations class in main method, it works fine and i can use fileOutput and fileInput without any problem.
But i wanted to implement those streams in other method and this is where i got stucked.
Why can't i use something like String fileLine = myFile.fileInput.readLine(); in main method? For me, it looks like those streams are not even opened despite they should be.
I am aware that i didn't close fileInput nor fileOuptu, i would close it after working with file.
Thank you for all advices and explanations!

code keeps throwing me an Exception

I have the next code which has to open a File given by the user. The adress in which the file is located is correct, but the problem is that it keeps throwing the exception FileNotFoundException and i can´t figure out what the problem is.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
public class OpenFile{
public static void main(String[] args) {
String fileName,name,r = "C:/Users/MyName/workspace/Proyect/";
Scanner t = new Scanner(System.in);
System.out.print("Give me the name of the file: ");
name = t.nextLine();
t.close();
fileName = r+name;
try
{
File f = new File(fileName);
RandomAccessFile ra = new RandomAccessFile(f,"r");
}
catch(FileNotFoundException ex)
{
System.out.println("cannot open file");
}
}
}
Couple Of Tips:
First, you should replace / this with File.separator
"CFile.separatorUsersFile.separatorMyNameFile.separatorworkspaceFile.separatorProyect`File.separator"
Second, your variables fileName and name are not intilized
it is better to define them like this.
String fileName ="";
String name=""; <------ which is more readable
Third it is good to put your scanner in try catch block with resources so there is not need to be close manualy like
try(Scanner input = new Scanner(System.in)){
}catch(FileNotFoundException e){
}
Hope these tips help you to solve your issue

Categories