How to initialize FileWriter outside of the main() method - java

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);

Related

Best way to ensure streams that are opened inside a method call get closed

I'm calling a method to write some data to a CSV file in java. Inside that method, I'm using a FileWriter that throws an IOException. I'm wondering what the correct way to handle this exception is if I want to handle it in the outer method while also ensuring that the FileWriter gets closed.
I am thinking of two solutions:
Just handle the exception inside the method that opens the FileWriter.
Figure out a way to pass the FileWriter back to the calling method so that it may be closed.
Here's an example of what I'm talking about:
public static void outerFunc() {
// get some sort of data
try {
innerFunc(data);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
// can I close the FileWriter here somehow?
}
}
private static void innerFunc(Data data) throws IOException {
FileWriter csv = new FileWriter("result.csv")
// Write the data to the file
csv.flush();
csv.close();
}
Let me know what you guys think. I'm very open to the fact that I may be completely off base here and should be doing this a different way. Thank you in advance for any input!
The method that opens the resource should close it, and I would use the try-with-resources Statement. Like,
try (FileWriter csv = new FileWriter("result.csv")) {
// ...
}

Buffered Output Stream

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");
}

Java writes writes line multiple times?

static void goOut(String in) {
//instance variables
String fileCopy = currentLine + in;
try {
FileWriter writer = new FileWriter(output,true);
writer.write(line1 + System.getProperty("line.separator", "\r\n"));
writer.write(fileCopy + System.getProperty("line.separator", "\r\n"));
} catch(IOException ex) {
ex.printStackTrace();
}
}
Edited code to the correct standard as pointed out by other users.
of course because thats what you r telling it to do. every time is called it writes both x and the number. a quick fix: you can keep a flag if it is the first run set it flag = true. and check within ur method, sth like this:
public class YourClass{
private boolean didRun = false;
static void goOut(String in) {
...... init ur file and writer
if(!didRun)
writer.write(Y);
writer.write(in);
writer.close();
didRun = true;
}
}
I dont know the rest of the code but i think thats what u need
I believe you want to separate the jobs the "goOut" is responsible for.
You should make "goOut" only write the numbers (in your example).
The writing of the y's (in your example) should not be apart of the method and called once, at the start of writing to the file.
Also, #Jon Skeet is right about the multiple FileWriters. Use one, since its the same file.
Agree, sounds like a disaster.
When you use multiple writers to access the file, I would expect to get unpredictable results.
I dont think there is any guarantee that FileWriter1 would complete the task before FileWriter2.
In addition, the method is not synchronized.

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");

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