I have a question about the com.jmatio.io package that I was hoping someone could answer. I am looking to write to a .mat file (using java) that may or may not already exist.
If it exists I would like to append the information to the end but if the file is not created I would like to create a new file and just add the contents to that.
My second write is overwriting the first but I would not like it to do this.
Any suggestions or solutions is gladly appreciated.
If you want to write multiple arrays to a new file you can achieve it using the MatFileIncrementalWriter. As it's explained in it's javadoc
An updated writer which allows adding variables incrementally for the life of the writer. This is necessary to allow large variables to be written without having to hold onto then longer than is necessary.
And it states clearly that you can't append to an existing file.
If you want to append to an existing file you might need
read variables from the existing file
write the existing variables back to the file using a MatFileIncrementalWriter
add new variables to the incremental writer
You need to write in append mode so the content get appended to the end to the file instead of overwriting.
File out = new File("out.mat");
try(FileWriter fw = new FileWriter(out, true); // true is for append
BufferedWriter bw = new BufferedWriter(fw)) {
// ...
}
If the file does not exist, it will be created.
Related
I'd like to modify the first line or header, of an existing csv file by adding a string to the end of that line.
I've tried using BufferedWriter to do so, but I can only get it to append at the end of the file.
My working code:
public static void writeStringtoCsvFile(String filePath, String input) throws IOException {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filePath, true)));
out.append(input);
out.close();
}
It seems OpenCsv doesnt have an available method to append to an existing file either. The file I need to process is at least 160mb or 1+mil records in size, would the alternative method:
BufferedReader to read all the lines
Append whatever is needed to first line
BufferedWriter to write everything to a new file
be too slow? Is there a more elegant solution to this? Thanks!
File systems do not allow you to insert bytes into or delete bytes from the middle of a file without rewriting all of the bytes after the insertion / deletion point.
Since the file system doesn't support it, the Java file I/O APIs can't support it.
Since the Java file I/O APIs don't support it, neither can the OpenCvs APIs. (Or at least not without rewriting the file under the covers.)
So, the answer is that there isn't a more efficient way than reading writing all of the lines of the file.
Notes:
While it is technically possible to do an in-place rewrite of a file, it is safer (and possibly more efficient) to create a new file, write to it and rename it when the writing is completed.
Reading and writing a line at a time (using BufferedReader / BufferedWriter) is better than reading all lines into memory at the same time, then writing them all out. Especially if the files are large.
This is my scenario: I have a huge .txt file (~16GB) that contains some lines that have to be removed (that can easily be found with a .contains()).
Obviously the idea of loading the whole file on RAM and explore it with a Scanner, then saving the results in a new .txt file is unfeasible (since I have 16GB of RAM).
I also know that with the streams I'm able to read the file line by line, avoiding the memory leak. What I don't know (and haven't been able to find) is wether it is possible to edit that specific line and put it back in its place into the file.
Otherwise, is it possible to just rewrite a new .txt file with just the "correct" lines in a similar way to the one that allows me to read line by line, so without loading the whole file in memory, since before or after it will become as huge as the original one?
Set up a Stream Reader that will be reading your file line by line, and a Stream writer that will be outputting to the new file. If the reader doesn't find the line to edit the writer simply writes that line to the new file. If the reader spots the line it wishes to edit, create a method to manipulate the line and return it, then have the Writer write that manipulated line rather than the original one.
You won't be allowed to access the same file with a Streamreader and Streamwriter.
I was recently trying to export my game to a jar file, and I ran into a problem with converting files to input and output streams. With the regular code that was not exported, I was able to read and write to text files by simply calling the Scanner and PrintStream constructor with the File location. This didn't work inside the jar because apparently these were no longer considered as files. I was able to work around the input stream one by doing this:
Scanner infile = new Scanner(this.getClass().getResourceAsStream("Resources/leaderboard.txt"));
as opposed to,
Scanner infile = new Scanner("Resources/leaderboard.txt");
And I am trying to utilize PrintStream, but so far I have not found an equivalent function that will take in a String location and return an OutputStream for the PrintStream constructor. Should I use a different method for writing to text files in a jar, is there a function or method of converting it to an OutputStream that I have yet to see, or should I avoid printing to a text file altogether?
Thanks in advance.
You shouldn't and for practical purposes can't write to a "file" within a jar file. Yes, there are kludges that allow you to get around this, but they shouldn't be implemented. Instead all files that the program might change should be outside of the jar and should be separate files.
I need to delete a line from a .txt file stored in the android device's internal storage. I am using
FileOutputStream fos = context.openFileOutput("file.txt", Context.MODE_APPEND);
to open the .txt file. I already know the line which is to be deleted. How to delete it? Sorry if this question is easy, I looked and couldn't find an answer on Google.
You can't easily remove a line of text from a file. You can overwrite it with other data which contains the same number of characters, but basically files don't support removing data from arbitrary locations in a file.
You probably want to:
Create a reader for the existing file
Create a writer for a new file
Copy one line at a time, skipping the line you want to delete
Close both the reader and the writer
Rename the old file out of the way
Rename the new file to the old filename
Delete the renamed old file
(Those steps make sure that even if something goes wrong, you never lose data.)
Ok so I know the value of the line, I dont have the line number, how would I edit only 1 line?
Its a config file, i.e
x=y
I want a command to edit x=y to x=y,z.
or even x=z.
In Java you can use `Properties class:
app.config file:
x=y
java:
public void writeConfig() throws Exception {
Properties tempProp = new Properties();
tempProp.load(new FileInputStream("app.config"));
tempProp.setProperty("x", "y,z");
tempProp.store(new FileOutputStream("app.config"), null);
}
If you are using that configuration format, you might want to use
java.util.Properties
component to read/write on that file.
But if you just want to edit it by hand, you can just read the file line by line and match the variable you want to change.
One way to do it is to:
Read the file into memory; e.g. as an array of Strings representing the lines of the file.
Locate the String/line you want to change.
Use a regex (or whatever) to modify the String/line
Write a new version of the file from the in memory version.
There are many variations on this. You also need to take care when you write the new version of the file to guard against losing everything if something goes wrong during the write. (Typically you write the new version to a temporary file, rename the old version out of the way (e.g. as a backup) and rename the new version in place of the old one.)
Unfortunately, there is no way to add or remove characters in the middle of a regular text file without rewriting a large part of the file. This "problem" is not specific to Java. It is fundamental to the way that text files are modelled / represented on most mainstream operating systems.
Unless the new line has the exact same length as the old one, your best bet is to
Open a temporary output file
Read the config file, line by line
Search for your key
If you can't find it, just write the line you just read to the output file
If you can find it, write the new value to the temporary file instead
Until you hit EOF
Delete old file
Rename new file to the old file
IF your config file is small, you can also do the whole parsing/modification step in memory and then write the final result back to the config file, that way you skip the temporary file (although a temporary file is a good way to prevent corruption if something breaks while you write the file).
If this is not what you're looking for, you should edit your question to be a lot more clear. I'm just guessing what you're asking for.
If your data is all key and value pairs, for example ...
key1=value1
key2=value2
... then load them into a Properties object. Off the top of my head, you'll need a FileInputStream to load the properties, modify with myProperties.put(key, value) and then save the properties with the use of a FileOutputStream.
Hope this helps!
rh