Append a String to the end of the existing String with specific position in a text file in Java - bufferedreader

Exp -
In a text file we have the following topics with some description.
#Repeat the annotation
It is the major topic for .....
#Vector analysis
It covers all the aspects of sequential....
#Cloud Computing
Create header accounts for all the users
We have to add / append new Tags to the Topics in specific line
For exp-
#Repeat the annotation #Maven build
#Cloud Computing #SecondYear
File f = new File("/user/imp/value/GSTR.txt");
FileReader fr = new FileReader(f);
Object fr1;
while((fr1 = fr.read()) != null) {
if(fr1.equals("#Repeat the annotation")) {
FileWriter fw = new FileWriter(f,true);
fw.write("#Maven build");
fw.close();
}
}
****** #Maven is getting added to the last line of the text file but not at the specific position next to the topic

The output is written to the file GSTR_modified.txt. The code along with an example input file is also available here. The code in the github repository reads the file "input.txt" and writes to the file "output.txt".
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException {
// Create a list to store the file content.
ArrayList<String> list = new ArrayList<>();
// Store the file content in the list. Each line becomes an element in the list.
try (BufferedReader br = new BufferedReader(new FileReader("/user/imp/value/GSTR.txt""))) {
String line;
while ((line = br.readLine()) != null) {
list.add(line);
}
}
// Iterate the list of lines.
for (int i = 0; i < list.size(); i++) {
// line is the element at the index i.
String line = list.get(i);
// Check if a line is equal to "#Repeat the annotation"
if (line.contains("#Repeat the annotation")){
// Set the list element at index i to the line itself concatenated with
// the string " #Maven build".
list.set(i,line.concat(" #Maven build"));
}
// Same pattern as above.
if (line.contains("#Cloud Computing")){
list.set(i,line.concat(" #SecondYear"));
}
}
// Write the contents of the list to a file.
FileWriter writer = new FileWriter("GSTR_modified.txt");
for(String str: list) {
// Append newline character \n to each element
// and write it to file.
writer.write(str+"\n");
}
writer.close();
}
}

Related

How can we write data in CSV from Beanshell

While executing below code in eclipse its working but not working in bean shell ? it displaying error near writer.write(data);
So please help me out how can we pass string array from beanshell to csv
import java.io.*;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.util.List;
int i;
File file = new File("/home/sarvesh/Desktop/sgi/10");
int filecount = file.list().length;
File[] files = file.listFiles();
String[] imageString = new String[filecount];
for ( i =0;i<filecount;i++) {
File f = new File(files[i].getAbsolutePath());
FileInputStream fis = new FileInputStream(f);
byte [] byteArray = new byte[(int) f.length()];
fis.read(byteArray);
imageString[i] = Base64.getEncoder().encodeToString(byteArray);
//vars.put("imagData",imageString[i]);
FileWriter writer = new FileWriter("/home/sarvesh/Desktop/sgi/base64_csv.csv");
// List<String> data = new ArrayList<String>();
ArrayList data = new ArrayList();
data.add(new String[] {imageString[i] });
**writer.write(data);**
// writer.write(imageString[i]);
// writer.close();
System.out.println("***********************************************");
System.out.println("Base 64 conversion of Image : " + i + " ::" + imageString[i]);
System.out.println("File Path : " + f.getAbsolutePath());
System.out.println("***********************************************");
}
Beanshell is not Java, it doesn't support diamond operators therefore you need to change this line:
List<String> data = new ArrayList<String>();
to this one:
List data = new ArrayList();
Starting from JMeter 3.1 you should rather be using JSR223 Test Elements and Groovy language for scripting
Your approach will work given you run your test with 1 thread (virtual user), if there will be more users - you'll run into the race condition resulting into file corruption/data loss so if you need to write some specific data into some specific file it's better to go for the Flexible File Writer. Alternatively you can use Critical Section Controller but it will slow down your test

FSDataOutputStream.writeUTF() adds extra characters at the start of the data on hdfs. How to avoid this extra data?

What I am trying to is to convert a sequence file on hdfs which has xml data into .xml files on hdfs.
Searched on Google and found the below code. I made modifications according to my need and the following is the code..
public class SeqFileWriterCls {
public static void main(String args[]) throws Exception {
System.out.println("Reading Sequence File");
Path path = new Path("seq_file_path/seq_file.seq");
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
SequenceFile.Writer writer = null;
SequenceFile.Reader reader = null;
FSDataOutputStream fwriter = null;
OutputStream fowriter = null;
try {
reader = new SequenceFile.Reader(fs, path, conf);
//writer = new SequenceFile.Writer(fs, conf,out_path,Text.class,Text.class);
Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);
Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf);
while (reader.next(key, value)) {
//i am just editing the path in such a way that key will be my filename and data in it will be the value
Path out_path = new Path(""+key);
String string_path = out_path.toString();
String clear_path=string_path.substring(string_path.lastIndexOf("/")+1);
Path finalout_path = new Path("path"+clear_path);
System.out.println("the final path is "+finalout_path);
fwriter = fs.create(finalout_path);
fwriter.writeUTF(value.toString());
fwriter.close();
FSDataInputStream in = fs.open(finalout_path);
String s = in.readUTF();
System.out.println("file has: -" + s);
//fowriter = fs.create(finalout_path);
//fowriter.write(value.toString());
System.out.println(key + " <===> :" + value.toString());
System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeStream(reader);
fs.close();
}
}
I am using "FSDataOutputStream" to write the data to HDFS and the method is used is "writeUTF" The issue is that when i write to the hdfs file some additional characters are getting in the starting of data. But when i print the data i couldnt see the extra characters.
i tried using writeChars() but even taht wont work.
is there any way to avoid this?? or is there any other way to write the data to HDFS???
please help...
The JavaDoc of the writeUTF(String str) method says the followings:
Writes a string to the underlying output stream using modified UTF-8 encoding in a machine-independent manner.
First, two bytes are written to the output stream as if by the writeShort method giving the number of bytes to follow. This value is the number of bytes actually written out, not the length of the string. Following the length, each character of the string is output, in sequence, using the modified UTF-8 encoding for the character. (...)
Both the writeBytes(String str) and writeChars(String str) methods should work fine.

while(line.contains("^")) loop not breaking

this is my class:
import java.io.*;
public class Test
{
public static void main(String[] args) throws FileNotFoundException, IOException
{
BufferedReader br = new BufferedReader(new FileReader("file2.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("file.txt"));
int i = 0;
String line;
while ((line = br.readLine()) != null) {
while(line.contains("^")) {
i ++;
line = line.replaceFirst("^", Integer.toString(i));
}
bw.write(line + "\n");
}
br.close();
bw.close();
}
}
the file2.txt and file.txt are exactly the same and I want to make the lines that look like
<wpt lat="26.381418638" lon="-80.101236298"><ele>0</ele><time> </time><name>Waypoint #^</name><desc> </desc></wpt>
to look like
<wpt lat="26.381418638" lon="-80.101236298"><ele>0</ele><time> </time><name>Waypoint #5</name><desc> </desc></wpt>
When I run it though, it goes on an infinite loop. Any advice will help. Thanks!
line = line.replaceFirst("^", Integer.toString(i));
replaceFirst's first argument is a regular expression, and "^" as a regular expression means "the start of the string". So this command just keeps prepending values to the start of the string, and never removes any circumflexes. Instead, you should write:
line = line.replaceFirst("\\^", Integer.toString(i));
The String.replaceFirst method takes a regular expression which has special characters for certain operations - one of these characters is the^ character. You need to escape it to look for occurances of it (In Java, since backslash is special in strings, this would be "\\^" in the "replaceFirst" argument)

Jmeter value to variable in string

How do i replace a variable defined in a file (a.xml) after the file is read into Jmeter ?
eg. a.xml has a content.
<Shipment Action="MODIFY" OrderNo="${vOrderNo}" >
The entire file is read into a string using
str_Input=${__FileToString(/a.xml)}
In the Jmx file, a http Request is made to get output from a webservice as
Using Xpath Extractor the value of OrderNo is read into a Variable vOrderNo.
Now, wanted to use the value of variable vOrderNo in the str_Input.. ? How do i ?
You can easily achieve this using beanshell (~java) code from any jmeter's sampler which allows beanshell code execution - BeanShell Sampler e.g..
The following works:
import java.io.*;
try
{
// reading file into buffer
StringBuilder data = new StringBuilder();
BufferedReader in = new BufferedReader(new FileReader("d:\\test.xml"));
char[] buf = new char[1024];
int numRead = 0;
while ((numRead = in.read(buf)) != -1) {
data.append(buf, 0, numRead);
}
in.close();
// replacing stub with actual value
String vOrderNo = vars.get("vOrderNo");
String temp = data.toString().replaceAll("\\$\\{vOrderNo\\}", vOrderNo);
// writing back into file
Writer out = new BufferedWriter(new FileWriter("d:\\test.xml"));
out.write(temp);
out.close();
}
catch (Exception ex) {
IsSuccess = false;
log.error(ex.getMessage());
System.err.println(ex.getMessage());
}
catch (Throwable thex) {
System.err.println(thex.getMessage());
}
This code doesn't require read file into string via ${__FileToString(...)}.
As well, you can combine both methods.

Problems during counting strings in the txt file

I am developing a progam which reads a text file and creates a report. The content of the report is the following: the number of every string in file, its "status", and some symbols of every string beginning. It works well with file up to 100 Mb.
But when I run the program with input files which are bigger than 1,5Gb in size and contain more than 100000 lines, I get the following error:
> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
> at java.util.Arrays.copyOfRange(Unknown Source) at
> java.lang.String.<init>(Unknown Source) at
> java.lang.StringBuffer.toString(Unknown Source) at
> java.io.BufferedReader.readLine(Unknown Source) at
> java.io.BufferedReader.readLine(Unknown Source) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:771) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:723) at
> org.apache.commons.io.IOUtils.readLines(IOUtils.java:745) at
> org.apache.commons.io.FileUtils.readLines(FileUtils.java:1512) at
> org.apache.commons.io.FileUtils.readLines(FileUtils.java:1528) at
> org.apache.commons.io.ReadFileToListSample.main(ReadFileToListSample.java:43)
I increased VM arguments up to -Xms128m -Xmx1600m (in eclipse run configuration) but this did not help. Specialists from OTN forum advised me to read some books and improve my program's performance. Could anybody help me to improve it? Thank you.
code:
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.util.List;
public class ReadFileToList {
public static void main(String[] args) throws FileNotFoundException
{
File file_out = new File ("D:\\Docs\\test_out.txt");
FileOutputStream fos = new FileOutputStream(file_out);
PrintStream ps = new PrintStream (fos);
System.setOut (ps);
// Create a file object
File file = new File("D:\\Docs\\test_in.txt");
FileReader fr = null;
LineNumberReader lnr = null;
try {
// Here we read a file, sample.txt, using FileUtils
// class of commons-io. Using FileUtils.readLines()
// we can read file content line by line and return
// the result as a List of string.
List<String> contents = FileUtils.readLines(file);
//
// Iterate the result to print each line of the file.
fr = new FileReader(file);
lnr = new LineNumberReader(fr);
for (String line : contents)
{
String begin_line = line.substring(0, 38); // return 38 chars from the string
String begin_line_without_null = begin_line.replace("\u0000", " ");
String begin_line_without_null_spaces = begin_line_without_null.replaceAll(" +", " ");
int stringlenght = line.length();
line = lnr.readLine();
int line_num = lnr.getLineNumber();
String status;
// some correct length for if
int c_u_length_f = 12;
int c_ea_length_f = 13;
int c_a_length_f = 2130;
int c_u_length_e = 3430;
int c_ea_length_e = 1331;
int c_a_length_e = 442;
int h_ext = 6;
int t_ext = 6;
if ( stringlenght == c_u_length_f ||
stringlenght == c_ea_length_f ||
stringlenght == c_a_length_f ||
stringlenght == c_u_length_e ||
stringlenght == c_ea_length_e ||
stringlenght == c_a_length_e ||
stringlenght == h_ext ||
stringlenght == t_ext)
status = "ok";
else status = "fail";
System.out.println(+ line_num + stringlenght + status + begin_line_without_null_spaces);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Also specialists from OTN said that this programm opens the input and reading it twice. May be some mistakes in "for statement"? But I can't find it.
Thank you.
You're declaring variables inside the loop and doing a lot of uneeded work, including reading the file twice - not good for peformance either. You can use the line number reader to get the line number and the text and reuse the line variable (declared outside the loop). Here's a shortened version that does what you need. You'll need to complete the validLength method to check all the values since I included only the first couple of tests.
import java.io.*;
public class TestFile {
//a method to determine if the length is valid implemented outside the method that does the reading
private static String validLength(int length) {
if (length == 12 || length == 13 || length == 2130) //you can finish it
return "ok";
return "fail";
}
public static void main(String[] args) {
try {
LineNumberReader lnr = new LineNumberReader(new FileReader(args[0]));
BufferedWriter out = new BufferedWriter(new FileWriter(args[1]));
String line;
int length;
while (null != (line = lnr.readLine())) {
length = line.length();
line = line.substring(0,38);
line = line.replace("\u0000", " ");
line = line.replace("+", " ");
out.write( lnr.getLineNumber() + length + validLength(length) + line);
out.newLine();
}
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Call this as java TestFile D:\Docs\test_in.txt D:\Docs\test_in.txt or replace the args[0] and args[1] with the file names if you want to hard code them.

Resources