"String.substring(int, int) line: not available" causes error - java

Somehow my if loop using a substring to check a .txt file is causing problems. Without the if loop, everything works fine. But with it, it seems that an empty line in the text file is causing it to crash. It is working until the first empty line in the file, and then I get this error. What could I do about that?
code:
public class S1_Blockchain extends ConsoleProgram {
public void init() {
setSize(400, 250);
setFont("Arial-bold-18");
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader("block_chain.txt"));
while((line = br.readLine()) != null){
if(line.substring(0,1).equals("T") || line.substring(0,1).equals("G")) {
System.out.println(line);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

You might want to also check empty string:
if( !line.trim().isEmpty() && (line.substring(0,1).equals("T") || line.substring(0,1).equals("G"))) { ... }
You then might also want to refactor the code to make it more readable:
public class S1_Blockchain extends ConsoleProgram {
public void init() {
setSize(400, 250);
setFont("Arial-bold-18");
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader("block_chain.txt"));
while((line = br.readLine()) != null){
if(shouldConsider(line)) {
System.out.println(line);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private boolean shouldConsider(String line){
return !line.trim().isEmpty()
&&
(line.substring(0,1).equals("T") || line.substring(0,1).equals("G"));
}

So you tested your first edge-case for empty string "" (unhappy path).
Next you can avoid effective empty cases by using trim() (remove surrounding white-spaces):
so spaced input like " Trouble Centered " becomes trimmed `"Trouble Centered" (so that starting with a "T" which could be wanted).
and blank lines like " " become empty string "" (which will break some tests)
br = new BufferedReader(new FileReader("block_chain.txt"));
while((line = br.readLine()) != null){
line = line.trim(); // remove white-spaces; blank line results as empty
if (line.isEmpty()) {
// might handle or ignore this case
}
firstChar = line.charAt(0); // expresses intend better than substring
if (Set.of('T', 'G').contains(firstChar) { // the Set improves readability for condition
System.out.println(line);
}
}
Alternatives for Testing Strings
A) separate tests:
could also test an empty (not even spaces) or blank (only spaces) with line.isBlank()
could also test the start of a string with line.startsWith("T")
B) all in one (your case):
with a regular expression catching all cases: line.matches("^\\s*(G|T)")

Besides checking if your String is null you also have to check if it is an empty String (""). You can check it as line.trim().legth() == 0; or line.isEmpty() but also there is Apache Utils called StringUtils. There there is a method isBlank(String str) that checks in one go if String is null or blank. That is what I would recommend

Related

How Can I Read 2 lines From txt File

Hey Guys My I am Dealing With This Issue
I Want To merge to line from txt file and show them in Arraylist
So My Code Is That And I Want To Skip The -- Line To Show in Arraylist..
private List getQuotes(){
List<String> quotes = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
InputStream open = getAssets().open("barish.txt");
bufferedReader = new BufferedReader(new InputStreamReader(open));
String line;
while ((line = bufferedReader.readLine()) != null) {
quotes.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return quotes;
}
[enter image description here][1]
txt File image is here
[1]: https://i.stack.imgur.com/AiI67.png
try to use replaceAll method then read the file as above
line = line.replaceAll("--"," ");
//to remove all "--" and replace it with a space
You could check if the line is not equal to -- before adding it to the quotes list.
if(line.equals("--") == false) {
quotes.add(line);
}
Edit: Combining the lines together
In order to combine the strings between the -- lines you could accumulate the quote into a string quoteLine between each --. So if the line is not a -- line then it will be appended to the string quoteLine. If it is a -- line then it will add the previously constructed quote to the array list and initialize quoteLine to an empty string to reset it.
String line;
String quoteLine = "";
while ((line = bufferedReader.readLine()) != null) {
if(line.equals("--") == false) {
quotes.add(quoteLine);
quoteLine = "";
} else {
quoteLine += line;
}
}
enter image description here
This is Txt File ..
This Is A Poetry App.. This 2 Lines Make 1 poetry
So I Want To Display every 2 lines together In My Recyclerlist View..
This The Example...
i Want To Display My Poetry Like This In Recycler View
enter image description here
I think perhaps you want something more like this:
public List<List<String>> getQuotes() {
List<List<String>> allQuotes = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
InputStream open = getAssets().open("barish.txt");
bufferedReader = new BufferedReader(new InputStreamReader(open));
String line;
ArrayList<String> quote = new ArrayList<>();
while ((line = bufferedReader.readLine()) != null) {
if (line.equals("--")) {
if (!quote.isEmpty()) {
allQuotes.add(quote);
}
quote = new ArrayList<>();
} else {
quote.add(line);
}
}
if (!quote.isEmpty()) {
allQuotes.add(quote);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return allQuotes;
}
The result is a List<List<String>>: a list of poems, with each poem in its own List<String>.
You can do something like this:
public static List<List<String>> getQuotes(String file) {
List<List<String>> allQuotes = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
// Let's have a queue backed by LinkedList to keep the two
// lines just before the next line that is '--'.
Queue<String> quotes = new LinkedList<String>();
String line;
while ((line = br.readLine()) != null) {
// If the current line starts with -- and the two previous lines persisted
// in the quotes queue to allQuotes and clear the quotes. You can do an equals
// check here if you're certain about no leading and trailing white spaces in
// each line and it is always --.
if (line.trim().startsWith("--")) {
// Don't add quotes to allQuotes when quotes queue is empty.
// You can also check quotes.size() == 2 along with !quotes.isEmpty()
// if you want to always have at least two quotes in each sub-list retuned.
if (!quotes.isEmpty()) {
allQuotes.add(new ArrayList(quotes));
quotes.clear();
}
} else if (!line.trim().isEmpty()) {
// Add each line into the quotes queue if it is not blank
// or if it is not --
quotes.add(line);
}
// If the size of queue is > 2 remove an item from from the front,
// because we are only interested in two lines before --
if (quotes.size() > 2) {
quotes.remove();
}
}
} catch (Exception e) {
e.printStackTrace(); // TODO: Handle exceptions
return null;
}
return allQuotes;
}

Java print specific data from file

I've a txt file. In there are rules and I have to get everything between the brackets in a separate file. But I don't even get it shown in the console.
I already tried many methods, but i always get some errors.(outlined code)
With the solution right now, it just showing nothing in the console. Does anyone know why?
The brackets are always in the same line as "InputParameters" i tried something with that, at the end of the code.
The solutions that are outlined won't work. Maybe someone got an idea?
with that code below i get the following error :
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1 at java.lang.String.substring(Unknown
Source) at blabla.execute.main(execute.java:17)
here some content from the txt file:
dialect "mvel"
rule "xxx"
when
InputParameters (xy <= 1.124214, xyz <= 4.214214, abc <= 1.12421, khg <= 1.21421)
then
Ty
Here is the code:
public class execute {
public static void main(String[] args) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("C:..."));
java.lang.String line;
line = br.readLine();
while ((line = br.readLine()) != null) {
System.out.println(line.substring(line.indexOf(("\\("), line.indexOf(("\\)")))));
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1 at java.lang.String.substring(Unknown
Source) at blabla.execute.main(execute.java:17)
This exception means that -1 was passed to substring() method. This -1 is produced by indexOf() when it doesn't find anything.
Does all your lines contain brackets? There should be check if the brackets are present in the line.
while ((line = br.readLine()) != null) {
if(line.indexOf(("\\(") != -1 && line.indexOf(("\\)") != -1) {
System.out.println(line.substring(line.indexOf(("\\("), line.indexOf(("\\)")))));
}
}
the problem is if you want to get the index of a string (indexOf()) in a string in which the searched string doesnt exist, indexOf returns -1 and if the method substring receives the argument -1 then it throws a StringIndexOutOfBoundsException. I suggest to check first if a line contains "InputParameter" since you said this word is always in the same line and then you get the string inside the brackets by using the methods subtring and indexOf.
this one works for me
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileRead {
public static void main(String[] args) {
final String filename = "$insertPathToFile$";
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
String line = br.readLine();
while(line != null){
if (line.contains("InputParameters")) {
System.out.println(line.substring(line.indexOf("(")+1, line.indexOf(")")));
} // end if
line = br.readLine();
} // end while
} catch (Exception e) {
// TODO: handle exception
} finally {
try {
br.close();
} catch (IOException e) {}
} // end try
} // end main
} // end class

How to use conditional statement or contains method in a text file?

I have a java program that can read multiple files and replace values accordingly. However, I am struggling to apply a condition to it and apply the changes only when a certain condition is met. For example, if the file contains this specific character ':20:' then apply the changes otherwise leave the text file as it is.
The problem here is, since I don't have fields to look for to apply the condition accordingly I don't know how these can be applied to such a text file which contains just data like : (12345555555) 233344 100 :20:aaa.
I also looked at using the contains() method to look into the file to find the value I want then apply the changes but couldn't make it work.
public class TextFm
{
public static void main(String[] args)
{
File folder = new File("C:\\tmp");
File[] listOfFiles = folder.listFiles();
for(File file : listOfFiles)
{
replaceText(file);
}
}
public static void replaceText(File file)
{
try
{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "", oldtext = "";
while ((line = reader.readLine()) != null)
{
oldtext = oldtext + line + System.lineSeparator();
}
reader.close();
String replacedtext = oldtext.replaceAll("100", "200");
FileWriter writer = new FileWriter(file);
writer.write(replacedtext);
writer.close();
System.out.println("Done");
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
Using contains() method will work fine in this case. You can do that like this:
String line = "", oldtext = "";
while ((line = reader.readLine()) != null)
{
oldtext = oldtext + line + System.lineSeparator();
}
reader.close();
if(oldtext.contains(":20:")) {
String replacedtext = oldtext.replaceAll("100", "200");
FileWriter writer = new FileWriter(file);
writer.write(replacedtext);
writer.close();
System.out.println("Done");
}
public static void replaceText(File file)
{
try
{
Charset charset = Charsets.defaulCharset();
String oldText = new String(Files.readAllBytes(file.toPath()),
charset);
if (!oldText.contains(":20")) {
return;
}
if (!oldText.matches("(?s).*you (idiot|unspeakable).*")) {
return;
}
String replacedtext = oldtext.replace("100", "200");
replacedtext = replacedtext .replaceAll("\\d", "X"); // Digit X-ed out
if (!replacedText.equals(oldText)) {
Files.write(file.toPath(), replacedText.getBytes(charset));
}
System.out.println("Done");
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
For speed one should not collect the file contents with a String and +. Better use a StringBuilder, or the very nice Files class.
Finding text goes either by contains or by a regular expression match.
Replacement can be done by either too.
The replace, replaceFirst and replaceAll methods return the original string when nothing could be replaced.
Regex (?s) lets . (=any char) also match line breaks.

How to read the first element/term of a line in Java?

My aim is to read the first element/term of each line from a given input file and then decide what to do (using an if-else construct) depending on what that first element is. I.e. if the first element/word happens to be "the" (as mentioned in the code below), then I have to skip that line and move to the next line.
I have written the following code till now but I am not sure on how to read only the first element of each line of the text file that I am passing as input.
public static void main(String[] args) {
BufferedReader br = null;
try {
String line;
br = new BufferedReader(new FileReader("input.txt"));
while ((line = br.readLine()) != null) {
System.out.println(line);
StringTokenizer stringTokenizer = new StringTokenizer(line, " ");
while (stringTokenizer.hasMoreTokens()) {
String term = stringTokenizer.nextElement().toString();
if (term.equals("the")) {
//Code on what to do depending on the first character of each line.
}
StringBuilder sb = new StringBuilder();
System.out.println(sb.toString());
}
}
System.out.println("Done!");
}
catch (IOException e)
{
e.printStackTrace();
}
finally {
try {
if (br != null)
br.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}
Below is the simple code that prints the as the output. you can use this and no need to create an extra array or use StringTokenizer.
String s = "The a an the abcdef.";
System.out.println(s.contains(" ") ? s.substring(0, s.indexOf(" ")) : s);
You can turn each term into an array of words via:
while((line = br.readLine()) != null){
System.out.println(line);
String word = line.split("\\s+")[0];
if(word.equals("the")){
//Code on what to do depending on the first character of each line.
}
StringBuilder sb = new StringBuilder();
System.out.println(sb.toString());
}
...
but I am not sure on how to read only the first element of each line of the text file that I am passing as input.
There are a couple of different solutions depending on your exact requirement.
You can read the entire line of data and then use the String.startsWith(...) method to test for the first word. Using this approach you don't tokenize all the data if you just want to skip the rest of the line. Then if you want to continue processing you can use the String.substring(...) method to get the rest of the data from the line.
You can use the Scanner class. The Scanner allows you to tokenize the input as you read the data from the file. So you can read the first word and then determine whether to skip the rest of the data or read the rest of the line.
StringTokenizer is considered as legacy class. It is only there for backward compatibility. Use split() on string to split the single string into array of strings/words.
String[] s = line.readLine().split(" ");
String firstWord = s[0]; // ->First word
So your code can be edited to
public static void main(String[] args)
{
BufferedReader br = null;
try
{
String line;
br = new BufferedReader(new FileReader("input.txt"));
while((line = br.readLine()) != null)
{
System.out.println(line);
String s = line.split(" "); // instead of StringTokenizer
if(s[0].equals("the"))
{
//Code on what to do depending on the first character of each line.
}
StringBuilder sb = new StringBuilder();
System.out.println(sb.toString());
}
System.out.println("Done!");
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)
br.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
Note:
Don't use startsWith(...) to check for the first word because it checks by character-wise instead of word-wise. If you want to check for the word the then the words there,their also returns true which might break your code.
Try to use split() instead of StringTokenizer from now onwards.

Why is this BufferedReader returning empty String instead of null?

I have a BufferedReader iterating through the lines of a CSV file; when it gets to the end of the file, it returns the following error:
Exception in thread "main" java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:992)
How do I get the reader to realize it reached the end of file and input is null instead of empty? I've checked the file and there is no whitespace at the end of the last line.
Code:
File filReadMe = new File(inputFile);
BufferedReader brReadMe = new BufferedReader(new InputStreamReader(new FileInputStream(filReadMe), "UTF-8"));
try
{
String strLine;
while ((strLine = brReadMe.readLine()) != null)
{
System.out.println(strLine);
//place the line into CsvRecordFactory
int record = csv.processLine(strLine, input);
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
//Close the BufferedReader
try {
if (brReadMe != null)
brReadMe.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
You can simply modify your code this way:
while ((strLine = brReadMe.readLine()) != null)
{
if (!strLine.isEmpty()) {
System.out.println(strLine);
//place the line into CsvRecordFactory
int record = csv.processLine(strLine, input);
}
}
This way, your code will ignore all empty lines, not only those at the end of your file.
The problem isn't the end of file. The problem is that you are processing a blank line as though it wasn't blank. That could conceivably happen anywhere, not just as a final line before EOF. Check the line for emptiness before you start parsing it.
if the end of your file is a newline, try backspacing it to the end of the previous line and see if you still get the error
Try to give it a small if condition to check whether the string is empty or not.
Version 1: Check if string is empty
while ((strLine = brReadMe.readLine()) != null)
{
if(!strLine.isEmpty()){
System.out.println(strLine);
//place the line into CsvRecordFactory
int record = csv.processLine(strLine, input);
}
}
I also have version 2 of code, which checks if string is number otherwise if they are characters or empty or anything else, the code inside if is going be ignored
while ((strLine = brReadMe.readLine()) != null)
{
if(strLine.matches("\\d+")){
System.out.println(strLine);
//place the line into CsvRecordFactory
int record = csv.processLine(strLine, input);
}
}

Categories