Buffered Output Stream - java

I have notice a behavior for output stream class (buffered output stream) and I want to understand it to resolve my issue , that when I create an object to write text data in file it is OK but when try to write again with another object of same class it work fine but replace previous text with new one
class writeFile extneds BufferedOutputStream{
public static void main(String arg[]) throws FileNotFoundException, IOException
{
new writeFile(new FileOutputStream(file)).setComments("hello");
new writeFile(new FileOutputStream(file)).setComments("Hi");
}
public void setComments(String s) throws IOException
{
this.write(this.setBytes(s+"\r\n\n"));
this.write(this.setBytes("-----------------------------------\r\n\n"));
}
when execute it I find just Hi word and the first word is not there because it replaced with last one so why when I use another object to write some text it write from beginning and replace with before it and is there any solution because when I close the program and open it again it will be new declaration for object and this considered as new object

There is a FileOutputStream(String, boolean) constructor, where the second parameter is to append. Easiest fix I see, change
new writeFile(new FileOutputStream(file)).setComments("Hi");
to
new writeFile(new FileOutputStream(file, true)).setComments("Hi");
Personally, I think, it would be better to use one OutputStream (and your writeFile is one possible such class). And you should always close your resources (you could use a try-with-resources). Finally, Java naming conventions have classes start with a capital letter - writeFile looks like a method name.
try (writeFile fos = new writeFile(new FileOutputStream(file))) {
fos.setComments("hello");
fos.setComments("Hi");
}

Related

How to initialize FileWriter outside of the main() method

I am writting a program in Java using the Spark Streaming framework (even if you don't know what Spark is you may still know the answer to my problem ).
I am basically receiving strings, one per second, through a socket and want to save them in a txt file ( each string separated by a paragraph. So something like this :
FileWriter a = new Filewriter (path to file);
a.append(string s);
a.append('\n');
a.flush;
The way Spark Streaming works is by converting the main () method into a big while loop, so in order for me to save the strings I receive in the same file, I need to declare the a variable outside of the main () (otherwise it will keep initializing and saving only the last string it receives ).
The problem is, because of an IOEXCEPTION, I have to do this:
public static void writer () throws IOException
{
FileWriter a= new Filewriter (path to file );
}
But if I call writer() in the main () I get the same problem as before ( I keep initializing a).
How can I initialize a outside the main (), so I don't have this problem?
Thank you so much.
You can declare it as a field, however you need to catch the exception in the constructor. You can do this
private final PrintWriter writer = new PrintWriter(filename, true);
Using PrintWriter has the advantage that
it places an appropriate newline at the end of each line.
it can be enabled to autoflush.
You can call it with
writer.println(text);

How to use Scanner to read file and pass it to a method in Java

I am confused with how to use Scanner to read a file (given in command line argument), and use the information from that file in a method. What's the best way to do this?
I know there must be numerous errors in my code. i.e. Which type of parameter shall I pass to the method, string or file? I have commented my questions in the code. Many thanks!
public class Read {
int [] store;
public Read() {
store = new int[200];
}
public static void main(String[] args) throws FileNotFoundException {
File inputFile = new File (args[0]); //shall I declare a File variable here?
Read readFile = new Read();
readFile.doSomething(inputFile);//Should the parameter of doSomething be String type?
}
public void doSomething (String inputFile) throws FileNotFoundException{
Scanner sc; //I intend to use the info. from the file to do something here
sc = new Scanner(new FileReader(inputFile));
while (sc.hasNext()){
.....
}
}
}
I would suggest you to pass String means file path to the method in that sense after reading from file the Objects gets garbage collected after the execution of method while in main method you may want to perform some other stuff and File object remain accessible until the execution of main method.
What if you want to read more than one file and you are passing multiple command line argument ? So passing String to method sounds convenient as it will allow you to manage File object.In this situation creating File Objects and than passing it to method becomes more time consuming.
So it Should be...
public static void main(String[] args){
Read readFile = new Read();
readFile.doSomething(args[0]);
readFile.doSomething(args[1]);//You can read multiple files
....
}
public void doSomething (String inputFile) throws FileNotFoundException{
File inputFile = new File (inputFile);
//Read File With Scanner
}
It is possible to do it that way, but then you'll have to pass the filename into the commandline when starting the program. Like this:
java [program] [filename]
Another solution is hardcoding:
File inputFile = new File ("filename");
As stated above these are the two ways but note your harcoded file must be present in the project where your packages reside.

Java function question

Alright I am very new to Java and am trying to develop an application to teach myself how to use the language.
I have been copying and pasting the same few lines of code all over, and I know that there is a way to consolidate this into a function, but cannot quite figure it out.
FileOutputStream fout4 = openFileOutput("building1hourly.txt", MODE_WORLD_READABLE);
OutputStreamWriter osw4 = new OutputStreamWriter(fout4);
osw4.write("" +iHourlyAfter);
osw4.flush();
osw4.close();
Now isn't there some type of way I could do something like this
public void writerFunction("What to write to file", "name stream", "name writer", "MODE"){insert above code here}
Yes absolutely:
public void writeToFile(String fileName, String contents, int mode) throws IOException {
FileOutputStream fout = openFileOutput(fileName, mode);
OutputStreamWriter osw = new OutputStreamWriter(fout);
osw.write(contents);
osw.flush();
osw.close();
}
First of all, great job so far. Learning programming is just like learning math (except more fun), you can read about it all you want in a book, but you don't really understand concepts until you DO them. You're going about this the right way.
Now, to answer your question: Yes, you can encapsulate the process of writing to a file in a function. Let's call it writeToFile. You want to "call" this function by sending it arguments. The arguments are the information that the function needs to do its work.
There are two sides to a function: the declaration, and the invocation. Just like in math, you can define a function f(x), where f does something. For example: say I have the function f(x) = 2x - 4. That equation is what we call the function declaration, in that we are defining what f does, and you are defining the parameters that it accepts, namely a single value x. Then you want to apply that function on a certain value x, so you might do something like: f(4). This is the function invocation. You are invoking, or calling the function, and sending 4 as the argument. The code that invokes a function is called the caller.
Let's start with the declaration of the function that you want to build:
public void writeToFile (String data, String fileName)
This function defines two parameters in its signature; it expects a String containing the data you will write to the file, and the fileName to which we will write the data. The void means that this function does not return any data back to the caller.
The complete function, the body of which you provided in your post:
public void writeToFile (String data, String fileName){
FileOutputStream fout4 = openFileOutput(fileName, MODE_WORLD_READABLE);
OutputStreamWriter osw4 = new OutputStreamWriter(fout4);
osw4.write("" +iHourlyAfter);
osw4.flush();
osw4.close();
}
Now you will want to call, or invoke this function from somewhere else in your code. You can do this like so:
writeToFile("stuff I want to write to a file", "myFile.txt");

How to write a hashtable<string, string > in to text file,java?

I have hastable
htmlcontent is html string of urlstring .
I want to write hastable into a .text file .
Can anyone suggest a solution?
How about one row for each entry, and two strings separated by a comma? Sort of like:
"key1","value1"
"key2","value2"
...
"keyn","valuen"
keep the quotes and you can write out keys that refer to null entries too, like
"key", null
To actually produce the table, you might want to use code similar to:
public void write(OutputStreamWriter out, HashTable<String, String> table)
throws IOException {
String eol = System.getProperty("line.separator");
for (String key: table.keySet()) {
out.write("\"");
out.write(key);
out.write("\",\"");
out.write(String.valueOf(table.get(key)));
out.write("\"");
out.write(eol);
}
out.flush();
}
For the I/O part, you can use a new PrintWriter(new File(filename)). Just call the println methods like you would System.out, and don't forget to close() it afterward. Make sure you handle any IOException gracefully.
If you have a specific format, you'd have to explain it, but otherwise a simple for-each loop on the Hashtable.entrySet() is all you need to iterate through the entries of the Hashtable.
By the way, if you don't need the synchronized feature, a HashMap<String,String> would probably be better than a Hashtable.
Related questions
Java io ugly try-finally block
Java hashmap vs hashtable
Iterate Over Map
Here's a simple example of putting things together, but omitting a robust IOException handling for clarity, and using a simple format:
import java.io.*;
import java.util.*;
public class HashMapText {
public static void main(String[] args) throws IOException {
//PrintWriter out = new PrintWriter(System.out);
PrintWriter out = new PrintWriter(new File("map.txt"));
Map<String,String> map = new HashMap<String,String>();
map.put("1111", "One");
map.put("2222", "Two");
map.put(null, null);
for (Map.Entry<String,String> entry : map.entrySet()) {
out.println(entry.getKey() + "\t=>\t" + entry.getValue());
}
out.close();
}
}
Running this on my machine generates a map.txt containing three lines:
null => null
2222 => Two
1111 => One
As a bonus, you can use the first declaration and initialization of out, and print the same to standard output instead of a text file.
See also
Difference between java.io.PrintWriter and java.io.BufferedWriter?
java.io.PrintWriter API
Methods in this class never throw I/O exceptions, although some of its constructors may. The client may inquire as to whether any errors have occurred by invoking checkError().
For text representation, I would recommend picking a few characters that are very unlikely to occur in your strings, then outputting a CSV format file with those characters as separators, quotes, terminators, and escapes. Essentially, each row (as designated by the terminator, since otherwise there might be line-ending characters in either string) would have as the first CSV "field" the key of an entry in the hashtable, as the second field, the value for it.
A simpler approach along the same lines would be to designate one arbitrary character, say the backslash \, as the escape character. You'll have to double up backslashes when they occur in either string, and express in escape-form the tab (\t) and line-end ('\n); then you can use a real (not escape-sequence) tab character as the field separator between the two fields (key and value), and a real (not escape-sequence) line-end at the end of each row.
You can try
public static void save(String filename, Map<String, String> hashtable) throws IOException {
Properties prop = new Properties();
prop.putAll(hashtable);
FileOutputStream fos = new FileOutputStream(filename);
try {
prop.store(fos, prop);
} finally {
fos.close();
}
}
This stores the hashtable (or any Map) as a properties file. You can use the Properties class to load the data back in again.
import java.io.*;
class FileWrite
{
public static void main(String args[])
{
HashTable table = //get the table
try{
// Create file
BufferedWriter writer = new BufferedWriter(new FileWriter("out.txt"));
writer.write(table.toString());
}catch (Exception e){
e.printStackTrace();
}finally{
out.close();
}
}
}
Since you don't have any requirements to the file format, I would not create a custom one. Just use something standard. I would recommend use json for that!
Alternatives include xml and csv but I think that json is the best option here. Csv doesn't handle complex types like having a list in one of the keys of your map and xml can be quite complex to encode/decode.
Using json-simple as example:
String serialized = JSONValue.toJSONString(yourMap);
and then just save the string to your file (what is not specific of your domain either using Apache Commons IO):
FileUtils.writeStringToFile(new File(yourFilePath), serialized);
To read the file:
Map map = (JSONObject) JSONValue.parse(FileUtils.readFileToString(new File(yourFilePath));
You can use other json library as well but I think this one fits your need.

Is it possible to avoid temp files when a Java method expects Reader/Writer arguments?

I'm calling a method from an external library with a (simplified) signature like this:
public class Alien
{
// ...
public void munge(Reader in, Writer out) { ... }
}
The method basically reads a String from one stream and writes its results to the other. I have several strings which I need processed by this method, but none of them exist in the file system. The strings can get quite long (ca 300KB each). Ideally, I would like to call munge() as a filter:
public void myMethod (ArrayList<String> strings)
{
for (String s : strings) {
String result = alienObj.mungeString(s);
// do something with result
}
}
Unfortunately, the Alien class doesn't provide a mungeString() method, and wasn't designed to be inherited from. Is there a way I can avoid creating two temporary files every time I need to process a list of strings? Like, pipe my input to the Reader stream and read it back from the Writer stream, without actually touching the file system?
I'm new to Java, please forgive me if the answer is obvious to professionals.
You can easily avoid temporary files by using any/all of these:
CharArrayReader / CharArrayWriter
StringReader / StringWriter
PipedReader / PipedWriter
A sample mungeString() method could look like this:
public String mungeString(String input) {
StringWriter writer = new StringWriter();
alienObj.munge(new StringReader(input), writer));
return writer.toString();
}
StringReader
StringWriter
If you are welling to work with binary arrays in-memory like you do in C# then I think the PipedWriter & PipedReader are the most convenient way to do so. Check this:
Is it possible to avoid temp files when a Java method expects Reader/Writer arguments?

Categories

Resources