简体   繁体   中英

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM