I'm tinkering around on a small application to read some numbers in from a file. Everything runs well so far, but now I have encountered a problem I don't know how I can effectively fix it. If the user enters, unintentionally maybe, the wrong filename a FileNotFoundException will be thrown by the JVM, that I catch in my invoking method. Now I want to give him (the user) two another tries to enter the correct filename, but I don't know how I can invoke the method again which is opening the file when I'm actually in the catch-block below.
I will illustrate my transient solution below, but I'm not really sure if this is the most effective/elegant way to solve this problem:
//code omitted
int temp = 0;
while(true) {
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
if(temp++ == 3) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
continue;
}
break;
}
//do some other stuff
input is a scanner which reads the user input and assigns it to the String-variable filename. fileOpen is a method which takes a filename, opens the file, reads the content and write all numbers in a vector.
So, I would really appreciate every support from the more experienced java programmers.
Greetings
Tom
You could use something like this,
public class AppMain {
public static void main(String[] args) throws IOException {
String filePath = input.next();
InputStream is = getInputStream(filePath);
int temp = 0;
while(is == null && temp < 3){
filePath = input.next();
is = getInputStream(filePath);
temp++;
}
if(is == null){
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
.........
.........
}
private static InputStream getInputStream(String filePath){
InputStream is = null;
try{
is = new FileInputStream(filePath);
return is;
}catch (IOException ioException) {
return null;
}
}
}
You may want to recursively call the method again:
public void doTheStuff(int attemptsLeft)
// ...
if (attemptsLeft == 0) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
doTheStuff(attemptsLeft - 1);
return;
}
// ...
}
then simply call doTheStuff(3)
You can use exists method of the File class
For example fileOpen method can return true/false whether file exists
Think this will work.
int x = 0;
while (true){
filename = input.next();
try{
ex.fileOpen(filename);
break; // If it throws an exeption, will miss the break
}catch(FileNotFoundException e){
System.err.println("File not found, try again.");
}
if (x==2){
System.errprintln("You have entered the wrong file 3 times");
System.exit(0);
}
x++
}
Do not use exceptions to control your WorkFlow. Try something like this:
final int MAX_ERROR_ALLOWED=3;
public void readFile(String filename, int errorCount){
try{
File f = new File(filename);
if(!f.exists()){
String newFilename = input.next();
if(errorCount>=MAX_ERROR_ALLOWED){
throw new JustMyException();
}
readFile(newFilename, errorCount++);
}else{
//whatever you need to do with your file
}
}
}
How about something like this (pseudocode, not executable)?
// ...
for(int i = 0; i < 3; i++)
{
// User interaction to get the filename
if(attemptToOpenFile(ex))
{
break;
}
}
// Check if the file is open here and handle appropriately.
// ...
}
bool attemptToOpenFile(File ex, String filename) { // Forgot the class name for this
try {
ex.fileOpen(filename);
return true;
} catch(FileNotFoundException e) {
return false;
}
}
Alternatively, check if the file exists before calling fileOpen().
Related
I am trying to read integers from a text file but I failed.
(It fails to read even the first integer)
public void readFromFile(String filename) {
File file = new File(filename);
try {
Scanner scanner = new Scanner(file);
if (scanner.hasNextInt()) {
int x = scanner.nextInt();
}
scanner.close();
} catch (FileNotFoundException e) {
System.out.println("File to load game was not found");
}
}
The error I get is: NoSuchElementException.
The file looks like this:
N,X1,Y1,X2,Y2,X3,Y3
While n equals 3 in this example.
I call this method a in the main method like this:
readFromFile("file.txt");
I am not sure whether you would like to display only the integers after separating them from the string. If that is the case, I would suggest you to use BufferedInputStream.
try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))){
String input = br.readLine();
int count = 0;
for(int i = 0; i < input.length()- 1; i++){
if(isNumeric(input.charAt(i))){
// replace the Sysout with your own logic
System.out.println(input.charAt(i));
}
}
} catch (IOException ex){
ex.printStackTrace();
}
where isNumeric can be defined as follows:
private static boolean isNumeric(char val) {
return (val >= 48 && val <=57);
}
Scanneruses whitespace as the default delimiter. You can change that with useDelimiter See here: https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
I'm writing an application that is supposed to act like a cafe clip card. In other words, for every n:th (10 in my case) coffee that a customer purchases, he/she is awarded a free beverage. So, I'm quite done with the loop and I've been working on writing and reading from a file since I need the program to remember where it last left off in order for the customer to be able to close the application once he/she has been in the store. However, I'm having a difficult time figuring out how to write and read from a file, the code I have doesn't seem to output any .txt file. I need the code to have a closing condition, and upon entering this condition, it should write the "count" to a .txt file, and shut down. Once the program is being run the next time it should read from this .txt file so it knows where the count is at.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("countStorage.txt"))));
bw.write(count);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(newInputStreamReader(newFileInputStream(new File("countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
I see a few problems here. In your readFromFile() method, put a space after the keyword new. I also suggest putting a an absolute path for now (for debugging):
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
In your saveToFile() method, the constructor is wrong. Also put the full path to the file here:
bw = new BufferedWriter(new FileWriter("C:\\Temp\\countStorage.txt"));
Finally, in your saveToFile() method, write the count as a String. Writing it as an int refers to the Unicode character:
bw.write(Integer.toString(count)); //updated per Hunter McMillen
And invoke it...
FelixNeww f = new FelixNeww();
f.saveToFile(44);
System.out.println(f.readFromFile());
You need to invoke readFromFile or saveToFile in the place needed in order to become executed.
I suggest that you call readFromFile on the beginning of the Main method, use its returning contents, and saveToFile in the loop whenever the desired state changes and it needs to be saved.
Whenever I run this method, it produces an error saying that there is no line. The file (inv.txt) is a 1 on 25 lines, So 25 ones, each on a seperate line.
public class Inventory
{
File inventory = new File("Resources/inv.txt");
File db = new File("Resources/db.txt");
FileWriter write;
StringBuilder writethis;
public void addItem(int item, int slot)
{
int i = 1;
writethis = new StringBuilder();
Scanner scan;
try
{
scan = new Scanner(inventory);
if (scan.hasNextLine())
{
while (i < slot)
writethis.append(scan.nextLine()); // This is where it says the
// error is. For reference,
// slot is 2. It may somehow
// be making an infinite loop,
// but I don't know why it
// would.
scan.nextLine();
writethis.append(item);
while (i < 24)
writethis.append(scan.nextLine());
System.out.println(writethis.toString());
scan.close();
}
try
{
write = new FileWriter(inventory);
write.write(writethis.toString());
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}
Could this be due to the fact that the instance variable i is never incremented?
I would also close the data streams in a finally block.
I have an assignment where I need to write a while loop code block that contains a trycatch statement. The try block retrieves each line from an input file, and invokes an isValid method I created to check if the format is correct, passing to it the line from the file. If there are no more lines to parse, runProgram is set to false, the while loop terminates. The catch block will catch an exception that I made. So far I have
public static void main(String[] args)
{
File file;
Scanner inputFile;
String fileName;
Scanner scan = new Scanner(file);
fileName = scan.nextLine();
boolean runProgram = true;
while(runProgram)
{
try
{
// for loop to check each line of my file
// invoke isValid
// Check if it's the last line in the file, and end program if so
}
catch(BankAccountException e)
{
System.out.println("Account Exception. Do you wish to quit? y/n");
String quit = scan.nextLine();
if(quit.equals("y"))
runProgram = false;
else
runProgram = true;
}
}
}
I just have no idea how to open a file, check the next line, use my isValid method (which is just a StringTokenizer that checks for the correct format), and closes when it reaches the end of the file.
Here is my isValid method:
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
if(strTok.countTokens() == 2)
{
if(strTok.nextToken().length() == 10)
{
if(!strTok.nextToken().matches(".*[0-9].*"))
{
valid = true;
}
}
}
else
valid = false;
return valid;
}
I also have a question with the above method. If I call .nextToken() twice, am I right in expecting the first iteration to deal with the first token, and the second to deal with the second? Or will they both just check the first token?
Just to get you started.
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("/path/to/File")));
String currLine;
while ((currLine = reader.readLine()) != null) { // returns null at EOF
if (!isValid(currLine)) throw new BankAccountException();
}
} catch (BankAccountException e) {
// same
} finally {
reader.close();
}
So I have been working on a java project where the goal is to create a virtual computer. So I am basically done but with one problem. I have created a compiler which translates a txt document with assembly code in it and my compiler has created a new-file with this code written as machine executable ints. But now I need to write a load method that reads these ints and runs the program but I am having difficulty doing this. Any help is much appreciated....also this is not homework if you are thinking this. The project was simply to make a compiler and now I am trying to complete it for my own interest. Thanks.
Here is what I have so far for load:
public void load(String newfile) throws FileNotFoundException
{
try{
File file = new File(newfile);
FileInputStream fs = new FileInputStream(file);
DataInputStream dos = new DataInputStream(fs);
dos.readInt();
dos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Ok here is the part of the Compiler that does the writeInts:
public void SecondPass(SymbolList symbolTable, String filename){
try {
int dc = 99;
//Open file for reading
File file = new File(filename);
Scanner scan = new Scanner(file);
//Make filename of new executable file
String newfile = makeFilename(filename);
//Open Output Stream for writing new file.
FileOutputStream fs = new FileOutputStream(newfile);
DataOutputStream dos = new DataOutputStream(fs);
//Read First line. Split line by Spaces into linearray.
String line = scan.nextLine();
String[] linearray = line.split(" ");
while(line!=null){
if(!linearray[0].equals("REM")){
int inst = 0, opcode, loc;
if(isInstruction(linearray[0])){
opcode = getOpcode(linearray[0]);
loc = symbolTable.searchName(linearray[1]).getMemloc();
inst = (opcode*100)+loc;
} else if(!isInstruction(linearray[0])){
if(isInstruction(linearray[1])){
opcode = getOpcode(linearray[1]);
if(linearray[1].equals("STOP"))
inst=0000;
else {
loc = symbolTable.searchName(linearray[2]).getMemloc();
inst = (opcode*100)+loc;
}
}
if(linearray[1].equals("DC"))
dc--;
}
dos.writeInt(inst);
System.out.println(" inst is being written as:" + inst);
}
try{
line = scan.nextLine();
}
catch(NoSuchElementException e){
line = null;
break;
}
linearray = line.split(" ");
}
scan.close();
for(int i=lc; i<=dc; i++){
dos.writeInt(0);
}
for(int i = dc+1; i < 100; i++)
{
dos.writeInt(symbolTable.searchLocation(i).getValue());
}
dos.close();
fs.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So what I have done is write a file in txt like:
IN X
In Y
SUB X
STO Y
OUT Y
DC: X 0
DC: Y 0
And I wrote a compiler that has now converted this file into machine code so I have created a file for example called program.txt.ex and it contains a bunch of ####### or machine code and I did this using the SecondPass code above and now I need to write a load method that will allow me to load and run this file.
Here is my Run method
public void run(String filename) throws IOException
{
if (mem == null)
System.out.println("mem null");
if (filename == null)
System.out.println("filename null");
mem.loadFromFile(filename);
cpu.reset();
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.fetch2();
while (!cpu.stop())
{
cpu.decode();
if (cpu.OutFlag())
OutPut.display(mem.read(cpu.getMAR()));
if (cpu.InFlag())
mem.write(cpu.getMDR(),in.getInt());
if (cpu.StoreFlag())
{
mem.write(cpu.getMAR(),in.getInt());
cpu.getMDR();
}
else
{
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.execute();
cpu.fetch();
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.fetch2();
}
}
}
The Run Method:
public void run(int mem)
{
cpu.reset();
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.fetch2();
while (!cpu.stop())
{
cpu.decode();
if (cpu.OutFlag())
OutPut.display(mem.read(cpu.getMAR()));
if (cpu.InFlag())
mem.write(cpu.getMDR(),in.getInt());
if (cpu.StoreFlag())
{
mem.write(cpu.getMAR(),in.getInt());
cpu.getMDR();
}
else
{
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.execute();
cpu.fetch();
cpu.setMDR(mem.read(cpu.getMAR()));
cpu.fetch2();
}
}
}
I notice that your loader does a single
dos.readInt();
...which will read a single integer value from your file. What you probably want to do is create a loop that reads ints until you hit the end-of-file on dos (which might more aptly be named dis, no?). You could add those ints to a dynamic container like an ArrayList, which will grow with every element you stuff into it. Once done loading, you can use toArray to copy all those ints to an array of the appropriate size.
If seems that you need to load the whole file in memory before starting execution, so it would go:
public int[] load(String newfile) throws FileNotFoundException
{
int mem[] = new int[100];
try {
File file = new File(newfile);
FileInputStream fs = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fs);
for (int i = 0; i < mem.length; ++i) {
mem[i] = dis.readInt();
}
dos.readInt();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
return mem;
}
void run(int mem[]) {
// now execute code
int pc = 0;
loop: while (true) {
int inst = mem[pc++];
int opcode = inst/100;
int loc = inst%100;
switch (opcode) {
case OpCode.STOP:
break loop;
case OpCode.IN:
...
}
}
}