Passing FileWriter as a parameter to a method - java

I'm sure there is a fairly simple answer to this question, so here we go.
I'm trying to use a FileWriter to write text to a file. My program reads text in from an already existing file, specified by the user and then asks whether to print the text to the console or to a new file, also to be named by the user.
I believe my problem is with passing the FileWriter to the "FileOrConsole" method. Am I not passing or declaring the FileWriter in the "FileOrConsole" method correctly? The file is always created but nothing is written to it.
Here is the code:
import java.io.*;
import java.util.*;
public class Reader {
public static void main(String[] args) throws IOException {
Scanner s = null, input = new Scanner(System.in);
BufferedWriter out = null;
try {
System.out.println("Would you like to read from a file?");
String answer = input.nextLine();
while (answer.startsWith("y")) {
System.out.println("What file would you like to read from?");
String file = input.nextLine();
s = new Scanner(new BufferedReader(new FileReader(file)));
System.out
.println("Would you like to print file output to console or file?");
FileOrConsole(input.nextLine(), s, input, out);
System.out
.println("\nWould you like to read from the file again?");
answer = input.nextLine();
}
if (!answer.equalsIgnoreCase("yes")) {
System.out.println("Goodbye!");
}
} catch (IOException e) {
System.out.println("ERROR! File not found!");
// e.printStackTrace();
} finally {
if (s != null) {
s.close();
}
if (out != null) {
out.close();
}
}
}
public static void FileOrConsole(String response, Scanner s, Scanner input,
BufferedWriter out) {
if (response.equalsIgnoreCase("console")) {
while (s.hasNext()) {
System.out.println(s.nextLine());
}
} else if (response.equalsIgnoreCase("file")) {
System.out.println("Name of output file?");
response = input.nextLine();
try {
out = new BufferedWriter(new FileWriter(response));
} catch (IOException e) {
e.printStackTrace();
}
while (s.hasNext()) {
try {
out.write(s.nextLine());
out.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("Sorry, invalid response. File or console?");
response = input.nextLine();
FileOrConsole(response, s, input, out);
}
}
}

you make classic error forgetting that parameters passed by value in case of java it is a value of the reference. The thing is that your assignment
out = new BufferedWriter(new FileWriter(response));
actually does not change the variable declared in main() it stays null
BufferedWriter out = null;
and then in finally it skips the close() by the if(out==null)
and as it is Buffered and you do no flush nothing is written to file.
what you got to do is out.close(); in side the FileOrConsole method call
OR
do the out = new BufferedWriter(new FileWriter(response));
outside of it. You choose :-)

Try flushing your stream, but more importantly, remember to close it.
Here's a code example of recommended practice for handling streams. Same approach can be used for input streams too and things like database code where it's important to always clean up after yourself to get the expected results.
BufferedWriter out = null;
try {
out = // ... create your writer
// ... use your writer
} catch(IOException ex) {
// maybe there was a problem creating or using the writer
} finally {
if (null != out) {
out.flush();
out.close();
out = null;
}
}

Related

Is this simply a typo?

I've been reading the book Beginning Android Games and I came across this code and text:
public static void load(FileIO files) {
BufferedReader in = null;
try { in = new BufferedReader(new InputStreamReader(
files.readFile(".mrnom")));
soundEnabled = Boolean.parseBoolean( in .readLine());
for (int i = 0; i < 5; i++) {
highscores[i] = Integer.parseInt( in .readLine());
}
} catch (IOException e) {
// :( It's ok we have defaults
} catch (NumberFormatException e) {
// :/ It's ok, defaults save our day
} finally {
try {
if ( in != null)
in .close();
} catch (IOException e) {}
}
}
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".mrnom")));
out.write(Boolean.toString(soundEnabled));
for (int i = 0; i < 5; i++) {
out.write(Integer.toString(highscores[i]));
}
} catch (IOException e) {} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {}
}
}
Next up is a method called save(). It takes the current settings and serializes them to
the .mrnom file on the external storage (e.g., /sdcard/.mrnom). The sound setting and each
high-score entry is stored as a separate line in that file, as expected by the load()
method. If something goes wrong, we just ignore the failure and use the default values
defined earlier. In an AAA title, you might want to inform the user about this loading
error
I am very confused as it says it writes to a new line(in the save method) so that in the load method, which uses readLine() works properly. However, they are only using write() with no /n characters. How will this work? Is it simply a typo?
No, it's not a typo.
BufferedReader read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines. Then, it uses as delimiter the common System.lineSeparator() to split the text values.
Check the Javadoc by yourself.

Writing to files issue

So this may or may not be a dumb question but here we go!
So I'm trying to write to a file and it doesn't override but it writes over and over again so I need help.
Method:
#SuppressWarnings("resource")
public static void writeFile(File file, String index) {
try {
boolean wri = false;
PrintWriter out = new PrintWriter(new FileWriter(file, true));
Scanner scanner = new Scanner(file);
while(scanner.hasNext()) {
String str = scanner.nextLine();
if(str.equals(index)) {
System.out.println(index);
scanner.close();
wri = true;
break;
} else {
wri = false;
break;
}
}
if(wri != false)
return;
out.write(index);
out.write("\n");
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You code is full of errors.
Don't use hasNext() with nextLine(). Use hasNextLine() instead.
You don't close scanner if index is not found.
You don't close out if index is found.
You open file for writing, even if you don't need to write anything.
You ignore exceptions.
if(wri != false) is a very obscure way to write if (wri).
No need to wrap FileWriter in a PrintWriter if you're only using write() method.
Since you explicitly call FileWriter constructor in append mode, I'd assume you want to write index to file, if and only if file doesn't already contain that text.
Please be aware that your logic will not work if index contains line break characters.
Since you're only reading lines, you should use BufferedReader instead of Scanner, since Scanner has a very large overhead.
As for your lack of closing the resources, use try-with-resources.
Your code should be like this:
public static void writeFile(File file, String index) {
if (file.exists()) {
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
for (String line; (line = in.readLine()) != null; )
if (line.equals(index))
return;
} catch (Exception e) {
throw new RuntimeException("Error reading file: " + file, e);
}
}
try (FileWriter out = new FileWriter(file, true)) {
out.write(index);
out.write(System.lineSeparator());
} catch (Exception e) {
throw new RuntimeException("Error appending to file: " + file, e);
}
}
Test
File file = new File("C:/temp/test.txt");
writeFile(file, "Hello");
writeFile(file, "World");
writeFile(file, "Hello");
File Content
Hello
World
try with false
PrintWriter out = new PrintWriter(new FileWriter(file, false));

Trying to write to an output file using FileWriter

I'm currently trying to save the output of my code into a text file, when I run it on a different project it generates the output file and stores the output respectively, however when I run the same code in a different project it gives me blank output file and I do not really know what's the matter. I'm confused as to where to put the .close() function and the flush function as well. Thank you in advance!
FileWriter output = new FileWriter("set.txt");
BufferedWriter writer = new BufferedWriter(output);
InputStream fis_n = new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt");
InputStreamReader isr_n = new InputStreamReader(fis_n, Charset.forName("UTF-8"));
BufferedReader br_n = new BufferedReader(isr_n);
while ((input = br_n.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
}
writer.close();
output.close();
This is what the edited code looks like, yet still the output file "set.txt" is empty upon running the program.
FileWriter output = new FileWriter("set.txt");
BufferedWriter writer = new BufferedWriter(output);
InputStream fis_n = new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt");
InputStreamReader isr_n = new InputStreamReader(fis_n, Charset.forName("UTF-8"));
BufferedReader br_n = new BufferedReader(isr_n);
try {
while ((input = br_n.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
fis_n.close();
isr_n.close();
br_n.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// fis_n.close();
//isr_n.close();
//br_n.close();
}
This is what the final code looks like:
public static void dictionary(String sample_text, String text) throws FileNotFoundException, IOException {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt"),
Charset.forName("UTF-8")
));
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("/Users/User/NetBeansProjects/Test/src/test/set.txt"),
Charset.forName("UTF-8")
));
try {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
}
} finally {
writer.close();
}
} finally {
reader.close();
}
} catch (IOException e) {
// Error handling
}
}
This is the main method where the dictionary method is being called.
public static void main(String[] args) throws FileNotFoundException, IOException {
case 2: {
BufferedReader d_br = new BufferedReader(new InputStreamReader(
new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/input_file.txt"),
Charset.forName("UTF-8")
));
try {
String d_line;
while ((d_line = d_br.readLine()) != null) {
String h_input = test(d_line);
dictionary(d_line, h_input);
}
} catch(IOException e){
}finally {
d_br.close();
}
break;
}
}
You should put writer.close() after the while loop, and preferable, into the finally section.
If there is no requirement to store partially-processed files (as in most cases), you may remove flush at all. In the other case, it is better to leave it where it is.
The generic case of resource usage on Java 7+ looks like follows (this syntax is called try-with-resources:
try (
Resource resource1 = // Resource 1 initialization
Resource resource2 = // Resource 2 initialization
...
) {
// Resource utilization
} catch (XXXException e) {
// Something went wrong
}
Resource are freed (closed) automatically by try-with-resources.
If you need to use Java 6 or earlier, the above code could be roughly translated to the following (actually there are some subtle differences, that is not important at this level of details).
try {
Resource1 resource1 = // Resource initialization
try {
Resource2 resource2 = // Resource initialization
try {
// Resource utilization
} finally {
// Free resource2
resource2.close();
}
} finally {
// Free resource1
resource1.close();
}
} catch (XXXException e) {
// Something went wrong
}
Notice, how nested try-finally blocks used for resource management.
In your particular case we need to manage two resources: Reader and Writer, so the code will look as follows:
try (
// Notice, we build BufferedReader for the file in a single expression
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("sample.txt"),
StandardCharsets.UTF_8 // Better replacement for Charset.forName("UTF-8")
));
// Alternative way to do the same
// BufferedReader reader = Files.newBufferedReader(Paths.get("sample.txt"), StandardCharsets.UTF_8);
// Output charset for writer provided explicitly
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("set.txt"),
StandardCharsets.UTF_8
))
// Alternative way to do the same
// BufferedWriter writer = Files.newBufferedWriter(Paths.get("set.txt"), StandardCharsets.UTF_8)
) {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + text);
writer.newLine();
break;
}
}
} catch (IOException e) {
// Error handling
}
Or, using pre-Java7 syntax:
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("sample.txt"),
Charset.forName("UTF-8")
));
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("set.txt"),
Charset.forName("UTF-8")
));
try {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + text);
writer.newLine();
break;
}
}
} finally {
writer.close();
}
} finally {
reader.close();
}
} catch (IOException e) {
// Error handling
}
First of all, you call the flush method of a writer, whenever you want the current buffer to be written immediately. If you just write a file completely without any intermediate operation on your output, you do not need to call it explicitly, since the close call will do that for you.
Secondly, you only call the close method of the top-level reader or writer, in your case BufferedWriter. The close call is forwarded to the other assigned readers or writers. Multiple consecutive close calls do not have any effect on a previously closed instance, see here.
As a general note to using readers and writers, consider this pattern:
// This writer must be declared before 'try' to
// be visible in the finally block
AnyWriter writer = null;
try {
// Instantiate writer here, because it can already
// throw an IOException
writer = new AnyWriter();
// The the writing in a loop or as you wish
// If you need to write out the buffer in
// between, call flush
} catch (IOException e) {
// Something went wrong while writing
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
// Exception while trying to close
}
}
The finally block is ALWAYS executed. If you need a more compact syntax and you use at least Java 7, you can have a look at the try-with notation here.

java try catch block does not print the information that I want it to

I want the user to enter a filename on the command line. If they don't enter any, I should print information says file was not processed and exit out. Here is my try catch block
try{
parser.openFile(args[0]);
if(parser.getCounter() == 3)
{
System.out.println("File was processed: true");
}
else
{
System.out.println("File was processed: false. Missing information.");
}
//found = true;
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("File was processed: false. Re-enter filename.");
//fName = keyboard.nextLine();
}
The openFile method is in my class, and it is here, in case anyone needs it:
public void openFile (String filename)throws IOException{
fis = new FileInputStream(filename);
br = new BufferedReader(new InputStreamReader(fis));
String thisLine;
thisLine = br.readLine();
while(thisLine != null)
{
lines.add(thisLine);
thisLine = br.readLine();
}
}
Somehow "File was processed: false. Re-enter filename." does not printed out when there is not filename in the command line. Can anyone help me please?
Probably you're getting a different exception. Maybe
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Try to validate the content of args
Example:
public class TesteArgs {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Inform a valid name...");
System.exit(0);
}
// continue handling your args param
System.out.println(args[0]);
}
}
Change your IOException to Exception in your catch statement, that'll get 'em exceptions caught nicely for ya.
You can catch multiple exception in try{}catch{} block.
You have to catch specific exceptions (ArrayIndexOutOfBoundsException, which is child of Exception) first and generic exception (Exception) later.
Sample code:
try{
// Your code
File f = new File ("a.txt");
FileInputStream fio = new FileInputStream(f);
}catch(ArrayIndexOutOfBoundsException ae ){
System.out.println(ae);
}catch(IndexOutOfBoundsException ee ){
System.out.println(ee);
}catch(IOException ioe ){
System.out.println(ioe);
}catch(RuntimeException re ){
System.out.println(re);
}catch(Exception e ){
System.out.println(e);
}catch(Throwable t ){
System.out.println(t);
}
Have a look at hierarchy of exceptions

how to take input from keyboard in java till some words

I want to take input from keyboard in my java program until the user type abc
Here is the code which i have written but it doesn't work. the program continues to take input from keyboard even after i have typed abc and lastly I have to close the program by myself. It takes in input from keyboard and write it on a file named file1.txt
import java.io.*;
import java.util.*;
public class io {
public static void main(String args[]) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("file1.txt", true));
Scanner keyboard = new Scanner(System.in);
do {
writer.write(keyboard.next());
writer.newLine();
} while (keyboard.next() != "abc");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Try this , it works, Just use while loop instead of do while
Code:
import java.io.*;
import java.util.*;
public class io{
public static void main(String args[]) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("file2.txt", true));
Scanner keyboard = new Scanner(System.in);
while(!keyboard.next().equals("abc"))
{
writer.write(keyboard.next());
writer.newLine();
}
writer.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("file1.txt", true));
Scanner keyboard = new Scanner(System.in);
writer.keyboard.nextLine(); // if need write 1st string alltime
while (keyboard.hasNext()){
String buffer = keyboard.nextLine();
if (!"abc".equals(buffer)) // !!! using equals on object not null ("abc" - is not null)
{
// do if entered "abc", use break for ending while
}
// do if entered others, use variable name buffer
}
} catch (IOException e) {
e.printStackTrace();
}
As #JonSkeet said - you're calling keyboard.next() twice instead of storing the result in a local variable like you should. Secondly you're comparing strings with the != operator, but this only checks whether you are pointing to the exact same String object. There may be thousands of String objects in memory with the string "abc" in them, and none of them would be equal to each other using ==.
Instead, you need to call the method equals.
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("file1.txt", true));
Scanner keyboard = new Scanner(System.in);
String next;
do {
next = keyboard.next();
writer.write(next);
writer.newLine();
} while (!next.equals("abc"));
writer.close();
} catch (IOException e) {
e.printStackTrace();
}

Categories