Trouble reading a file in java in a certain format - java

I am reading text from a file and I have been having trouble trying to read List 1 and List 2 into 2 different String . The * indicates where the first list ends. I have tried using arrays but the array only stores the last * symbol.
List 1
Name: Greg
Hobby 1: Swimming
Hobby 2: Football
*
List 2
Name: Bob
Hobby 1: Skydiving
*
Here's what I tried so far:
String s = "";
try{
Scanner scanner = new Scanner(new File("file.txt"));
while(scanner.hasnextLine()){
s = scanner.nextLine();
}
}catch(Exception e){
e.printStackTrace}
String [] array = s.split("*");
String x = array[0];
String y = array[1];

Your code has multiple issues like #Henry said that your string contains only the last line of the file and also you misunderstood the split() because it takes a RegularExpression as a parameter.
I would recommend you to use the following example because it works and is a lot faster than your approach.
Kick-Off example:
// create a buffered reader that reads from the file
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt")));
// create a new array to save the lists
ArrayList<String> lists = new ArrayList<>();
String list = ""; // initialize new empty list
String line; // initialize line variable
// read all lines until one becomes null (the end of the file)
while ((line = reader.readLine()) != null) {
// checks if the line only contains one *
if (line.matches("\\s*\\*\\s*")) {
// add the list to the array of lists
lists.add(list);
} else {
// add the current line to the list
list += line + "\r\n"; // add the line to the list plus a new line
}
}
Explanation
I'm going to explain special lines that are hard to understand again.
Looking at the first line:
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt")));
This line creates a BufferedReader that is nearly the same like a Scanner but it's a lot faster and hasn't as much methods as a Scanner. For this usage the BufferedReader is more than enough.
Then it takes an InputStreamReader as a parameter in the constructor. This is only to convert the following FileInputStream to a Reader.
Why should one do that? That's because an InputStream ≠ Reader. An InputStream returns the raw values and a Reader converts it to human readable characters. See the difference between InputStream and Reader.
Looking at the next line:
ArrayList<String> lists = new ArrayList<>();
Creates a variable array that has methods like add() and get(index). See the difference of arrays and lists.
And the last one:
list += line + "\r\n";
This line adds the line to the current list and adds a new line to it.
"\r\n" Are special characters. \r ends the current line and \n creates a new line.
You could also only use \n but adding \r in front of it is better because this supports more Os's like Linux can have problems with it when \r misses.
Related
Using BufferedReader to read Text File

Related

Read file using delimiter and add to array

I am trying to read from a text file that is in my project workspace then;
Create an object depending on the first element on the first line of the file
Set some variables within the object
Then add it to my arrayList
I seem to be reading the file ok but am struggling to create the different objects based off what the first element on each line in the text file is
Text file is like this
ul,1,gg,0,33.0
sl,2,hh,0,44.0
My expected result is to create an UltimateLanding object or StrongLanding object based on the first element in the text above file example
Disclaimer - I know the .equals is not correct to use in the IF statement, i've tried many ways to resolve this
My Code -
Edited -
It seems the program is now reading the file and correctly and adding to the array. However, it is only doing this for the first line in the file? There should be 2 objects created as there are 2 lines in the text file.
Scanner myFile = new Scanner(fr);
String line;
myFile.useDelimiter(",");
while (myFile.hasNext()) {
line = myFile.next();
if (line.equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(myFile.next()));
sl.setLandingDesc(myFile.next());
sl.setNumLandings(Integer.parseInt(myFile.next()));
sl.setCost(Double.parseDouble(myFile.next()));
landings.add(sl);
} else if (line.equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(myFile.next()));
ul.setLandingDesc(myFile.next());
ul.setNumLandings(Integer.parseInt(myFile.next()));
ul.setCost(Double.parseDouble(myFile.next()));
landings.add(ul);
}
}
TIA
There are multiple issues with your current code.
myFile.equals("sl") compares your Scanner object with a String. You would actually want to compare your read string line, not your Scanner object. So line.equals("sl").
nextLine() will read the whole line. So line will never be equal to "sl". You should split the line using your specified delimiter, then use the split parts to build your object. This way, you will not have to worry about newline in combination with next().
Currently, your evaluation of the read input is outside of the while loop, so you will read all the content of the file, but only evaluate the last line (currently). You should move the evaluation of the input and creation of your landing objects inside the while loop.
All suggestions implemented:
...
Scanner myFile = new Scanner(fr);
// no need to specify a delimiter, since you want to read line by line
String line;
String[] splitLine;
while (myFile.hasNextLine()) {
line = myFile.nextLine();
splitLine = line.split(","); // split the line by ","
if (splitLine[0].equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(splitLine[1]));
sl.setLandingDesc(splitLine[2]);
sl.setNumLandings(Integer.parseInt(splitLine[3]));
sl.setCost(Double.parseDouble(splitLine[4]));
landings.add(sl);
} else if (splitLine[0].equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(splitLine[1]));
ul.setLandingDesc(splitLine[2]);
ul.setNumLandings(Integer.parseInt(splitLine[3]));
ul.setCost(Double.parseDouble(splitLine[4]));
landings.add(ul);
}
}
...
However, if you don't want to read the contents line by line (due to whatever requirement you have), you can keep reading it via next(), but you have to specify the delimiter correctly:
...
Scanner myFile = new Scanner(fr);
String line; // variable naming could be improved, since it's not the line
myFile.useDelimiter(",|\\n"); // comma and newline as delimiters
while (myFile.hasNext()) {
line = myFile.next();
if (line.equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(myFile.next()));
sl.setLandingDesc(myFile.next());
sl.setNumLandings(Integer.parseInt(myFile.next()));
sl.setCost(Double.parseDouble(myFile.next()));
landings.add(sl);
} else if (line.equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(myFile.next()));
ul.setLandingDesc(myFile.next());
ul.setNumLandings(Integer.parseInt(myFile.next()));
ul.setCost(Double.parseDouble(myFile.next()));
landings.add(ul);
}
}
...
A solution.
List<Landing> landings = Files.lines(Paths.get("LandingsData.txt")).map(line -> {
String[] split = line.split(",");
if (split[0].equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(split[1]));
sl.setLandingDesc(split[2]);
sl.setNumLandings(split[3]);
sl.setCost(Double.parseDouble(split[4]));
return sl;
} else if (split[0].equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(split[1]));
ul.setLandingDesc(split[2]);
ul.setNumLandings(split[3]);
ul.setCost(Double.parseDouble(split[4]));
return ul;
}
return null;
}).filter(t -> t!= null).collect(Collectors.toList());

Writing to a text file at a specific position Java

Suppose I have a file called "Bill.txt".
The format:
ItemType ItemName Price
Now I want to add a new Description field. This description must be written next to the price.
The problem is, how to determine the position where to write it.
Yeah I agree with user2085282. You could read in the file using:
BufferedReader in = new BufferedReader(new FileReader("Bill.txt"));
For each line, the Reader reads, add like a semicolon or some character that should not be in the original file. Then in array split the string based on that character.
while ((line = in.readLine()) != null) {
//string = line + semicolon
// then set an array to split(;)
}
Then in another loop have like result += array[i] + description;
Then write the string in a new file

complete indexing of text file java

im trying to read a text file, sort the words within alphabetically and display what line numbers those words appear on.
Im new to java so not sure what the most efficient way to approach the system is.
My plan so far is to:
-use a scanner to parse file into one string
-string.split
-lineCount++
-(somehow sort those split strings alphabetically)
-print sorted words with line number next to them
Is that the best way of going about this? im not sure if java has some sort of ordered dictionary maybe i could use?
A Scanner is fine, as you could scan per word, not even needing a split.
A BufferedReader would be for line-wise reading, and there exists a LineNumberReader for your goal: counting lines.
I head indicate the encoding of the file.
SortedMap<String, SortedSet<Integer>> linenosPerWord = new TreeMap<>();
// A BufferedReader with a linenumber counter:
try (LineNumberReader in = new LineNumberReader(new InputStreamReader(
new FileInputSTream(file, StandardCharsets.UTF_8))) {
for (;;) {
String line = in.readLine();
if (line == null) {
break;
}
int lineno = in.getLineNumber();
String[] words = line.split("\\P{LM}"); // Split on non-letters and non-accents
for (String word : words) {
word = word.toLowerCase(); // Possible with Locale
SortedSet<Integer> linenos = linenosPerWord.get(word);
if (linenos == null) {
linenos = new TreeSet<>();
linenosPerWord.put(word, lineno);
}
linenos.add(lineno);
}
}
}
linenosPerWord.remove(""); // Remove a possibly found empty word, like in "-Hello"

Java StringBuffer: replace the content from a starting index to the end of a line

I have content of a file in a StringBuffer. The content of the file includes many lines (not on a single line). I want to edit the content of a line from index 4 (just for example) to the end of that line. I use replace() to edit the content of the StringBuffer.
The point is that the replace method has parameters such as starting index and ending index. But I don't know what is the ending index since each line have different number of characters
I think of using str.indexOf("\n") to find the ending index of the line, but then the file have many lines, so it will return incorrect results.
this is the readFile() if u need to read the code
Thank you
public StringBuffer readFile(){ //read file line by line
File f = getFilePath(fileName);
StringBuffer sb = new StringBuffer();
String textinLine;
try {
FileInputStream fs = new FileInputStream(f);
InputStreamReader in = new InputStreamReader(fs);
BufferedReader br = new BufferedReader(in);
while (true){
textinLine = br.readLine();
if (textinLine == null) break;
sb.append(textinLine+ "\n");
}
fs.close();
in.close();
br.close();
} ... // just some catch statements heres
}
Use String.indexOf() as you indicated, but pass in the starting position, e.g. indexOf('\n', 4);
I agree with Jim's idea, why not process string before appending it to StringBuffer.
By the way, I think you can use indexOf(String str, int fromIndex) function to parse StringBuffer, and each time when you get '\n', you can set an offset value, then next time when you get the next \n, you can just let index value plus the offset.

Counting Words and Newlines In A File Using Java?

I am writing a small java app which will scan a text file for any instances of particular word and need to have a feature whereby it can report that an instance of the word was found to be the 14th word in the file, on the third line, for example.
For this i tried to use the following code which i thought would check to see whether or not the input was a newline (\n) character and then incerement a line variable that i created:
FileInputStream fileStream = new FileInputStream("src/file.txt");
DataInputStream dataStream = new DataInputStream(fileStream);
BufferedReader buffRead = new BufferedReader(new InputStreamReader(dataStream));
String strLine;
String Sysnewline = System.getProperty("line.separator");
CharSequence newLines = Sysnewline;
int lines = 1;
while ((strLine = buffRead.readLine()) != null)
{
if(strLine.contains(newLines))
{
System.out.println("Line Found");
lines++;
}
}
System.out.println("Total Number Of Lines In File: " + lines);
This does not work for, it simply display 0 at the end of this file. I know the data is being placed into strLine during the while loop as if i change the code slightly to output the line, it is successfully getting each line from the file.
Would anyone happen to know the reason why the above code does not work?
Read the javadocs for readLine.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
readLine() strips newlines. Just increment every iteration of the loop. Also, you're overcomplicating your file reading code. Just do new BufferedReader(new FileReader("src/file.txt"))

Categories

Resources