Is it possible to append columns to a text file in java? - java

Am aware that
FileOutputStream out = new FileOutputStream(file_name, true);
allows appending rows to a file. Is there a way to append columns of data to a non-empty text file starting from the first row?
For e.g., file.txt contains:
Name Address
ABC OtherLand
Can we later modify file.txt to be:
Name Address PhoneNumber
ABC OtherLand 3333333333
I've heard of the awk command in Unix. If there isn't a way to do this directly in the java programming language, would appreciate if someone could share code-bits on calling awk using java syscalls.
Thanks!

No you can't. There is no such option. You can always open a file to read, write or append content to it.
To achieve this, you will need to
Read each line of a file
Append the content to each line.
Write to a temporary file

Related

Look for specific sequence of characters in a file and store a sequence of characters/numbers after it in Java

I am trying to open up a .htm file and read a revision number of a file from it.
Let's say these are the lines in the file.
I don't want to read this.
I don't want to read this.
I don't want to read this. I don't want to read this. I don't want to read this. I don't want to read this.
Now, I want to look for the following characters "HIJK # " and read the number following it. Say 123456.
It will be in a line like this HIJK # 123456
I want to look for the specific sequence of characters "HIJK # " and read the number following it and store that number in a variable. Any help is appreciated. Thanks!
Simple approach :
Parse the file using a parser (because it is a htm file) Line-by-Line (maybe use JSoup)
On each line (read as a string), use contains("HIJK #").
If 2 is true, do replaceAll(".*HIJK #(//d+).*","$1");
Bingo!, you got your number
Happy coding.

split csv according to field in Java

I want to split a csv file according to the last "field".
For instance the csv file contains:
a,1
b,2
c,3
d,1
The numbers indicate categories.
This file should be split into seperate files according to the numbers (resp. categories) so that there exist three files.
first file:
a,1
d,1
second file:
b,2
third file:
c,3
The greedy method would be to read the csv per line, split the string at "," and seperate the last element (here the number). Afterwards I could check the number of the current line and put it into a FileWriter.
But: I do not know how many categories there will be as I want to keep the system extensible. Therefore the number of needed FileWriters is unknown.
As an alternative I could read the complete csv file for each category. In the first iteration only lines of category "1" would be processed and written into "1.csv", in the second step only lines of category "2" go into "2.csv" and so on.
But: This means the file has to be read as many times as categories exist which could be quite often.
Do you know whether there is an elegant solution for this purpose?
I also appreciate linux-based solutions! Maybe it is not necessary to create a Java program?
I guess that awk could be the tool of choice?
Thanks for your help!
Try this awk one-liner:
awk -F, '{print >> "output"$NF".csv"}' input.csv
It will read each line and write it to the appropriate output csv file, based on the value of the last field of the line.
I would make a more generic way. In this case I don't need to know all the items in the second column, so this is automatic:
total.csv:
a,1
b,2
c,3
d,1
script.sh:
#!/bin/bash
for line in $(cat total.csv)
do
filename=$(echo $line | awk -F "," '{print $2}')
echo $line >> $filename.csv
done
outputs: 1.csv 2.csv 3.csv

write strings to the bottom line of an textfile

i want to write strings to a textfile, everytime to the bottom of the file. And then if im searching for a certain string in the textfile and finds it, i want to replace that line with another.
I'm thinking this: Count rows in textfile and add +1 and then write the string i want to write to that index. But is it even possible to write to a certain linenumber in a textfile?
And how about to update a certain row to another string ?
thanks!
You do not want to do that: it is a recipe for disaster. If, during the original file modification, you fail to write to it, the original file will be corrupted.
Use a double write protocol, write the modified file to another file, and only if the write suceeds, rename that file to the original.
Provided your file is not too big, for some definition of "big", I'd recommend creating a List<String> for the destination file: read the original file line by line, add to that list; once the list processing is complete (your question is unclear what should really happen), write each String to the other file, flush and close, and if that succeeds, rename to the original.
If you want to append strings, the FileOutputStream does have an alternate constructor which you can set to true so you can open for appending.
If you'd like, say, to replace strings into a file without copying it, your best bet would be to rely in RandomAccessFile instead. However, if the line length is varying, this is unreliable. For fixed-length records, this should work as such:
Move to the offset
Write
You can also 'truncate' (via setLength), so if there's a trailing block you need to get rid, you could discard as such.
A Third Solution would be to rely in mmap. This requires on a Memory-Mapped Bytebuffer for the whole file. I'm not considering the whole feasibility of the solution (it works in plain C), but that actually 'looks' the more correct, if you consider both the Java Platform + the Operating System

Carriage Return and Line Feed windows and Linux java application

I am working on a integration test application, this is what I am doing in the test case,
I read a test input file,which is stored in the cvs , write it to a file in the file system,the application polls the directory for the file, processes it and creates the output file, and I poll the directory for the output file, test case is successful if the both the file contents are equal(I am reading the both input files and output files into strings and comparing them).
The problem is this test case fails when its runs in a linux system, the reason being the file which is stored in the cvs was checked in from a windows system which contains CRLF as the line terminations whereas the output file generated has the line terminations as CR,now when I read these files and compare them character by character, they are having a mismatch.
could anyone help here.
You can check the line separator for the host operating system using System.getProperty("line.separator")
Since you're using text files, you can also compare the file contents line by line. Check LineNumberReader.readLine() for that.
You can try to compare them by lines. E.g. use FileUtils for this.
List<String> file1 = FileUtils.readLines(...);
List<String> file2 = FileUtils.readLines(...);
return file1.equals(file2);
You could remove all the '\r' characters from the downloaded file? Or replace the "\r\n" Windows string by the "\n" Linux one. Beware of the Mac case too: end of line could be identified by "\r".
When you check in the file, you can tell CVS it's a binary file (cvs add -kb), and then CVS will not convert line endings along the way.
This has other drawbacks too, e.g. no proper diff, but if you really test character by character, I guess you don't need that.
Please note that you must specify -kb when adding the file, you can't change it later.

How to convert standard input to a string?

I would like to know how I can convert standard input to a string. For instance, I have a txt file with n amount of letters - all these I want to read into one string.
Just to make sure: standard input is when you give the program a .txt as input.
Help would be appreciated!
I have a file and I want to store the data of it in a string.
This can be done using commons-io:
String content = FileUtils.readFileToString(file);
(complete example)
To read from stdin to a string, you could use a scanner. Use while (scanner.hasNextLine()) if you want the entire file.
String firstLineFromStdin = new Scanner(System.in).readLine();
What you want to do is pipe the file into your application...
java your.package < file.txt
Then you can read the file as normal via Java's System.in.
First, do you want to give a filename as a argument with your program. Or the whole file as input? In the first case you do:
"program filename.txt"
In the second you input:
"program < filename.txt".
In the first case the filename is the input. And your program will have to open a file itself. In the second case the contents of the file are given as input of the file.
If you only give the filename, the filename is in the arguments of your main function (the array args of the "main(String args[])" part. Using this filename you can then use the earlier suggested readFileToString to convert the contents of the file into a string.
If you want to use the other method of file input "program < filename.txt", use the a InputStream for that. See the documentation for more information about InputStream http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html
You also mention you are rather new to Java. I hope you do know of the existence of the java documentation? http://download.oracle.com/javase/6/docs/api/index.html contains a lot of information you might want to know.
I end up using this:
String s = "";
while (!StdIn.isEmpty()){
s = s + StdIn.readChar();
}
I ran the program using: java program < a.text
You could try something like
System.setIn(new FileInputStream(filename));
Here's an example on redirecting standard i/o

Categories