Unable to append to file based on file.length() operation - java

I want to append to the file and if its not empty; and want to write if its empty. Below is is my code. write function works, append is not. Can anyone guide here?
public class Filecreate {
public static void main(String args[]) throws IOException {
File file = new File("newFileCreated.txt");
System.out.println("file path "+file.getAbsolutePath() +" file length - "+file.length());
FileWriter myWriter = new FileWriter(file);
if((int)file.length() != 0){
myWriter.append("appended text\n");
}else{
myWriter.write("Files in Java might be tricky, but it is fun enough!");
}
myWriter.close();
System.out.println("file length after writing to file "+file.length());
}
}

You don't need to worry about whether or not the file contains anything. Just apply the argument of true to the append parameter in the FileWriter constructor then always use the Writer#append() method, for example:
String ls = System.lineSeparator();
String file = "MyFile.txt";
FileWriter myWriter = new FileWriter(file, true)
myWriter.append("appended text" + ls);
/* Immediately write the stream to file. Only really
required if the writes are in a loop of some kind
and you want to see the write results right away.
The close() method also flushes the stream to file
before the close takes place. */
myWriter.flush();
System.out.println("File length after writing to file " +
new File(file).length());
myWriter .close();
If the file doesn't already exist it will be automatically created
and the line appended to it.
If the file is created but is empty then the line is appended to it.
If the file does contain content then the line is merely appended to
that content.

The issue occurs because you measure file's size after you open it. Thus, you have to check file's size before you open it. Also, I won't recommend to cast long to int, because your solution won't work on big files. To conclude, following code will work for you:
public static void main(String[] args) throws IOException {
File file = new File("newFileCreated.txt");
long fileSize = file.length();
System.out.println("file path "+file.getAbsolutePath() +" file length - "+file.length());
FileWriter myWriter = new FileWriter(file);
if(fileSize > 0L){
myWriter.append("appended text\n");
}else{
myWriter.write("Files in Java might be tricky, but it is fun enough!");
}
myWriter.close();
System.out.println("file length after writing to file "+file.length());
}

Related

Java not creating file

package com.company;
public class Main {
public static void main(String[] args) {
java.io.File file = new java.io.File("image/us.gif");
System.out.println("Does it exist:" + file.exists());
System.out.println("The file has " + file.length() + "bytes");
System.out.println("Can it be read? " + file.canRead());
}
}
I copied this code from my book Introduction to Java Programming, and it compiles correctly but it doesn't create the file, and returns false and zero bytes for the methods. Can someone help please I will give best answer.
You will have to create the file manually unless it already exists. Creating a new File object should not be confused with creating a file in the filesystem.
To create the file you will have to use the method createFile(); which exists in the class File:
File someFile = new File("path.to.file");
someFile.createFile();
It would also be a good idea to check if the file exists before creating it to avoid overwriting it. this can be done by:
File someFile = new File("path.to.file");
if(!someFile.exists()) {
someFile.createFile();
}
This will create a new empty file. That means that it's length will be 0.
To write to the file you will need a byte stream. For example, using a FileWriter:
File test = new File("SomeFileName.txt");
FileWriter fw = new FileWriter(test);
fw.append("Hello! :D");
fw.close();
Note: Some methods i used in the examples above throw exceptions which you will have to handle.

file input out append

I am trying to write some coordinates to a file and later read it in as a string. So I need to have them written to file attached...without space or a new line, but my code writes only the first coordinate, that is pos_Let, but does not write pos_Num at all, not even with a space or on a new line.
So how can I get the code to write to file pos_LetposNum like that? Obviously I mean their references ;) ..thanks in advance
protected void writeCoordtoFile () throws IOException
{
File file = new File("FermiPresentCoord.txt");
boolean yes = file.createNewFile() ;
//boolean yes = exists();
if (yes == true)
{
// create a FileWriter Object
FileWriter writer = new FileWriter(file, true);
// Writes the content to the file
writer.write("");
writer.flush();
writer.write(pos_Let);
writer.flush();
writer.write(pos_Num);
writer.close();
}
else
{
// creates the file
file.createNewFile();
// creates a FileWriter Object
FileWriter out = new FileWriter(file);
// Writes the content to the file
out.write(pos_Let);
out.flush();
out.write(pos_Num);
out.flush();
out.close();
}
}
Quoting the method createNewFile():
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
Note: this method should not be used for file-locking, as the resulting protocol cannot be made to work reliably. The FileLock facility should be used instead.
Returns:
true if the named file does not exist and was successfully created; false if the named file already exists
in your case, you first create the file, and createNewFile() returns true, so you go to the if block, appending the line to the current file. Then, createNewFile() returns false, since, the file exists! So, you go to the else block, and create the file again from scratch...
So, basically, just inverse the if with else, and don't call createNewFile() twice... With the least possible changes (so that you do not get confused) here is my simple suggestion:
protected void writeCoordtoFile () throws IOException
{
File file = new File("FermiPresentCoord.txt");
boolean fileDoesNotExist = file.createNewFile() ;
//boolean fileDoesNotExist = file does **not** exist!
if (fileDoesNotExist)
{
// create a FileWriter Object
FileWriter writer = new FileWriter(file);
// Writes the content to the file
writer.write(pos_Let);
writer.write(pos_Num);
writer.close();
}
else
{
// creates a FileWriter Object
FileWriter out = new FileWriter(file,true);
// Writes the content to the file
out.write(""); //not sure why you need that...
out.write(pos_Let);
out.write(pos_Num);
out.close();
}
}
I can not find out why you are checking the existence of the output file. Because, when you are using FileWriter if the file specified in the path does not exist, it would create it and open a character output stream to it. Also if it exists in that path, only opens the output stream and it is ready to write into.
Try the following code and see whats happening when you run it more than one times:
float posLat = 156.23589965f;
float posLon = 12.987564f;
File file = new File("c:/FermiPresentCoord.txt");
FileWriter writer = new FileWriter(file, true);
writer.append(posLat+",");
writer.append(posLon+",");
writer.flush();
writer.close();
There is no need to invoke the file.createNewFile() and/or checking the for the existence of the file when you want to write into it.
The second argument for the FileWriter constructor is append flag. So every time you create an output stream to a file with FileWriter(file, true) constructor it automatically appends to the data of the file.
Good Luck.

How do I append text to a csv/txt file in Processing?

I use this simple code to write a few strings to the file called "example.csv", but each time I run the program, it overwrites the existing data in the file. Is there any way to append the text to it?
void setup(){
PrintWriter output = createWriter ("example.csv");
output.println("a;b;c;this;that ");
output.flush();
output.close();
}
import java.io.BufferedWriter;
import java.io.FileWriter;
String outFilename = "out.txt";
void setup(){
// Write some text to the file
for(int i=0; i<10; i++){
appendTextToFile(outFilename, "Text " + i);
}
}
/**
* Appends text to the end of a text file located in the data directory,
* creates the file if it does not exist.
* Can be used for big files with lots of rows,
* existing lines will not be rewritten
*/
void appendTextToFile(String filename, String text){
File f = new File(dataPath(filename));
if(!f.exists()){
createFile(f);
}
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f, true)));
out.println(text);
out.close();
}catch (IOException e){
e.printStackTrace();
}
}
/**
* Creates a new file including all subfolders
*/
void createFile(File f){
File parentDir = f.getParentFile();
try{
parentDir.mkdirs();
f.createNewFile();
}catch(Exception e){
e.printStackTrace();
}
}
You have to use a FileWriter (pure Java (6 or 7)) rather than PrintWriter from the Processing API.
FileWriter has a second argument in it's constructor that allows you to set a Boolean to decide whether you will append the output or overwrite it (true is to append, false is to overwrite).
The documentation is here: http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html
Note you can also use a BufferedWriter, and pass it a FileWriter in the constructor if that helps at all (but I dont think it's necessary in your case).
Example:
try {
FileWriter output = new FileWriter("example.csv",true); //the true will append the new data
output.println("a;b;c;this;that ");
output.flush();
output.close();
}
catch(IOException e) {
println("It Broke :/");
e.printStackTrace();
}
As above, this will work in the PDE - and in Android - but if you need to use it in PJS, PyProcessing, etc, then you will have to hack it
dynamically read the length of the existing file and store it in an ArrayList
add a new line to the ArrayList
use the ArrayList index to control where in the file you are currently writing
If you want to suggest an enhancement to the PrintWriter API (which is probably based off of FileWriter), you can do so at Processing's Issue page on GitHub:
https://github.com/processing/processing/issues?state=open
Read in the file's data, append your new data to that, and write the appended data back to the file. Sadly, Processing has no true "append" mode for file writing.

Write some text to a File - Exception

I want to write data to a text file. But, in my application, i will want to keep on writing items to the text file (Which means, the text that i want to write, should be appended to the file - and not create a new file every time)
My code, is as follows; But how could i append text the next time i am writing something to the file ?
1.) The problem with the code below is, the first time writes to the file, but when i am trying to write for the 2nd time i get the following exception;
java.io.IOException: Stream closed
2.) I want to be able to write to the same file untill the application is closed. Therefore, how can i close the Stream when the application is closed ?
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriteToFileExample {
public void writeToFile(String stuff) {
try {
File file = new File("../somefile.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(stuff);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UPDATE 1
private File file;
public WriteToFileExample(){
file = new File("../somefile.txt");
}
public void writeToFile(String stuff) {
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(stuff);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EXCEPTION
Exception in thread "main" java.lang.NullPointerException
at com.proj.example.Log.WriteToFile(WriteToFileExample.java:3)
Which points to if (!file.exists()) {.
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
Use the true argument for the FileWriter constructor.
You should create your FileWriter using the contructor that takes an extra boolean argument, that indicates that you want to append.
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
You never close the FileWriter in your code. And from the documentation for the class:
Whether or not a file is available or may be created depends upon the
underlying platform. Some platforms, in particular, allow a file to be
opened for writing by only one FileWriter (or other file-writing
object) at a time. In such situations the constructors in this class
will fail if the file involved is already open.
Close the file writer before exiting your method, its good practice anyway. And yes, definitely do open the writer in append mode, if you don't want the files contents to be blown away every time you call your method.
Checking the api, says that the FileWriter constructor takes a boolean to flag whether to append or not. That answer your question?
Instead of doing this:
FileWriter fw = new FileWriter(file.getAbsoluteFile());
do as follow:
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
As to append on a existing file FileWriter needs an extra argument as true here
FileWriter
public FileWriter(File file, boolean append) throws IOException
Constructs a FileWriter object given a File object. If the second argument is true, then bytes will be
written to the end of the file rather than the beginning.
Parameters:
file - a File object to write to
append - if true, then bytes will be
written to the end of the file rather than the beginning
Throws:
IOException - if the file exists but is a directory rather than a
regular file, does not exist but cannot be created, or cannot be
opened for any other reason
Since:
1.4

Java FileWriter overwrite

I have a piece of code that generates new data whenever there is new data available as InputStream . The same file is overwritten everytime. Sometimes the file becomes 0 kb before it gets written. A webservice reads these files at regular intervals. I need to avoid the case when the file is 0 bytes.
How do it do this? Will locks help in this case? If the browser comes in to read a file which is locked, will the browser continue to show old data from the cache until the lock is released and file is available to be read again.
try{
String outputFile = "output.html";
FileWriter fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
outputFile = "anotheroutput.html";
fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
fWriter.close();
}
catch(Exception e)
{
e.prinStackTrace();
}
Try writing to a temporary file (in the same file system) and once the file write is complete move it into place using File.renameTo(). If you underlying file system supports atomic move operations (most do) then you should get the behaviour that you require. If you are running on windows you will have to make sure you close the file after reading otherwise the file move will fail.
public class Data
{
private final File file;
protected Data(String fileName) {
this.file = new File(filename);
}
/* above is in some class somehwere
* then your code brings new info to the file
*/
//
public synchronized accessFile(String data) {
try {
// Create temporary file
String tempFilename = UUID.randomUUID().toString() + ".tmp";
File tempFile = new File(tempFilename);
//write the data ...
FileWriter fWriter = new FileWriter(tempFile);
fWriter.write(data);
fWriter.flush();
fWriter.close();
// Move the new file in place
if (!tempFile.renameTo(file)) {
// You may want to retry if move fails?
throw new IOException("Move Failed");
}
} catch(Exception e) {
// Do something sensible with the exception.
e.prinStackTrace();
}
}
}
FileWriter fWriter = new FileWriter(fileName,true);
try using above :-)
Your requirement is not very clear. Do you want to write a new name file every time or you want to append to the same file or you want to over write the same file? Anyway all three cases are easy and from the API you can manage it.
If the issue is that a web service is reading the file which is not yet complete i.e. is in writing phase. In your web service you should check if the file is read only, then only you read the file. In writing phase once writing is finished set the file to read only.
The 0Kb file happens because you are overwriting the same file again. Overwriting cleans up all the data and then start writing the new content.
public class Data
{
String fileName;
protected Data(String fileName)
{
this.fileName= fileName;
return; // return from constructor often not needed.
}
/* above is in some class somehwere
* then your code brings new info to the file
*/
//
public synchronized accessFile(String data)
{
try
{
// File name to be class member.
FileWriter fWriter = new FileWriter(fileName);
//write the data ...
fWriter.write(data);
fWriter .flush();
fWriter .close();
return;
}
catch(Exception e)
{
e.prinStackTrace();
}
this is not needed:
outputFile = "anotheroutput.html";
fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
fWriter.close();
that's because work on the file is a method of class Data

Categories