Buffered Reader find specific line separator char then read that line - java

My program needs to read from a multi-lined .ini file, I've got it to the point it reads every line that start with a # and prints it. But i only want to to record the value after the = sign. here's what the file should look like:
#music=true
#Volume=100
#Full-Screen=false
#Update=true
this is what i want it to print:
true
100
false
true
this is my code i'm currently using:
#SuppressWarnings("resource")
public void getSettings() {
try {
BufferedReader br = new BufferedReader(new FileReader(new File("FileIO Plug-Ins/Game/game.ini")));
String input = "";
String output = "";
while ((input = br.readLine()) != null) {
String temp = input.trim();
temp = temp.replaceAll("#", "");
temp = temp.replaceAll("[*=]", "");
output += temp + "\n";
}
System.out.println(output);
}catch (IOException ex) {}
}
I'm not sure if replaceAll("[*=]", ""); truly means anything at all or if it's just searching for all for of those chars. Any help is appreciated!

Try following:
if (temp.startsWith("#")){
String[] splitted = temp.split("=");
output += splitted[1] + "\n";
}
Explanation:
To process lines only starting with desired character use String#startsWith method. When you have string to extract values from, String#split will split given text with character you give as method argument. So in your case, text before = character will be in array at position 0, text you want to print will be at position 1.
Also note, that if your file contains many lines starting with #, it should be wise not to concatenate strings together, but use StringBuilder / StringBuffer to add strings together.
Hope it helps.

Better use a StringBuffer instead of using += with a String as shown below. Also, avoid declaring variables inside loop. Please see how I've done it outside the loop. It's the best practice as far as I know.
StringBuffer outputBuffer = new StringBuffer();
String[] fields;
String temp;
while((input = br.readLine()) != null)
{
temp = input.trim();
if(temp.startsWith("#"))
{
fields = temp.split("=");
outputBuffer.append(fields[1] + "\n");
}
}

Related

Java using \034 as delimiter in a string

I am trying to use '\034' field separator character as a delimiter in a string.
The issue is when I hardcode "\034"+opField and write it to a file it works, but if the "\034" character is read from a file, it writes the output as string "col1\034col2'.
I tried using StringBuilder but it escapes the \034 to "\\034".
I am using the following code to read the character from the file:
try (BufferedReader br = new BufferedReader(new FileReader(fConfig))){
int lc = 1;
for(String line;(line = br.readLine())!=null;){
String[] rowList = line.split(delim);
int row_len = rowList.length;
if (row_len<2){
System.out.println("Incorrect dictionary file row:"+fConfig.getAbsolutePath()+"\nNot enough values found at row:"+line);
}else{
String key = rowList[0];
String value = rowList[1];
dictKV.put(key, value);
}
lc++;
}
}catch(Exception e){
throw e;
}
Any help is welcome...
[update]: The same thing is happening with '\t' character, if harcoded fine, but if read from a file its getting appended as characters. "col0\tcol1"
if(colAl.toLowerCase().contains(" as ")){
String temp = colAl.replaceAll("[ ]+as[ ]+"," | ");
ArrayList<String> tempA = this.brittle_delim(temp,'|');
colAl = tempA.get(tempA.size()-1);
colAl = colAl.trim();
}else {
ArrayList<String> tempA = this.brittle_delim(colAl,' ');
colAl = tempA.get(tempA.size()-1);
colAl = colAl.trim();
}
if(i==0){
sb.append(colAl);
headerCols+=colAl.trim();
}else{
headerCols+= this.output_field_delim + colAl;
sb.append(this.output_field_delim);
sb.append(colAl);
}
}
}
System.out.println("SB Header Cols:"+sb.toString());
System.out.println("Header Cols:"+headerCols);
Output:
SB Header Cols:
SPRN_CO_ID\034FISC_YR_MTH_DSPLY_CD\034CST_OBJ_CD\034PRFT_CTR_CD\034LEGL_CO_CD\034HEAD_CT_TYPE_ID\034FIN_OWN_CD\034FUNC_AREA_CD\034HEAD_CT_NR
Header Cols:
SPRN_CO_ID\034FISC_YR_MTH_DSPLY_CD\034CST_OBJ_CD\034PRFT_CTR_CD\034LEGL_CO_CD\034HEAD_CT_TYPE_ID\034FIN_OWN_CD\034FUNC_AREA_CD\034HEAD_CT_NR
In the above code if I do the following I am getting correct results:
headerCols+= "\034"+ colAl;
output:
SPRN_CO_IDFISC_YR_MTH_DSPLY_CDCST_OBJ_CDPRFT_CTR_CDLEGL_CO_CDHEAD_CT_TYPE_IDFIN_OWN_CDFUNC_AREA_CDHEAD_CT_NR
The FS characters are there even if they are geting removed here
You should provide an example demonstrating your problem. Not just incomplete code snippets.
Following runable snippet does what you explained.
// create a file one line
byte[] bytes = "foo bar".getBytes(StandardCharsets.ISO_8859_1);
String fileName = "/tmp/foobar";
Files.write(Paths.get(fileName), bytes);
String headerCols = "";
String outputFieldDelim = "\034";
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
// read the line from the file and split by blank character
String[] cols = br.readLine().split(" ");
// contcatenate the values with "\034"
// but ... for your code ...
// don't concatenate String objects in a loop like below
// use a StringBuilder or StringJoiner instead
headerCols += outputFieldDelim + cols[0];
headerCols += outputFieldDelim + cols[1];
}
// output with the "\034" character
System.out.println(headerCols);
I guess this is where I found my solution and the actual words for my Question.
How to unescape string literals in java

How to replace a specific character in a text file by giving the index value?

Came across this code which replaces all the characters of the given value.
File temp = File.createTempFile("newfile", ".txt");
FileWriter fw = new FileWriter(temp);
Reader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader);
while (br.ready()) {
fw.write(br.readLine().replaceAll("n", "j") + "\n");
}
fw.close();
br.close();
reader.close();
temp.renameTo(file);
}
instead of replacing all 'n's with 'j's isn't there a way to specify the index I want to change only?
You can use replaceFirst (that accepts a regex), using the following pattern:
(?<=.{N-1}).
Where "N" is the index you want to replace.
Of course there are many alternatives, look at the String API to fuel your creative fire.
The line within the while statement as follows:
fw.write(br.readLine().replaceAll("n", "j") + "\n");
This can be expanded to:
String str = br.readLine(); //get text
String replace = str.replaceAll("n", "j"); //replace content
replace = replace + "\n"; //add new line
fw.write(replace); //write to file
For your instance of replacing a certain index, you would want to do something similar:
StringBuilder str = new StringBuilder(br.readLine()); //Read line into StringBuilder
if(str.length() > 3) //Check if string is long enough
str.setChar(4, 'x'); //Replace character in line at index 4 to 'x'
fw.write(str); //write to file

String comparison not breaking out of a while loop

I am trying these lines:
private String line;
private final String stopChr= "#";
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
while ((line = in.readLine()) != null) {
tcpData = tcpData + line;
if(line.equals(stopChr)) break;
}
Why is the if statement not breaking out of the loop when # is present?
Most likely the line is not exactly "#" for example it might have a space after it. I suggest you look at what the line is in your debugger or in an editor to see exactly what characters the String has.
Try printing the following to help see what the string is actually.
System.out.println(Arrays.toString(line.toCharArray());
If you have trailing spaces you can drop these with trim
if (line.trim().equals(stopChar)) break;
If the string contains other characters, as in your example input $353323058181636,EV,D,T,567888.9,+12C,FFFFE000# (from your comment on #PeterLawrey's answer), use the following instead of String.equals:
if(line.contains(stopChr)) break;
If it specifically ends with the stop character, you can alternatively use:
if(line.endsWith(stopChr)) break;
The following code is working :
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = "";
String data = "";
while ((line = br.readLine()) != null) {
data += line;
if (line.contains("#"))
break;
}
Also, instead of contains() you can use endsWith() to check for end of file.
You make take help.
for getting everything before the #
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = "";
String data = "";
while (true)
{
line = br.readLine();
// break if terminated
if (line==null)
break;
// Check : for debugging only
System.err.println("LINE : "+line);
// break if #
if (line.contains("#"))
{
// Get first part, part after, we dont care
int first=line.indexOf('#');
data+=line.substring(0, first);
break;
}
else
data += line;
}
// See the result
System.out.println("DATA:"+data);
The problem solved. readLine() function need end of string character <CR>. Just replacing "#" to "\n" solved the problem. Thanks to all great team.
you will never get null if the inputstream is from socket. Instead, the readLine() method will block until you get new data.

how can i use split() with a big number of elements, java

I need to process a big text file, there are almost 400 column in each line, and almost 800000 lines in the file, the format of each line in the file is like:
340,9,2,3........5,2,LA
what I want to do is, for each line, if the last column is LA, then print the first column of this line.
i write a simple program to do it
BufferedReader bufr = new BufferedReader(new FileReader ("A.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter ("LA.txt"));
String line = null;
while ((line = bufr.readLine()) != null) {
String [] text = new String [388];
text = line.split(",");
if (text [387] == args[2]) {
bufw.write(text[0]);
bufw.newLine();
bufw.flush();
}
}
bufw.close();
bufr.close();
but it seems the length of an array cant be that big, i received a java.lang.ArrayIndexOutOfBoundsException
since i'm using split(",") in order to get the last column of a line, and it will be out of array bounds, how can I do with it? thanks.
text does not need to be initialized, String.split will create a correctly sized array:
String[] text = line.split(",");
You're also comparing Strings using reference equality (==). You should be using .equals():
if (text[387].equals(args[2])) { ... }
You're probably getting java.lang.ArrayIndexOutOfBoundsException because the the index 387 is too big. If you want to get last element, use this:
text[text.length - 1]
Modify and try this
String [] text = line.split(",");
if (text [text.length - 1].equals(args[2])) {
bufw.write(text[0]);
bufw.newLine();
bufw.flush();
}
Assuming args[2] is LA.
String [] text;
Change your code to this. You don't need to initialize a size. When the String.split method executes it will automatically initialize the correct size for your array.
If you just need the first and the last column, then there is no need to create an array out of the current line.
You could do something like this:
final String test = "340,9,2,354,63,5,5,45,634,5,5,2,LA";
final char delimiter = ',';
final String lastColumn = test.substring(test.lastIndexOf(delimiter) + 1);
if (lastColumn.equals("LA")) {
final String firstColumn = test.substring(0, test.indexOf(delimiter));
System.out.println(firstColumn);
}
This code extracts the last column first and tests it. If it matches "LA", then it extract the first column. It will ignore the remaining content of the line.
Your code would be:
BufferedReader bufr = new BufferedReader(new FileReader ("A.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter ("LA.txt"));
String line = null;
while ((line = bufr.readLine()) != null) {
final String lastColumn = line.substring(line.lastIndexOf(delimiter) + 1);
if (lastColumn.equals(args[2])) {
bufw.write(line.substring(0, line.indexOf(delimiter)));
bufw.newLine();
bufw.flush();
}
}
bufw.close();
bufr.close();
(this code is not tested yet, but you get the idea :))

Reading from text area by line and assigning variables

I need to append variables to each line of text from a TextArea. The TextArea is coded, and works perfectly. I can retrieve information from the TextArea by using TextArea.getText();
To break it apart, I am trying to use a BufferedReader. Unfortunately, this does not work. Is there a different way of doing this? Here is an example of how the information needs to be written in the text area:
"workerName"
"workerDepartment"
"workerNumber"
BufferedReader inStream= new BufferedReader
(new InputStreamReader(TextArea.getText()));
String workerName = "";
String workerDepartment = "";
int workerNumber = 0;
String line = inStream.readLine();
while (line != null) {
workerName = line;
line = inStream.readLine();
workerDepartment = line;
line = inStream.readLine();
workerNumber = Integer.parseInt(line);
}
inStream.close();
if the lines are separated by any delimiter(for example newline, comma...) , then use split method of String and put the delimiter
String[] lines = TextArea.getText().split("\n");
//then you can access your array
String workerName = lines[0];
String workerDepartment = lines[1];
// and so on
Also you need to check array size before getting the value to prevent ArrayOutOfIndexException, for example if there are two lines only then you should not call lines[2], so do the check:
if ( lines.length < 3 ) {
// input is not complete, show error message
}
else {
// do your splitting and reading values
}

Categories