I'm having trouble opening a file. The hasNext seems to crashing with the following error java.lang.NullPointer. This is my the code that's erring out (with hasNext).
import java.io.*;
import java.util.Scanner;
public class Customers{
private Scanner opener;
public void openFile() {
try {
opener = new Scanner (new File ("customer.txt"));
} catch (Exception f) {
System.out.println("Can not read file.");
}
}
public void readFile() {
while(opener.hasNext()) {
String a = opener.next();
String b = opener.next();
String c = opener.next();
System.out.printf("%s %s %s\n", a, b, c);
}
}
public void closeFile() {
opener.close();
}
}
and this is the other class:
public class fileTest {
public static void main (String args []) {
Customers c = new Customers();
c.openFile();
c.readFile();
c.closeFile();
}
}
opener might be null as there could be an exception in opening the file
public void openFile() throws Exception{
opener = new Scanner (new File ("customer.txt"));
}
If there is any exception in opening the file, then just a message is printed and opener remains null which will lead to NPE in opener.hasNext()
You should not catch the exception instead throw the exception because if you are not able to open the file, then the code should fail and the other methods should not execute.
Your question is not clear, but you seem to be saying that opener.hasNext() is throwing an NPE.
If so, that means that opener is null. That in turn means that either you are not calling openFile() OR you are calling it but it is not working. I suspect the latter, especially since the main method does call openFile().
If the openFile() method fails to open the file (e.g. because it doesn't exist with the pathname as given), then a message is printed and opener remains null. This is probably what is happening.
The openFile() method has a number of flaws:
it is catching Exception ... which could catch other exceptions than the one(s) you are expecting.
it is not logging the stacktrace or the actual exception message
it is assuming that the problem is due to not being able to open the file ... when it could possibly be something else (in general, if not in this particular case),
once it has printed the error message, it just continues as if nothing bad had happened.
The NPE problems are then a consequence of the openFile() flaws.
Note that if you print out the actual exception message, it should tell you why the application is unable to open the file.
UPDATE
The error message customer.txt (The system cannot find the file specified) is clearly telling you that it can't find the file. The chances are that your application's current directory is not the directory that contains that file. Since you used a relative pathname, you told it it look in the current directory. The solution is to either use an absolute (full) pathname ... or make sure your application is launched with the right current directory.
Once you get past this problem, there is a problem in the way that you are reading the file. The readFile() method is assuming that it is going to be able to read multiples of 3 tokens (strings) from the input. If there is a problem with the file format, you are liable to get an (unchecked) exception. You probably should catch this exception and produce a diagnostic ... rather than assuming that nothing bad can happen.
First:Make sure your file actually exists in the disk, it is possible to create a File object even if the file does not exists.
Second:You are checkin for one element by doin opener.hasNext() and accessing next 3 elements!
When there is only one element in the list opener.hasNext() return true but you are accessing next 2 elements which are not present! hence the null pointer exception
your opener is not getting initialized that why the null pointer exception, make sure the file exists there and just try to give absolute path of the file
Check few points here:
Is your program reading the file specified?If you are using eclipse,keep your file in src folder and give path as opener = new Scanner (new File ("src/customer.txt"));
2.The second problem with your code is you are only checking once for while(opener.hasNext()) for next element and then reading three elements String a = opener.next();
String b = opener.next();
String c = opener.next(); .If there is no next element in your file you will get an exception ,check for each element before accessing it.
use this code instead:
public void readFile() {
while(opener.hasNext()) {
String a = opener.next();
System.out.printf("%s\n", a);
}
}
Related
Summary
I am looking at a scenario, such as this:
File someFile = null;
try
{
someFile = File.createTempFile( SOME_PREFIX, SOME_SUFFIX, targetDirectory );
}
catch( IOException e )
{
throw new SomeException( "Unable to create file for domain specific task", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
try( BufferedOutputStream stream = new BufferedOutputStream( new FileOutputStream( someFile.getAbsolutePath() ) ) )
{
stream.write( byteData, 0, byteData.length );
stream.flush();
}
catch( IOException e )
{
throw new SomeException( "Unable to write domain specific data to domain specific file", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
For this scenario someFile is initialized with null. My intent is to translate this code into something that follows proper practices.
What I considered
Simply initializing someFile to null, as shown in the current code snippet. However typically I am avoiding this, so this does not seem satisfactory as of now
Initializing someFile with e.g. an empty String. This provides a default instance of File of sorts. The problem I see with this is, if this error handling changes in the future, a valid File with nonsense properties could be passed to some other place inside the code.
Nesting the try-catch blocks. This does work, however for some reason feels bad, especially since both nested blocks catch IOException
An Optional<File> was also considered, I am however not convinced if every try-catch block where a somewhat complex object is initialized to be used outside that block justifies the use of Optional
Question
Is initializing someFile to null an antipattern? If so, how is a scenario, such as the one posted, handled best?
How about something like this:
public void yourMethod() {
File file = createFile();
writeFile(file);
}
private File createFile() {
try {
return File.createTempFile(...);
} catch(...) {
...
}
}
private void writeFile(File file) {
try(...) {
...
} catch(...) {
...
}
}
So your method stays clean and easy to understand.
EDIT: Or even return an Optional<File> from createFile:
private Optional<File> createFile() {
try {
return Optional.of(File.createTempFile(...));
} catch(...) {
...
return Optional.empty();
}
}
Then you can use Optional.ifPresent in yourMethod:
public void yourMethod() {
Optional<File> file = createFile();
file.ifPresent(value -> writeFile(value));
// or shorter:
createFile()
.ifPresent(this::writeFile);
// depends on how exactly the methods receive their parameters
}
You can just have
File someFile;
without any explicit assignment.
Java would then normally complain about using that variable before it has a value but the compiler is smart enough to understand that the only way the variable might not have a value is if createTempFile throws an IOException, but since you catch that and then throw again it knows that either the method exits here or someFile has a proper value. Therefore the later usages of someFile.getAbsolutePath() are allowed.
This is cleaner than null because now if you e.g. remove the re-throwing of the exception your code will not longer compile because now the compiler can no longer infer a value will always be assigned. If you init with null and remove the re-throw you will run into an NPE later on.
Optionals are not needed here because the compiler can in this case differentiate between non-initialized value and initialized value.
This is just for a simple command-line standalone program in Java.
I'd like to open a file to write to, and keep it open. I need to write formatted floats/doubles to it, in human-readable ASCII, like a CSV file.
I have tried various approaches (1) (2) (3) I have found through my favorite search engine, and they have the form:
try {
// some file handle opening sequence
}
catch ( <some exception> ) {
// do something
}
finally {
// do something else
}
(...or in the case of the third example, the file opening/writing/closing is inside a function that throws an exception.) I realize it's good programming style to make sure that you've opened a file ok, but for my purposes that's really not necessary.
Anyway the problem with the above approach is that outside of the try{} block, the filehandle is closed. I'd like to keep it open, because the kernel of my code consists of a huge loop that I go through a few 100,000 times (say), and each time through I'd like to output a single float (in ASCII) to the file.
With the above form, the only way to do that is to enclose my huge for loop inside the try{} block. Which seems silly. Alternatively, I could re-open the file every time through the loop, but that means additional logic, opening the file as a 'new' file the first time, and appending in all subsequent times.
Is there some way to open the file, keep it open to write to it occasionally, and then close it when I'm done?
Something like:
{
// open file "data.out"
}
for (i=0;i<100000;i++) {
// do a lot of stuff
//
// calculate some quantity "x"
//
// output float "x" in ASCII form, appending it to data.out
}
{
// close data.out
}
Does Java allow that? Thanks.
Of course you can simple store your FileWriter somewhere, as any other variable. You can, for example, encapsulate the whole writing logic in its own class, which offers one write method for your specified format.
But why does it seem silly? Perhaps this approach might help...
public void methodA(File myFile) throws IOException{
try ( FileWriter writer = new FileWriter( myFile ) ) {
writeTo(writer);
}
}
private void writeTo(FileWriter writer) throws IOException {
for (i=0;i<100000;i++) {
// do a lot of stuff
//
// calculate some quantity "x"
//
// output float "x" in ASCII form, appending it to data.out
}
}
This way, one method takes care of the opening/closing/exceptions, while the other method can concentrate on the important writing stuff, using the FileWriter given to it.
as you said the file is closed at the end of the try block. Possibly
the FileWriter object is created inside the try block:
(You did not post a real java code, only a pseudo code.)
Example, hope this helps
public static void main(String[] args)
{
...
BufferedWriter ofs=null; // should by outside the try block
try
{
Path logfile = Paths.set("C:\\temp\\log.log");
ofs = Files.newBufferedWriter(logfile); // new in java 8
YourWorker.doYourJob(ofs);
} catch (Exception e)
{ e.printStackTrace();
} finally
{
if (ofs!=null) { try { ofs.close(); } catch (Exception e) {} }
}
System.exit(1);
} //---------- end of main()
} //---- end of class
I'm working on a program that uses JavaFx to display icons in a list.
I've made a static class used to look up specific ids from a txt document. Originally, the static block would add the id and name of an item defined on each line, but since these issues arose, I've tried to find the source of the issue.
Instead, I've just gone through the text file's content in the static block and have printed it out to the console.
This is my code for reference:
public class ItemIds {
public static int UNDEFINED_ID = -1;
private static HashMap<String, Integer> items;
static {
items = new HashMap<String, Integer>();
System.out.println(new File("res/ids/item ids.txt").exists());
try {
//should print out every line in the text file
Files.lines(Paths.get("res/ids/item ids.txt")).forEach(s -> {
System.out.println(s);
});
} catch (IOException e) {
System.out.println("Unable to read specified file.");
e.printStackTrace();
}
}
public static int getId(final String name) {
final Integer id = items.get(name);
return id != null ? id : UNDEFINED_ID;
}
}
However, what I do get when this static class is initialized and the static block is invoked is quite odd. It lists every single line without error until it gets to line 10691, where it throws "Exception in thread "JavaFX Application Thread" java.lang.ExceptionInInitializerError".
What makes this particularly weird, however, is that when I work with a smaller text document (with less entries), everything seems to work fine. Since the file is comprised of almost 14000 lines, I have to delete ~4000 lines for it to be able to work.
Any ideas on why it would be doing this? Any feedback is appreciated - thank you
I am unable to reproduce this error. I have created a file with 18K lines and you program just works fine with that. So, definitely consider reviewing your file and also the stack trace.
Now coming back to your exception ExceptionInInitializerError, the following is a possible:
ExceptionInInitializerError signals that an unexpected exception has occurred in a static initializer. An ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer or the initializer for a static variable.
class ItemIds
{
static
{
// if something does wrong -> ExceptionInInitializerError
}
}
Because static variables are initialized in static blocks there is a potential for introducing errors too. An example:
class ItemIds
{
static int v = D.foo();
}
=>
class ItemIds
{
static int v;
static
{
v = D.foo();
}
}
So if foo() goes crazy then you can get a ExceptionInInitializerError.
Have you presented your complete code in static block?
I have searched pretty thoroughly and I'm fairly certain that no one has asked this question. However, this may be because this is completely the wrong way to go about this. I once wrote an effective java program that copied files from one directory to another. If the file already existed in the corresponding directory it would be caught with an exception and renamed. I want to use this program for another application, and for this I want it to do nothing when the exception is caught, simply continue on with the program without copying that file. I will be using this to fix approximately 18gb of files when it works, if it even printed one character when the exception was caught it would be extremely inefficient. This is the code I have so far:
import java.nio.file.*;
import java.io.IOException;
public class Sync
{
public static void main(String[] args)
{
String from=args[0];
Path to=FileSystems.getDefault().getPath(args[1]);
copyFiles(from, to);
}
public static void copyFiles(String from, Path to)
{
try(DirectoryStream<Path> files= Files.newDirectoryStream(FileSystems.getDefault().getPath(from)))
{
for(Path f:files)
{
Files.copy(f, to.resolve(f.getFileName()));
System.out.println(" "+f.getFileName()+" copied ");
}
}
catch(FileAlreadyExistsException e)
{
//not sure
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Is there a way to use FileAlreadyExistsExcpetion to do this?
I wouldn't use the try/catch to perform a user logic, this is wrong from a programming point of view and also not efficient.
What I would do is to check if the file exists, and n that case skip the copy operation or do whatever you want
for(Path f:files)
{
//here use Files.exists(Path path, LinkOption... options)
Files.copy(f, to.resolve(f.getFileName()));
System.out.println(" "+f.getFileName()+" copied ");
}
Here the Files docs:
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
Good luck
This is my code. It thinks that the config area section = null.
Heres the code:
public void loadArenas() {
fc1 = new File(plugin.getDataFolder(), "config.yaml");
if (!fc1.exists()) {
try {
fc1.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
fc = YamlConfiguration.loadConfiguration(fc1);
for (String keys : fc.getConfigurationSection("Arenas.").getKeys(false)) {
Oh and heres the error:
Error
fc1 is initialized, but fc is not.
You should print out the contents of fc1 at the top. It is very likely that you are running into path-related issues and so a new, EMPTY, configuration file is created.
That new file is then used as the input to fc, and naturally the "Arenas." section wouldn't exist. The NPE would either be thrown when you try to access the non-existent section's keys via getKeys().
Either way, if you are not sure what the problem is, you can either step through it with a debugger or just throw print statements everywhere to determine that things are what you expect.