I have made a program that is supposed to create a file, write to it, and then read from it. The problem comes with readFile(), where suddenly hasNext() is undefined for Formatter? I thought that
while (file.hasNext()) {
String a = file.next();
System.out.println(a);
would go as long as there was something in the file, copy it to a and then print a? What am I doing wrong?
import java.util.*;
import java.io.*;
class Oppgave3
{
public static void main(String[] args)
{
Kryptosystem a = new Kryptosystem();
a.createFile();
a.writeFile();
a.openFile();
a.readFile();
a.closeFile();
}
}
class Kryptosystem
{
public Kryptosystem(){}
Scanner keyboard = new Scanner (System.in);
private Formatter file;
private Scanner x;
public void createFile(){
try {
file = new Formatter("kryptFil.txt");
}
catch (Exception e) {
System.out.println("could not create file");
}
}
public void writeFile(){
System.out.println("what do you want to write");
String tekst = keyboard.nextLine();
file.format(tekst);
}
public void openFile() {
try {
x = new Scanner (new File("kryptFil.txt"));
}
catch (Exception e) {
System.out.println("something is wrong with the file");
}
}
public void readFile() {
while (file.hasNext()) {
String a = x.next();
System.out.println(a);
}
}
public void closeFile() {
file.close();
}
}
You state:
where suddenly hasNext() is undefined for Formatter?
Please have a look at the Formatter API as it will show you that this class has no hasNext() method, and your Java compiler is correctly telling you the same thing. Similarly, the Scanner API will show you that it in fact has the method you need.
You're opening the same File in a Scanner, called x, and this is what you want to use to read from the file. So the solution is to call hasNext() on the Scanner variable:
while (x.hasNext()) { // x, not file
String a = x.next();
System.out.println(a);
}
Note I'm not sure why you opened the file a second time and placed it into a Formatter object. Please clarify your motivation for this. I believe that you wish to write to the file with this, but you certainly would not try to use it to read from the File, which is what you're use of hasNext() is trying to do. I think you were just a little confused on which tool to use is all.
Related
I am trying to print out a message based on whether or not a previous specific message was printed. Here is my code:
public class Main {
public static Runnable getRunnable() {
return () -> {
System.out.println("Hello from a thread");
};
}
public static void main(String[] args){
new Thread(getRunnable()).start();
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
if (name.equals("Hello from a thread")) {
System.out.println("Hi!");
} else {
System.out.println("That's not nice");
}
}
}
I know that Scanner is probably no the solution here, but whenever I try something else like System.console.readLine(), which is probably also not correct, it prints out a NullPointerException. What am I supposed to use here to read previous output?
UPDATE: Hey, I tried it again but it didn't work out... not sure why again. Here's my updated code
public static ByteArrayOutputStream baos = new ByteArrayOutputStream();
public static PrintStream ps = new PrintStream(baos);
public static PrintStream old = System.out;
public static Runnable getRunnable() {
System.out.println("Hello from a thread");
return () -> {
System.setOut(ps);
System.out.println("Hello from a thread");
};
}
public static void main(String[] args){
new Thread(getRunnable()).start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
System.out.println("Somethings wrong!");
}
System.out.flush();
System.setOut(old);
if (baos.toString().equals("Hello from a thread")) {
System.out.println("Hello other thread!");
}
}
}
System.out is not System.in
System.out is the standard output stream, which usually prints to console. System.in is the standard input stream, which usually is taken from console. You can do setOut, setIn, and setErr to change the I/O streams, so for your case, you would need to redirect in to read from a source and out to output to that source. You may consider using an ArrayList to store and retrieve the output / input:
final List<Integer> list = new ArrayList<>();
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
list.add(b);
}
}));
System.setIn(new InputStream() {
public int read() {
if (list.size() == 0) return -1;
return list.remove(0);
}
});
(Note that for various reasons, you probably want to do setErr so you can still output things properly.)
You can try a working example of this here
I am trying to run this simple program that reads from a separate text file and prints out each line. However, when I try to compile it, it keeps giving me the same error:
story.java:11: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
x = new Scanner(new File("names.txt"));
Here is my code:
import java.io.*;
import java.util.*;
public class story {
private static Scanner x;
public static void main(String[] args) {
String story = "";
x = new Scanner(new File("names.txt"));
while(x.hasNext()){
story = story + x;
}
System.out.println(story);
}
}
This message is telling you that your main() method is doing some stuff that may throw FileNotFoundException but you are neither catching this exception, nor declaring that such an exception may be thrown by the main() function.
To correct it, declare your main() method as follows:
public static void main(String[] args) throws FileNotFoundException {
Change it to
public static void main(String[] args) throws Exception {
String story = "";
x = new Scanner(new File("names.txt"));
while(x.hasNext()){
story = story + x;
}
System.out.println(story);
}
OR
Put try catch in your code
public static void main(String[] args) {
String story = "";
try {
x = new Scanner(new File("names.txt"));
while(x.hasNext()){
story = story + x;
}
System.out.println(story);
}
catch(Exception e) {
// handle
}
}
When programming there is the normal flow of logic that solves your problem, and a second flow of logic that handled "Exceptional" unexpected situations. Java uses the type Exception and the keyword throw to have bits of code present exceptional error states.
Your program, when being complied, is being checked for its ability to handle exceptional return values. Since you didn't handle the exceptional return value, it is not going to be compiled.
Below is your code, handling this Exception. Pay close attention to the try and catch block structure, as it is how one writes code that can handle an Exception being raised. However, don't be constrained by how I handled the exception for you, because the details of how to handle the exception are dependent on what you would prefer to do.
import java.io.*;
import java.util.*;
public class story {
private static Scanner x;
public static void main(String[] args) {
String story = "";
try {
x = new Scanner(new File("names.txt"));
} catch (FileNotFoundException error) {
System.out.println("the program failed because \"names.txt\" was not found.");
return -1;
}
while(x.hasNext()){
story = story + x;
}
System.out.println(story);
}
}
There is another approach to handling exceptions that sometimes is appropriate, which is to "not handle" the exception. When doing so, change the method from whatever the method was to whatever the method was throws Exception. For example public static void main(String[] args) to public static void main (String[] args) throws Exception.
While this handles the compiler's complaint it should be used sparingly because exceptions that bubble up through the nested method calls past the main method will crash the program, typically without easily readable output that might make the error easier for a human to fix.
Whenever working with a file object, you must handle the chance of a FileNotFoundException, which occurs when the file you specify does not exist.
to fix this, simply say throws Exception in you main header, or use a try/catch block.
public static void main(String[] args) throws Exception {
or
public static void main(String[] args) {
String story = "";
try
{
x = new Scanner(new File("names.txt"));
while(x.hasNext()){
story = story + x;
}
System.out.println(story);
}
catch(Exception e)
{
System.out.println("Error: File not found!");
}
}
1) You need to put them in the try catch block.
2) specify the path of "names.txt".
3) My code looks like:
String story = "";
try {
x = new Scanner(new File("/Users/Workspace/names.txt"));
while(x.hasNext()){
System.out.println(story = story+x.next());
}
System.out.println(story);
} catch (FileNotFoundException e){
e.printStackTrace();
}
}
I want to write program that stores information about cars. You input for instance brand and owner name for each car in dialog boxes. In the end, a dialog box with information about all cars should be shown by writing the information to a text file and then reading from it to the dialog box. I create a method getInfo which shows the appropriate boxes correctly.
public static void getInfo() {
boolean done = false;
do {
String brand=JOptionPane.showInputDialog(null, "Brand?");
String name=JOptionPane.showInputDialog(null, "Owner?");
if (brand == null) {
done = true;
} else {
String info ="Car: "+brand+" "+"\nOwner: "+name;
String message = " Do you want to input more cars?";
int buttonClicked = JOptionPane.showConfirmDialog(null, message, "", JOptionPane.YES_NO_OPTION);
done = (buttonClicked == JOptionPane.NO_OPTION);
}
} while (!done);
}
public static void main(String[] args) {
getInfo();
}
I am not sure how to add the information to a text file and how to deal with the loops. To write the information to a text file I tried to change the main method to the following
public static void main(String[] args) throws IOException {
try (PrintWriter outstream = new PrintWriter
(new BufferedWriter
(new FileWriter("cars.txt", true)))) {
getInfo();
outstream.println(info);
}
}
What am I missing and how can I implement the functionality?
You can define a BufferedWriter outside of the loop:
File outputFile = new File("path/to/the/file.txt");
if(!outputFile.exists()){
try {
outputFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedWriter bw = null; //this declares a buffer that writes to some stream.
try{
bw = new BufferedWriter(new FileWriter(outputFile,true)); //here we actually create it, and tell it to write to a file stream, directed at the outputFile file.
}catch(IOException e){
e.printStackTrace(); //this is if the file doesn't exist, which shouldn't happen, but we still need to put this here, because better safe than sorry.
}
And then in your loop: after the
String info ="Car: "+brand+" "+"\nOwner: "+name;
do:
String info ="Car: "+brand+" "+"\nOwner: "+name;
try {
bw.write(info);//write the information to the buffer when there's new info.
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
and after exiting the loop, call:
bw.close();
First of all, with every loop you are creating a new instance of info, so you will lose the information from the previous runs.
In your main method you are accessing info, but it should not be known in that scope. What you could do, is to return info from the getInfo() method.
You should then also think about line breaks and so on, but for a first try this should be it.
Try the following:
public static void main() {
boolean done = false;
do {
Info info = getInfo();
storeInfo(info);
done = getDone();
} while (!done);
displayInfo();
}
class Info {
private brand;
private owner;
}
Now you can do single things in each method.
getInfo calls showInputDialog and returns an Info object.
storeInfo stores the Info object to a text file.
getDone calls showInputDialog and returns, if the user wants to quit.
displayInfo opens the text file and shows the info.
The easiest way to implement displayInfo migth be:
void displayInfo() {
// Create a window with TextBox
// Open the text file
// Read the content of the text file and add it to the TextBox
}
I'm having trouble with some java code. The program consists of about 7 files, but I will try to keep it short.
I'm trying to load an ArrayList from a file into a variable, with ObjectStream. It gave me a warning, because all the compiler could see, was that I said an Object should be casted to ArrayList. of course the compiler won't know what kind of object there is in the file. As the coder I know that the file can only consist of one ArrayList and nothing else. So I searched the web, and found out to supress the warning, nut now it give me the error:
Schedule.java:34: error: <identifier> expected
To give you a picture of what's happening, here is the code the error happens in. This error shouldn't be affected by any of the other classes
import java.util.*;
import java.io.*;
public class Schedule
{
private static ArrayList<Appointment> schedule;
private static File file;
private static ObjectInputStream objIn;
private static boolean exit;
private static Scanner in = new Scanner(System.in);
public static void main(String[] args)
{
initializeSchedule();
System.out.println("Welcome!");
while(!exit){
System.out.print("write command: ");
Menu.next(in.next());
}
}
public static void initializeSchedule()
{
try{
file = new File("Schedule.ca");
if(!file.exists()){
schedule = new ArrayList<Appointment>();
}
else{
objIn = new ObjectInputStream(new FileInputStream("Schedule.ca"));
#SuppressWarnings("unchecked")
schedule = (ArrayList<Appointment>)objIn.readObject();
objIn.close();
}
} catch (IOException e){
System.out.println("Exception thrown :" + e);
} catch (ClassNotFoundException e){
System.out.println("Exception thrown :" + e);
}
}
public static void exit()
{
exit = true;
}
public static ArrayList<Appointment> getSchedule()
{
return schedule;
}
}
the error is in initializeSchedule, right under the supression, where schedule is set to the ObjectStream input.
The correct locations for #SuppressWarnings("unchecked") are
TYPE, FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE
So the compiler cannot parse #SuppressWarnings at this point, but considers it a statement. If you move it above the method declaration or above the declaration of schedule, it should be fine.
A better way to fix that is to actually correct the issue that the compiler is complaining about like this:
final Object input = objIn.readObject();
if (input instanceof ArrayList) {
schedule = (ArrayList<Appointment>) input;
} else {
throw new IllegalStateException(); // or whatever suits you
}
You can't annotate an assignment. Move the
#SuppressWarnings("unchecked")
to the line before the method starts.
I'm trying to monitor the file content and adding any new line to JTextArea. I created thread, which monitor the file, but when the Scanner object reachs the end of file it stop working. I tried very simple method, which create new Scanner object and read the file from the begin, but it isn't good solution.
It's the version which stop and do nothing :
public class TextAreaThread implements Runnable {
JTextArea text = null;
File file = null;
Scanner read = null;
public TextAreaThread(JTextArea text, File file) {
this.text = text;
this.file = file;
try{
read = new Scanner(file);
}catch(FileNotFoundException e){
JOptionPane.showMessageDialog(null,"Wrong file or file doesn't exist","Error",JOptionPane.ERROR_MESSAGE);
}
}
public void run() {
while(true){
while(read.hasNext())
text.append(read.nextLine()+"\n");
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The wait method is not what you want here. Try Thread.sleep instead.