1. what does new file in new File("scores.dat") line mean? It will create a new file?
2. When I run this piece of code, I get this as output:
"java.io.FileNotFoundException: scores.dat (The system cannot find the file specified)"
Does anybody know what the problem is?
3. There is not any "finally" section in this code; putting "finally" is optional in exceptions?
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class ReadAndPrintScores
{
public static void main(String[] args)
{
try
{
Scanner s = new Scanner( new File("scores.dat") );
while( s.hasNextInt() )
{
System.out.println( s.nextInt() );
}
}
catch(IOException e)
{
System.out.println( e );
}
}
}
1. new File("scores.dat") does not create the file. It will just create something like a handle to this file (whether it exists or not). You can use this File object to ask whether the file already exists, to create a new file if it does not exist yet, and so on. You can see a full documentation of the File class in the official JavaDocs.
2. Since you do not create the file by simply creating a File object for it, the file does not exist yet and so there is nothing to read from.
3. The finally structure is optional. It is good practice to use it to make sure you close resources you do not need anymore, because finally blocks are always executed if their according try block was entered. Read more about the finally keyword here.
new File() is the constructor of File class. So a new instance of File will be created.
scores.dat must be a file that exists in the same directory of your code.
Yes finally is optional
Check the Java Doc for more information about the File class.
Related
I have a main class that expects an input file name to be provided through the command line argument; if this is not true then the program exits with an error message.
We are assuming the existence of a class called SudokuReducer. After making sure there is an input file, the main function will pass the input file (not just the name of the file) to an instance of SudokuReducer.
What I want to know, is this bad form/practice? Is it wrong to put the entirety of the scan inside a try/catch like this? Because then if I wanted to declare the SudokuReducer instance in 'main' outside of the try/catch instead of in, I can't since it doesn't recognize what 'fileInput' has been passed due to its limited scope inside the 'try'
Is there a better way of doing this? Here's what I have:
import java.io.File;
public class MainMV {
File inputFile;
public static void main(String args[]) {
// check if file is entered and handle exception
try {
if (args.length > 0) {
File inputFile = new File(args[0]);
System.out.println("Processing file");
SudokuReducer reducer = new SudokuReducer(inputFile);
} else {
System.out.println("No file entered.");
System.exit(1);
}
} catch (Exception e) {
System.out.println("File failed to open.");
System.exit(1);
}
}
}
To answer the question in the title: no, it's not bad practice, if that method needs a File to do its work.
Another option would be passing a String; and that's a poor choice, because it doesn't convey that the parameter is supposed to represent a File of some sort.
Perhaps a better option would be to pass in an InputStream to the method, since a) that clearly conveys that it's going to be used for input (as opposed to being a File that you will write to); b) it's more flexible, because it doesn't have to refer to a file on disk.
To answer the question in the question: no, it's not really good practice to wrap everything in one try/catch like this. It makes it hard to distinguish the modes of failure: many different things could go wrong in your code, and it's better to handle those things separately, e.g. to provide specific failure messages.
A better way to structure the code is something like this:
if (args.length == 0) {
System.out.println("No file entered.");
System.exit(1);
}
File inputFile = new File(args[0]);
System.out.println("Processing file");
try {
SudokuReducer reducer = new SudokuReducer(inputFile);
// Do something with reducer.
} catch (IOException e) {
e.printStackTrace();
System.out.println("File failed to open.");
System.exit(1);
}
Note that this has small blocks, handling specific errors, rather than a great big block where the error handling is separated from the thing causing the error.
Also, note that it's not catching Exception: you really don't want to do that unless you have to, because you're not correctly handling exceptions that it would catch that have to be handled in special ways (i.e. InterruptedException). Catch the most specific exception type you can.
From my understanding, Java passes parameters as a reference of the object by value which for me was terribly confusing.
Link to explanation of Pass by Reference vs Pass by Value.
Link to explanation of the Java implementation
Depending on how much information from the file is required to generate an instance of your SudokuReducer class, the overhead of this could be significant. If this is the case, you'll want to parse your input line by line doing
something like this in your main method.
try {
SudokuReducer reducer = SudokuReducer.makeSudokuReducer(args[0])
}
catch(Exception e) {
System.out.println("No file entered.");
System.exit(1);
}
Here's an example of reading a file line by line
There are many ways to do this, but the most efficient way I can think of is by using Java 8's Stream and Files classes.
The method signature will look something like this:
public static SudokuReducer makeSudokuReducer(String filename) {
//Open file
//Parse input line by line
//Use information to create a new instance of your class
//Return the instance of this class
}
You'll be able to call this static method anywhere to produce a new instance of your class from a filename.
I have this text file of the format:
Token:A1
sometext
Token:A2
sometext
Token:A3
I want to split this file into multiple files, such that
File 1 contains
A1
sometext
File 2 contains
A2
sometext
I do not have much idea about any programming or scripting language as such, what would be the best way to go about the process? I was thinking of using Java to solve the problem.
if you want to use java, I would look into using Scanner in conjunction with File and PrintWriter with a for loop and some exception handling you will be good to go.
import the proper libraries!
import java.io.*;
import java.util.*;
declare the class of course
public class someClass{
public static void main(String [] args){
now here's where stuff starts to get interesting. We use the class File to create a new file that has the name of the file to be read passed as a parameter. You can put whatever you want there whether its a path to the file or just the file name if its in the same directory as your code.
File currentFile = new File("new.txt");
if (currentFile.exists() && currentFile.canRead()){
try{
next we create a scanner to scan through that newly created File object. the for loop continues on as long as the file has new tokens to scan through. .hasNext() returns true only if the input in the scanner has another token. PrintWriter writes and creates the files. I have it set that it will create the files based on the iteration of the loop (0,1,2,3 etc) but that can be easily changed. (see new PrintWriter(i + ".txt". UTF-8); )
Scanner textContents = new Scanner(currentFile);
for(int i = 0; textContents.hasNext(); i++){
PrintWriter writer = new PrintWriter(i + ".txt", "UTF-8");
writer.println(textContents.next());
writer.close();
}
these catch statements are super important! Your code wont even compile without them. If there is an error they will make sure your code doesn't crash. I left the inside of them empty so you can do what you see fit.
} catch (FileNotFoundException e) {
// do something
}
catch (UnsupportedEncodingException i){
//do something
}
}
}
}
and thats pretty much it! if you have any questions be sure to comment!
There is no best way and it depends on your environment and need actually. But for any language figure out your basic algorithm and try using the best available data structure(s). If you are using Java, consider using guava splitter and do look into its implementation.
In the following SSCCE, I do not get a FileNotFoundException even if I delete this file from the given location/path i.e. "D:\\Eclipse Workspaces\\SAMPLES AND OTHER SNIPPETS\\SoapCallResults.txt"
Rather the PrintWriter seems to create the file if it is not found.
If the Printwriter creates the file if it is not found, why do we try to handle the FileNotFoundException (compiler complains if we don't surround it with try/catch or add a throws clause) when it is never going to be thrown?
package com.general_tests;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class PrintWriterFileNotFoundExceptionTest {
public static void main(String[] args) {
String myName = "What ever my name is!";
PrintWriter printWriter = null;
try {
printWriter = new PrintWriter("D:\\Eclipse Workspaces\\SAMPLES AND OTHER SNIPPETS\\SoapCallResults.txt");
printWriter.println(myName);
} catch (FileNotFoundException e) {
System.out.println("FILE NOT FOUND EXCEPTION!");
e.printStackTrace();
} finally {
if (printWriter != null) { printWriter.close(); }
}
}
}
FileNotFoundException is a checked exception, which simply translates that you will have to either catch it or add it in the throws clause.
I hope this answers your question about why we actually need it even though a file is created if not present-
From javadoc -
FileNotFoundException - If the given file object does not denote an existing, writable regular file and a new regular file of that name cannot be created, or if some other error occurs while opening or creating the file
Replace Eclipse Workspaces in your path with foo and see if you get the exception. The file itself may be created, but not the whole path above it.
You can also leave the path exactly as it is, but set read-only, hidden, and system attributes on the file. The OS will not be able to either write or create it.
Another variation: modify the file's ACL so your user doesn't have the write permission.
There are many more.
FIleNotFoundException is a checked exception. You need to handle these type of exceptions if your codeblock is throwing them. For unchecked type of exceptions, you don't have to handle (not mandatory). Can you really guarantee that the file is created, but not corrupted or the disk record isn't corrupted? Also, look into this - Java: checked vs unchecked exception explanation.
Main thing is that your constructor is throwing FileNotFoundException (look here - https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html#print%28char%29), which you have to catch (because it is checked).
Tips - For Eclipse, try and see what ctrl+SPACe reveals about an object's method. If your JavaDoc is in the right location, you will see all the explanation of what a method is doing including "Throws: SomeException" bit. This is what you need to look for when calling a method (i.e. whether you need try catch block for this).
I am working on a basic game similar to Break Out and I plan to use a text file to store level data on where various objects should be located when a level is rendered onto the screen. Here is the code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class LevelData {
public LevelData(){
readFile();
}
public void readFile(){
try{
BufferedReader in = new BufferedReader(new FileReader("Levels"));
String str;
while((str = in.readLine()) != null){
process(str);
in.close();
}
}catch (IOException e){
System.out.println("File Does Not Exist");
}
}
private void process(String str){
System.out.println(str);
}
}
This following code, based off of previous research, should access the file "Levels" that is located in the same package as the Java class, but if the program cannot access the file then it should print "File Does Not Exist" to the console. I have created a file called "Levels" that is located in the same package as the Java class but whenever I run this class, it does not read the file properly and it catches the Exception.
Does anyone have any ideas on why it cannot access the proper file? I have already looked on various other threads and have found nothing so far that could help me.
Thanks in advance
Your Levels file probably doesn't want to be in the same package as the class, but rather, in the same directory from where your java program was run.
If you're using eclipse, this is probably the project directory.
Your issue is probably the lack of a file extension!
BufferedReader in = new BufferedReader(new FileReader("Levels.txt"));
In case you are running from Eclipse, the file should be accessed like new FileReader("src/<package>/Levels") .
Closing the inputstream in.close(); should happen outside the while loop.
As you said you plan to use a text file to store level data. One way to solve the problem is to provide relative path to the file while storing and while reading the file use the relative path to read the file. Please don't forget to specify the extention of the file.
I see a few problems, the first one being there's no file extension. Second, the in.close() is in the while loop, and since you are planning on storing high scores, I would recommend you would use an ArrayList.
It is always a good practice to specify the absolute path name of the file if the file is external to your jar file. If it is part of your jar file, then you need to get it using 'getResourceAsStream()'.
I'm trying to get my submit button to save the GUI in a text file, I've made the GUI and the button listener ...etc but I'm having trouble making the method that saves the information from the GUI into a text file.
so far i have:
public void save() {
File k1 = new File("documents/"+"newfile.txt");
try {
k1.createNewFile();
FileWriter kwriter = new FileWriter(k1);
BufferedWriter bwriter = new BufferedWriter(kwriter);
bwriter.write(txtField1.getText().trim());
bwriter.newLine();
bwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
but it doesn't seem to work, nothing happens; is there anything I'm missing?
You're file is called .txt - perhaps insert a name in the first row:
File k1 = new File("documents/filename.txt");
You should be getting an error when running that code.
The problem is that the document directory doesn't exist or it is not where you expected.
You can check for the parent directory with:
if(!k1.getParentFile().exists()){
k1.getParentFile().mkdirs();
}
Alternatively you need to set the file to be a more precise location.
org.apache.commons.lang.SystemUtils might be able to help you out here with user home.
i was just think is there a easier way, for example i already have the Jfilechoser open a "save as box" when the "submit" button is pressed so is there a easier way to create the file (saving the gui infomation in a txt file) ?
This is a continuation on your previous question. You should just get the selected file and write to it with help of any Writer, like PrintWriter.
File file = fileChooser.getSelectedFile();
PrintWriter writer = new PrintWriter(file);
try {
writer.println(txtField1.getText().trim());
writer.flush();
} finally {
writer.close();
}
Don't overcomplicate by creating a new File() on a different location and calling File#createFile(). Just writing to it is sufficient.
See also:
Java IO tutorial
update here's an SSCCE, you can just copy'n'paste'n'compile'n'run it.
package com.example;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.JFileChooser;
public class Test {
public static void main(String[] args) throws IOException {
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
PrintWriter writer = new PrintWriter(file);
try {
writer.println("Hello");
writer.flush();
} finally {
writer.close();
}
Desktop.getDesktop().open(file);
}
}
}
My guess is that the file is being created, but not in the directory that you expect. Check the value of the user.dir system property and see what it shows. This is the current working directory of your JVM.
You may need to either:
Specify a full path in the code (as Martin suggested), e.g. new File("/home/foo/newfile.txt")
Change the working directory of the JVM. The way that you do this depends on how you are launching it (e.g. if you are running the java command directly from a CLI, then just switch directories first, if you are running from an IDE then change the launch configuration, etc.).
As far as I know, you cannot change the working directory at runtime (see this SO question).
Your code is working for me with minor change.
As a debugging process, I would completely delete the directory path and try to use a file only..
instead of
File k1 = new File("documents/"+"newfile.txt");
use
File k1 = new File("newfile.txt");
Check where your file is generated and then create directory there..
Good luck!!