FileOutputStream(FileDescriptor) that overwrites instead of appending data? - java

Im writing to a file through a FileOutputStream that is opened via its constructor taking a FileDescriptor.
My desired behavior: When I write to the file I want that to be the only content of it. E.g. writing "Hello" should result in the file containing just "Hello".
Actual behavior: Each time I write something, it is simply appeneded. E.g. in the above example I will get "HelloHello".
How can I open a FileOutputStream like Im doing, and have it not be in append mode?
Note: I am forced to use a FileDescriptor.

According to the ContentProvider.java file documentation, you can use "rwt" mode to read and write in file in truncating it.
ParcelFileDescriptor pfd = context.getContentResolver.openFileDescriptor(uri, "rwt");
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
#param mode Access mode for the file. May be "r" for read-only access,
"rw" for read and write access, or "rwt" for read and write access
that truncates any existing file.
Hope this help despite that the question was posted a long time ago.

If you use FileOutoutStream then the ctor provides an option for you to specify whether you want to open the file to append or not. Set it to false and it will work.
OutputStream out = null;
try {
out = new FileOutputStream("OutFile", false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}

FileOutputStream(File file, boolean append)
Make the argument append to false, so it overrides the existing data everytime when you call.
https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#FileOutputStream(java.io.File,%20boolean)

FileOutputStream outputStream;
try {
outputStream = openFileOutput("your_file", Context.MODE_PRIVATE);
//Context.MODE_PRIVATE -> override / MODE_APPEND -> append
outputStream.write("your content");
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}

Related

Unable to delete text file using delete()

I am trying to transfer the data from old textfile to new textfile. Although the code below is able to transfer successfully, it does not delete the old textfile. May I know why is this so?
private void dataTransfer(String oldFilePath, String newFilePath) {
byte[] buffer = new byte[10000];
try {
FileInputStream fileInput = new FileInputStream(oldFilePath);
BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);
FileOutputStream fileOutput = new FileOutputStream(newFilePath);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(fileOutput);
while(true) {
int length = fileInput.read(buffer);
if(length == -1) {
break;
} else {
bufferedOutput.write(buffer);
bufferedOutput.flush();
}
}
fileInput.close();
bufferedInput.close();
fileOutput.close();
bufferedOutput.close();
File oldFile = new File(oldFilePath);
oldFile.delete();
} catch (IOException e) {
e.printStackTrace();
System.out.println(ERROR_TRANSFER_DATA);
}
}
Update the JRE and JDK, make sure you have the rights on the file. Try with a file created by you.
Also, add a catch block for SecurityException
For deleting a file it should work fine but for deleting a directory you have to make sure that Directory is Empty.
You can use the following code block. It works, though don't know. Even without setWritable, it works,
oldFile.setWritable(true);
if(!oldFile.delete()){
System.out.println("de;eted");
}
According to Oracle's docs, the delete method does not guarantee that it will delete the file.
http://docs.oracle.com/javase/7/docs/api/java/io/File.html#delete()
Deleting a file will fail if:
file does not exist
there is a lock on that file it might be opened by another process
file does not exist on the disk
you don't have enough permissions to delete that file (in this case a SecurityException is thrown)
I agree with #panagdu that you might not have sufficient rights to delete the file.
Just as a fluke try closing bufferedStream before fileInputStream
like
bufferedInput.close();
fileInput.close();
bufferedOutput.close();
fileOutput.close();
But I don't think this will help.
Test your code for files with sufficient permission. For example Java does not allow the delete() for system files.

How to make a copy of a file containing images and text using java

I have some word documents and excel sheets which has some images along with the file text content. I want to create a copy of that file and keep it at a specific location. I tried the following method which is creating file at specified location but the file is corrupted and cannot be read.
InputStream document = Thread.currentThread().getContextClassLoader().getResourceAsStream("upgradeworkbench/Resources/Upgrade_TD_Template.docx");
try {
OutputStream outStream = null;
Stage stage = new Stage();
stage.setTitle("Save");
byte[] buffer= new byte[document.available()];
document.read(buffer);
FileChooser fileChooser = new FileChooser();
fileChooser.setInitialFileName(initialFileName);
if (flag) {
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Microsoft Excel Worksheet", "*.xls"));
} else {
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Microsoft Word Document", "*.docx"));
}
fileChooser.setTitle("Save File");
File file = fileChooser.showSaveDialog(stage);
if (file != null) {
outStream = new FileOutputStream(file);
outStream.write(buffer);
// IOUtils.copy(document, outStream);
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
Can anyone suggest me any different ways to get the proper file.
PS: I am reading the file using InputStream because it is inside the project jar.
PPS: I also tried Files.copy() but it didnt work.
I suggest you never trust on InputStream.available to know the real size of the input, because it just returns the number of bytes ready to be immediately read from the buffer. It might return a small number, but doesn't mean the file is small, but that the buffer is temporarily half-full.
The right algorithm to read an InputStream fully and write it over an OutputStream is this:
int n;
byte[] buffer=new byte[4096];
do
{
n=input.read(buffer);
if (n>0)
{
output.write(buffer, 0, n);
}
}
while (n>=0);
You can use the Files.copy() methods.
Copies all bytes from an input stream to a file. On return, the input stream will be at end of stream.
Use:
Files.copy(document, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
As the class says, the second argument is a Path, not a File.
Generally, since this is 2015, use Path and drop File; if an API still uses File, make it so that it uses it at the last possible moment and use Path all the way.

Append data in text file does not work in android application

I'm using the following code for append new position data obtained by GPS, each time position change.
if (isExternalStorageWritable()) {
if (myFile.exists()) {
try {
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(location.getLatitude()+", "+location.getLongitude()+", "+nodeCounter+"\n");
myOutWriter.close();
fOut.close();
nodeCounter++;
} catch (Exception e) {
}
} else {
try {
myFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}else
{
Log.i("logGPSData","Error");
}
The problem is that the append does not work, since each time a new row is inserted, the previous row is overwritten, so my file contains always one line, even if I collect many gps data.
The second argument means if text should be appended to the existing file, change the following lines in your code:
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
to:
FileOutputStream fOut = new FileOutputStream(myFile,true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut,true);
From the Docs:
public FileOutputStream(String name,boolean append)
throws FileNotFoundException
Creates a file output stream to write to the file with the specified name. If the second argument is true, then bytes will be written to the end of the file rather than the beginning. A new FileDescriptor object is created to represent this file connection.
First, if there is a security manager, its checkWrite method is called with name as its argument.
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 then a FileNotFoundException is thrown.
Parameters:
1) name - the system-dependent file name
2) append - if true, then bytes will be written to the end of the file rather than the beginning
Throws:
1)FileNotFoundException - 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.
2)SecurityException - if a security manager exists and its checkWrite method denies write access to the file.
Since:
JDK1.1

File Delete and Rename in Java

I have the following Java code which will search in an xml for a specific tag and then will add some text to it and save that file. I couldnt find a way to rename the emporary file to the original file. Please suggest.
import java.io.*;
class ModifyXML {
public void readMyFile(String inputLine) throws Exception
{
String record = "";
File outFile = new File("tempFile.tmp");
FileInputStream fis = new FileInputStream("InfectiousDisease.xml");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
FileOutputStream fos = new FileOutputStream(outFile);
PrintWriter out = new PrintWriter(fos);
while ( (record=br.readLine()) != null )
{
if(record.endsWith("<add-info>"))
{
out.println(" "+"<add-info>");
out.println(" "+inputLine);
}
else
{
out.println(record);
}
}
out.flush();
out.close();
br.close();
//Also we need to delete the original file
//outFile.renameTo(InfectiousDisease.xml);//Not working
}
public static void main (String[] args) {
try
{
ModifyXML f = new ModifyXML();
f.readMyFile("This is infectious disease data");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Thanks
First delete the original file and then rename the new file:
File inputFile = new File("InfectiousDisease.xml");
File outFile = new File("tempFile.tmp");
if(inputFile.delete()){
outFile.renameTo(inputFile);
}
A good method to rename files is.
File file = new File("path-here");
file.renameTo(new File("new path here"));
In your code there are several issues.
First your description mentions renameing the original file and adding some text to it. Your code doesn't do that, it opens two files, one for reading and one for writing (with the additional text). That is the right way to do things, as adding text in-place is not really feasible using the techniques you are using.
The second issue is that you are opening a temporary file. Temporary files remove themselves upon closing, so all the work you did adding your text disappears as soon as you close the file.
The third issue is that you are modifying XML files as plain text. This sometimes works as XML files are a subset of plain text files, but there is no indication that you attempted to ensure that the output file was an XML file. Perhaps you know more about your input files than is mentioned, but if you want this to work correctly for 100% of the input cases, you probably want to create a SAX writer that writes out all a SAX reader reads, with the additional information in the correct tag location.
You can use
outFile.renameTo(new File(newFileName));
You have to ensure these files are not open at the time.

Creating a file is causing problem, the File.getPath() doesn't seem to work

I am trying to create a back up file for an html file on a web server.
I want the backup to be in the same location as the existing file (it's a quick fix). I want to create the file using File file = new File(PathName);
public void backUpOldPage(String oldContent) throws IOException{
// this.uri is a class variable with the path of the file to be backed up
String fileName = new File(this.uri).getName();
String pathName = new File(this.uri).getPath();
System.out.println(pathName);
String bckPath = pathName+"\\"+bckName;
FileOutputStream fout;
try
{
// Open an output stream
fout = new FileOutputStream (bckFile);
fout.close();
}
// Catches any error conditions
catch (IOException e)
{
System.err.println ("Unable to write to file");
System.exit(-1);
}
}
But if instead I was to set bckPath like this, it will work.
String bckPath = "C://dev/server/tomcat6/webapps/sample-site/index_sdjf---sd.html";
I am working on Windows, not sure if that makes a difference.
The result of String bckPath = pathName+"\"+bckName;
is bckPath = C:\dev\server\tomcat6\webapps\sample-site\filename.html - this doesn't result in a new file.
Use File.pathSeparator, that way you dont need to worry what OS you are using.
Try to use File.getCanonicalPath() instead of plain getPath(). This helps if the orginal path is not fully specified.
Regarding slashes, / or \ or File.pathSeparator is not causing the problem, because they are all the same on Windows and Java. (And you do not define bckFile in your code, only bckPath. Also use getCanonicalPath() on the new created bckPath.)

Categories

Resources