delete contents of a binary file before writing to it again - java

I have a simple write method using RandomAccessFile to write an ArrayList of Strings in a *.bin file. Depending on user input, the size of the ArrayList is going to change after every user access. This is the only method that writes to this file.
#FXML protected void writeToFile(){
try(RandomAccessFile file = new RandomAccessFile(fileName, "rw")){
// file.setLength(0);
file.seek(0);
file.writeUTF(wordsArrayList.toString());
file.close();
}catch (IOException e){
System.out.println("error writing from writeToFile()");
}
}
How can I clear the contents of the file (not delete the file and create a new one) using RandomAccessFile before writing to it again in order to avoid *.bin files like below? Setting the length to zero doesn't seem to work.

Related

how to write a string which starts with - into csv file?

I am trying to write data to CSV file.
The string value which starts with - is getting converted to #NAME? automatically when i open csv file after writing. e.g. If i write test it displays correctly but when i write -test the value would be #NAME? when i open csv file. It is not a code issue but csv file automatically changes the value which starts with - to error(#NAME?). How can i correct this programmatically. below is the code,
public class FileWriterTest {
public static void main(String[] args) {
BufferedWriter bufferedWriter = null;
File file = new File("test.csv");
try {
bufferedWriter = new BufferedWriter(new FileWriter(file));
List<String> records = getRecords();
for (String record : records) {
bufferedWriter.write(record);
bufferedWriter.newLine();
}
bufferedWriter.flush();
System.out.println("Completed writing data to a file.");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null)
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static List<String> getRecords() {
List<String> al = new ArrayList<String>();
String s1 = "test";
String s2 = "-test";
al.add(s1);
al.add(s2);
return al;
}
}
Could you please assist?
It's a problem with excel. When you open a CSV file in excel it tries to determine cell type automatically which usually fails. The CSV file is alright the editor is not ;)
You can either right click on the field, select Format Cell and there make it a text file (and you might need to remove the automatically inserted '=' sign). Or you can open the CSV file by going into Data - From Text/CSV and in the wizard select the proper column types.
In the formal CSV standard, you can do this by using quotes (") around the field value. They're a text delimiter (as opposed to other kinds of values, like numeric ones).
It sounds like you're using Excel. You may need to enable " as a text delimiter/indicator.
Update: If you double-click the .csv to open it in Excel, even this doesn't work. You have to open a workbook and then import the CSV data into it. (Pathetic, really...)
I got a relatively old version of Excel (2007), and the following works perfectly:
Put the text between double quotes and preceed it with an equal sign.
I.e., -test becomes ="-test".
You file will therefore look like this:
test1,test2,test3
test4,="-test5",test6
UPDATE
Works in Excel-2010 as well.
As Veselin Davidov mentioned, this will break the csv standard but I don't know whether that's a problem.

FileOutputStream(FileDescriptor) that overwrites instead of appending data?

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

Java FileWriter not writing to file

I'm creating an app which requires to write a file for every user (in JSON format).
The app successfully creates the file, But it's empty. In the code I added a finer output to see how the converted JSON String looks like, and I noticed that it's complete (it contains everything, so the conversion is ok). But the string isn't present in the file.
//create a new FileWriter C:/.../42.guser
FileWriter writer = null;
//for every User
for(int i=0; i<users.size(); i++) {
try {
File f = new File(Users.usersDir.getPath()+"/"+i+".guser");
//Create new file
f.createNewFile();
writer = new FileWriter(f);
//convert to json and write to file. Here we get the object with KEY = keys[i].
String stringedUsr = gson.toJson(users.get(keys[i]));
logger.finer("Converted user: \""+stringedUsr+"\""); //Output seems ok
//Write (NOT WORKING)
writer.write(stringedUsr);
logger.fine("Wrote updated user \""+keys[i]+"\" to file "+f.getCanonicalPath());
} catch (IOException e) {
FAILS++;
e.printStackTrace();
}
}
//End of for
What am I doing wrong?
Note: i gave to the app all the necessary Permissions. No AccessControlExceptions
First of all think about closing your writer.
When closing, it should flush() your data first (as mentioned in the doc here)
You can also flush() manually.

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.

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.

Categories

Resources