The proper uses of a print writer and file writer - java

why should we use file writer and then wrap it with a print writer when we can directly use a print writer? and we use buffered readers so they can read large chunks of data at once but then to get the output printed we have to loop them into a while loop why don't we have a simpler way to get the output printed?

Let's first have a look at the javadoc for the main differences.
FileWriter
Convenience class for writing character files. The constructors of this class assume that the default character encoding ... FileWriter is meant for writing streams of characters.
PrintWriter
Prints formatted representations of objects to a text-output stream.
Which means FileWriter focuses on character-wise output and you cannot define the character encoding. Whereas PrintWriter focuses on formatted text output and you can specify the character encoding.
Find a small example as demonstraction
// we need this as there is no convenient method to output a platform
// specific line separator charcater(s)
String newLine = System.getProperty("line.separator");
try (FileWriter fw = new FileWriter("/tmp/fw.txt")) {
fw.append('\u2126').append(newLine);
fw.write(65);
fw.append(newLine);
fw.append(String.format("%10s: %s%n", "some", "value"));
fw.append("some line").append(newLine);
} catch (IOException ex) {
System.err.println("something failed: " + ex.getMessage());
}
// the println() methods will append the right platform specific line separator
// charcater(s)
try (PrintWriter pw = new PrintWriter("/tmp/pw.txt", "UTF8")) {
pw.append('\u2126');
pw.println();
pw.write(65);
pw.println();
pw.printf("%10s: %s%n", "some", "value");
pw.println("some line");
} catch (FileNotFoundException | UnsupportedEncodingException ex) {
System.err.println(ex.getMessage());
}
If you run the snippet on a unicode aware machine (or run the code as java -Dfile.encoding=UTF-8 ...) the output will be
fw.txt
Ω
A
some: value
some line
pw.txt
Ω
A
some: value
some line
For the above examples the code and the result look more or less the same. PrintWriter provide methods for formatted output, whereas for FileWriter you have to do the formatting before the output.
But the big difference comes, when your environment is not unicode aware (or run the code as java -Dfile.encoding=ISO-8859-1 ...)
fw.txt
?
A
some: value
some line
The unicode omega character cannot be printed with ISO8859-1 encoding.
With the PrintWriter we defined the character encoding for the output. Which is independent from the default encoding of the environment.
pw.txt
Ω
A
some: value
some line
Back to your question. Wrapping a FileWriter into a PrintWriter. It is possible. But you loose the main benefit, the ability to choose the chracter encoding.
try (PrintWriter pw = new PrintWriter(new FileWriter("/tmp/pwfw.txt"))) {
pw.append('\u2126');
pw.println();
} catch (IOException ex) {
System.err.println("something failed: " + ex.getMessage());
}
The file pwfw.txt will contain the unicode character omega only if the default encoding of the environment is unicode. So you would have the same limitation (for the encoding) like with FileWriter.
If you have to use FileWriter or PrintWriter depends on your needs. I believe PrintWriter should to do it most of the time.

Related

Writing a javafx textarea to a textfile with linebreaks

So i'm currently trying to save the contents of a javafx textarea to a text file using the formatter class. The problem is that the text just gets saved in one line, without any line breaks.
This is the code i'm using for the Writing to the textFile
File file = new File(link);
Formatter formatter = null;
try {
formatter = new Formatter(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
formatter.format(textArea.getText() + "\n");
EDIT:
I found the problem: It is the fault of Windows Notepad. When i open the txt file in a other texteditor like notepadd++, it works just fine
do you really need to use the Formatter class? I suppose this class produces line separators (only) for the %n placeholder (but appears to be ignoring newline characters) in the contents of the format parameter (see also the corresponding javadoc):
format(String format, Object... args)
// Writes a formatted string to this object's destination using the specified format string and arguments.
One solution might be to specify the format string as "%s%n" (indicating that you want to format a String, followed by a line break) and pass the TextArea's contents, e.g. formatter.format("%s%n", textArea.getText()), if you really need to use the formatter.
Otherwise, you may just as well directly output the contents of the textArea to the file via some Writer:
FileWriter w = new FileWriter(file);
w.write(textArea.getText());
w.close();
you have to close the formatter
formatter.close();
The Formatter output is buffered in memory first. SO you have to close your formatter once you are done.
use finally block for this
try {
//code
} catch{
//code
}
finally {
formatter.close();
}
In my project I write the contents of a TextArea as follows:
byte[] contents = area.getText().getBytes(StandardCharsets.UTF_8);
Files.createDirectories(path.getParent());
Files.write(path, contents, StandardOpenOption.CREATE);
Which saves the contents as a UTF-8 encoded text file. This includes \n. Given that I'm working on Linux, I did not check if it actually is \n\r or not, my guts tell me it is only \n.

Write different lines to file

I have this method that writes to a file every time it's called:
public void writeToFile(String ins) {
FileWriter fw = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(ins);
bw.newLine();
bw.close();
fw.close();
}
But it only writes on the very first line of the file.
So, if I called it once with "Hello" and then again with "World", the file would contain "World", but the result I'm looking for is:
Hello
World
I tried using BufferedWriter.newLine() before and after writing the string but the result is the same?
You have to use FileWriter(String fileName, boolean append)
FileWriter fw = new FileWriter(f, true);
read the documentation of FileWriter:
FileWriter(File file, boolean append)
Constructs a FileWriter object given a file name with a boolean indicating whether or not to append the data written.
and you see, that you need to set the append value to true:
FileWriter fw = new FileWriter(f, true);
The point is: your code does what it is supposed to do - it uses a FileWriter, which by default will create a new, empty file; it writes one string; and closes the FileWriter.
If you want to write more than one line; you either have to
use the FileWriter in APPEND mode when doing later writes (by using that second, boolean argument for the FileWriter constructor with true)
change your method to take a list of strings, and write all of them at once
you can use a escape character:
\b Insert a backspace in the text at this point.
\n Insert a newline in the text at this point.
\r Insert a carriage return in the text at this point.
I recommend you to use resource try to allow java to close the file when it will necessary
public void writeToFile(String ins) {
String fileName= "file.txt";
try (FileWriter fileWritter = new FileWriter(fileName, true)) {
fileWritter.write(ins + "\r\n");
} catch (IOException ex) {
}
}
give to this method a empty string "" to insert in the file a "Enter"

Java FileWriter outputs a question mark

I have been unable to find the reason for this. The only problem I am having in this code is that when the FileWriter tries to put the new value into the text file, it instead puts a ?. I have no clue why, or even what it means. Here is the code:
if (secMessage[1].equalsIgnoreCase("add")) {
if (secMessage.length==2) {
try {
String deaths = readFile("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt", Charset.defaultCharset());
FileWriter write = new FileWriter("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt");
int comb = Integer.parseInt(deaths) + 1;
write.write(comb);
write.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And here is the readFile method:
static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Also, the secMessage array is an array of strings containing the words of an IRC message split into individual words, that way the program can react to the commands on a word-by-word basis.
You're calling Writer.write(int). That writes a single UTF-16 code point to the file, taking just the bottom 16 bits. If your platform default encoding isn't able to represent the code point you're trying to write, it will write '?' as a replacement character.
I suspect you actually want to write out a text representation of the number, in which case you should use:
write.write(String.valueOf(comb));
In other words, turn the value into a string and then write it out. So if comb is 123, you'll get three characters ('1', '2', '3') written to the file.
Personally I'd avoid FileWriter though - I prefer using OutputStreamWriter wrapping FileOutputStream so you can control the encoding. Or in Java 7, you can use Files.newBufferedWriter to do it more simply.
write.write(new Integer(comb).toString());
You can convert the int into a string. Otherwise you will need the int to be a character. That will only work for a small subset of numbers, 0-9, so it is not recommended.

Strange behavior in writing to file

I was trying some basic Java I/O operations, I try to run the below code :
public static void main(String[] args) {
File file = new File("fileWrite2.txt"); // create a File object
try {
FileWriter fr = new FileWriter(file);
PrintWriter pw = new PrintWriter(file); // create a PrintWriter that will send its output to a Writer
BufferedWriter br = new BufferedWriter(fr);
br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();
pw.println("howdy"); // write the data
pw.println("folks");
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
When I run the above I get the following output in the file created :
howdy
folks
f
Can anyone explain why the 'f' is coming in the last line ?
The f comes from the left over string of br.append("fffff"); which was written in the file by the BufferedWriter.
Since both BufferedWriter and PrintWriter write to the same file, the contents written by the PrintWriter overwrite the contents written by the BufferedWriter.
But seems the no. of bytes written by PrintWriter fall short by 1 to completely overwrite the data written by BufferedWriter and thus you get the f.
If you change this br.append("fffff"); to br.append("ffffg");, you can see that the g is now left over. Alternatively, changing pw.println("folks"); to pw.println("folks1"); will show that the previously written data is now completely overwritten by the PrintWriter.
All this confusion is because of having 2 different writers for the same file object which is the cause of the problem. As #Boris pointed out, have just 1 writer for a file object.
Note: Another interesting thing to test out would be to move the second br.flush(); after the pw.flush();.
// br.flush(); // moved from here
pw.println("howdy"); // write the data
pw.println("folks");
pw.flush();
br.flush(); // to here
You are writing 15 characters on the bufferedwriter by doing this
`
br.write("sdsadasdsa");
br.flush();
br.append("fffff");`
But when you are writng on printWriter, it overwrites the content of the file
this time you are writing
pw.println("howdy"); // write the data
pw.println("folks");
which is 10 characters only with two new line \n which takes 2 bytes since we use println because \n in windows will transform to \r\n . So total of 14.
so 1 character remains there which is f
In your code the following steps are executed.
1 When
br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();
is executed.
The file content will be
sdsadasdsafffff
2 when
pw.println("howdy"); is calling.
String howdy override the first 5 character sdsad and a new line terminates the line. In txt, 2 characters are needed \r\n, this will over write another 2 character .Then the file content will be as follows:
howdy
dsafffff
3 when
pw.println("folks");
is executed.
Since it is not called flush() method in step#2. String folks will over write the second line content in file. and a new line to over write another 2 characters.
Then the following content will be stored in file:
howdy
folks
f

Replace All Backslashes on a Property File

I was looking at a Properties file I'm testing and I realized that every time I do a Properties.store() values that contain characters like : and / receive a backslash, but I want my property file to be read by other programs that are not written in Java (so they will not use the Properties library) and those backslashes are causing problems on them. Is there any way to save the file without those?
I've tried building this function, which is called after the Properties file has been saved:
private void replaceInFile(File file) throws IOException {
File tmpFile = new File("/sdcard/test.prop");
FileWriter fw = new FileWriter(tmpFile);
Reader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while (br.ready()) {
fw.write(br.readLine().replaceAll("\\", "") + "\n");
}
fw.close();
br.close();
fr.close();
}
But I'm getting this error when the function is called:
02-03 13:05:34.757: E/AndroidRuntime(15558): java.util.regex.PatternSyntaxException: Syntax error U_REGEX_BAD_ESCAPE_SEQUENCE near index 1:
\
^
These are special characters. They must be escaped with a slash.
= and : are symbols that separate key from value. What if you have foo=bar=baz? Or foo:bar:baz? Which is the key and which is the value
If you want to enforce different rules, then implement your own mechanism and don't use java.util.Properties. For the complete set of rules see Properties.load(..)
You can, after storing the properties, 1. read to string 2. replace escaped characters. 3. write the new string to file.

Categories

Resources