I am currently building an application that is extracting values from a text file inside a project. Somehow managed extract data from specific lines but don't seem to get the right one.
Here is the code:
private String getInputsFromATextFile(int item) throws FileNotFoundException {
InputStream is = this.getResources().openRawResource(R.drawable.input);
StringBuilder builder = new StringBuilder();
int lineNo = 0;
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null){
lineNo++;
if(lineNo == item){
builder.append(reader.readLine());
}
}
reader.close();
}
catch (IOException e){
e.printStackTrace();
}
return builder.toString();
}
And here are the text file contents:
20.45
21.65
1
225
4102
401
3
3
6
1
196.41
64.11
7
3
5
2
144.01
3
452.33
12
701.33
33
78.12
12
123.90
4
25.00
10
6.51
30.98
2.50
Spiderman
100.00
90
150.00
100
10
34
12
James
1267
Joshue
401
Christelle
3050
Ryan
888
Hanna
5
13
24
9
5
3
50
Suppose we assign a certain line number in a parameter. This method returns the exact next data from which the line number is assigned. Although, maybe I can adjust to the output that it always returns (lineNo + 1), but if in case I assigned '0' (zero) in the parameter, it instead returns null. Why is that so? I must be missing something really important.
That's because you're reading the line again in the statement builder.append(reader.readLine()).
Notice that you've already read it in while loop.
So, the correct statement would be:
builder.append(line);
Don't read it again when appending it. Use :
builder.append(line);
Also, if you want it to be 0 indexed, you should increment lineno after comparing it.
if(lineno == item)
{
}
lineno ++;
If you do it before comparision, it will never be 0 and hence returns a null .
Is that optimal?
If it just a one time retireval Yes.
If you use it again and again - No, everytime you want data from the line, you need to traverse the whole file till that line.
One way you can do is to store it in an ArrayList.
InputStream is = this.getResources().openRawResource(R.drawable.input);
ArrayList<String> list = new ArrayList();
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null){
list.add(line);
}
reader.close();
}
catch (IOException e){
e.printStackTrace();
}
getLineFromFile(list, 10);
Store all the strings in an arrayList and then retrieve them.
public String getLineFromFile(ArrayList<String> list, int lineNo);
{
return list.get(lineNo - 1);
}
Related
I want to read the data from text, then I will remove the header of the text and save the data into and array every 2 line, cause it still continues data.
visitor.txt
1 DAILY REPORT VISITOR
DATE : 02-02-22
0+------------------------------------------------------------------+
NO. DATE NAME ADDRESS
PHONE BIRTHDAY NEED
+------------------------------------------------------------------+
1 02-02-22 ELIZABETH ZEE WASHINGTON DC
+32 62 18-10-1985 BORROW BOOK
2 02-02-22 VICTORIA GEA BRUSEELS
+32 64 24-05-1986 VISITOR
3 02-02-22 GEORGE PHILIPS BRUSEELS
+32 76 02-05-1990 VISITOR
I want the data that save into an array like this.
1 02-02-22 ELIZABETH ZEE WASHINGTON DC +32 62 18-10-1985 BORROW BOOK
2 02-02-22 VICTORIA GEA BRUSEELS +32 64 24-05-1986 VISITOR
3 02-02-22 GEORGE PHILIPS BRUSEELS +32 76 02-05-1990 VISITOR
This is the code
BufferedReader bR = new BufferedReader(new FileReader(myfile));
int i =0;
String line;
try {
while (line = bufferedReader.readLine()) != null) {
i++;
String data = line.split("\\s", "")
if(data.matches("[0-9]{1,3}\\s.+")) {
String[] dataArray = data.split("\\s", -1);
String[] result = new String[30];
System.arraycopy(fileArray, 0, result, 0, fileArray.length);
String data1 = line.get(i).split("\\s", "")
String[] fileArray1 = data.split("\\s", -1);
String[] result1 = new String[30];
System.arraycopy(fileArray1, 0, result1,0,fileArray1.length);
}
}
The problem here is, I think this code is not effective cause it will be read the second line twice from data and data1. I want every 2 lines will save into one row in the database like the result of text. Do you have any solution?
It seems unlikely for me that one line would be read multiple times. Try to debug your code to see if that actually happens.
Otherwise, you could really skip the first line before starting processing:
BufferedReader bR = new BufferedReader(new FileReader(myfile));
int i =0;
String line;
try {
// alternative one
String firstline = bufferedReader.readLine();
String secondline = bufferedReader.readLine();
String mergedline = firstline + secondline; // the linefeed should have been removed but the data is retained
// alternative two
StringBuilder sb = new StringBuilder();
sb.append(bufferedReader.readLine()); // first line
sb.append(bufferedReader.readLine()); // second line
... = sb.toString(); // now do something with the merged lines
// the other stuff
while (line = bufferedReader.readLine()) != null) {
// process your data lines here
}
}
The result has actually a dynamic number of records. Then a fixed size array
no longer is suitable. Use List<String\[\]> instead: list.add(stringArray), list.get(i), list.size(), list.isEmpty().
The header seems to consist of 2 lines, but I may err.
I saw fields with a space, hence one cannot split on \s+ (one or more whitespace characters). I did split on \s\s+. Maybe you should better use the fixed length field boundaries with line1.substring(i1, i2).
FileReader uses the encoding on your current computer (=unportable file). I have made it explicit. If it always an US-ASCII file, without special characters, you could use StandardCharsets.US_ASCII. Then you can run the software on a Linux server, that normally uses UTF-8.
So without check of data format (which however makes sense):
private void stackOverflow() throws IOException {
List<String[]> data = loadData("mydata.txt");
System.out.println(data.size() + " records read");
for (String[] fields: data) {
System.out.println(Arrays.toString(fields));
}
}
private List<String[]> loadData(String myFile) throws IOException {
List<String[]> data = new ArrayList<>();
Path path = Paths.get(myFile);
try (BufferedReader bufferedReader =
Files.newBufferedReader(path, Charset.defaultCharset())) {
if (bufferedReader.readLine() != null
&& bufferedReader.readLine() != null) { // Skip both header lines.
String line1, line2;
while ((line1 = bufferedReader.readLine()) != null
&& (line2 = bufferedReader.readLine()) != null) {
String[] fields1 = line1.split("\\s\\s+", 4); // Split on at least 2 spaces.
if (fields1.length != 4) {
throw new IOException("Wrong number of fields for first line: " + line1);
}
String[] fields2 = line2.split("\\s\\s+", 3); // Split on at least 2 spaces.
if (fields1.length != 3) {
throw new IOException("Wrong number of fields for second line: " + line2);
}
String[] total = Arrays.copyOf(fields1, 7);
System.arraycopy(fields2, 0, total, 4, fields2.length);
;
data.add(total);
}
if (line1 != null && !line1.isBlank()) {
throw new IOException("Trailing single line: " + line1);
}
}
}
return data;
}
Substring is better, safer, than split.
Instead of String[] you might use record class (since java 14)
record Visitor(String no, String date, String name, String address,
String phone, String birthday, String need) { }
List<Visitor> data = new ArrayList<>();
data.add(new Visitor(fields1[0], fields1[1], fields1[2], fields1[3],
fields2[0], fields2[1], fields2[2]);
A record need little code, however cannot be changed, only replaced in the list.
im a new coder here.
My program in a nutshell: Im working on a fantasy football trade calculator using player values to understand what would be a good trade.
My problem: I am able read from my file, count the positions however unable to add my string to my array of playNames. I get null, please look at my iteration in the for loop line. I am curious to why im getting a null value? Any Idea on a fix?
Thank you, Sincerely
*Java Noob
String filename="C:\\Users\\Karanvir\\Desktop\\21days\\players.txt";
File filez=new File(filename);
BufferedReader br;
String[] playerNames = null;
int counterOfReadLines=0;
try {
br = new BufferedReader(new FileReader(filez));
System.out.println(br.readLine());
counterOfReadLines=counterOfReadLines+1;
while(br.readLine() != null){
System.out.println(br.readLine());
counterOfReadLines=counterOfReadLines+1;
playerNames=new String[counterOfReadLines];
}
for(int i=0;i<playerNames.length;i++){
playerNames[i]=br.readLine();
}
br.close();
Rob Gronkowski 48
Zach Ertz 34
Travis Kelce 29
Evan Engram 15
Jimmy Graham 12
Cameron Brate 10
Delanie Walker 9
Kyle Rudolph 6
Austin Seferian-Jenkins 6
Jack Doyle 6
Hunter Henry 5
while(br.readLine() != null){
System.out.println(br.readLine());
counterOfReadLines=counterOfReadLines+1;
playerNames=new String[counterOfReadLines];
}
for(int i=0;i<playerNames.length;i++){
playerNames[i]=br.readLine();
}
This just doesn't work at all:
while(br.readLine() != null){
is reading a line, checking if it is null, then discarding it.
System.out.println(br.readLine());
is reading another line, printing it, then discarding it.
playerNames=new String[counterOfReadLines];
is creating a new array, filled with nulls.
You never put anything into the array.
Now:
for(int i=0;i<playerNames.length;i++){
playerNames[i]=br.readLine();
}
OK, so you go back and try to read the right number of items from the BufferedReader. However, the reason you stopped the previous loop is because br.readLine() returned null, and that's because you reached the end of the stream.
You've already read all the data there is to be read here, so you just read a null on each iteration, and put that into the array element (which already is already set to null).
Instead, use a List<String>, which can grow - arrays cannot - and put items into that:
List<String> playerNames = new ArrayList<>();
String line;
// This reads a line, and stores it in a variable, so you can use
// the String you read inside the loop body.
while ((line = br.readLine()) != null) {
System.out.println(line);
// Don't need counterOfReadLines, just use playerNames.size().
playerNames.add(line);
}
The normal usage of readLine is:
List<String> lines = new ArrayList<>();
for (;;) {
String line = br.readLine();
if (line == null) { // End of input reached.
break;
}
System.out.println(line);
lines.add(line);
}
for (String line : lines) {
System.out.println(line);
}
Arrays do not grow, so better use an ArrayList.
My TAB-delimited input file has 1 million lines, it looks like this:
id name artist_name genre notoriete_fr notoriete_us notoriete_uk notoriete_it notoriete_sp notoriete_no notoriete_de notoriete_wd
1 10ème bougie 113 rap 0 -5 -5 -5 -5 -5 -5 -5
2 I'm not in love 10cc pop 1 1 1 1 1 1 1 1
5 Generation Black Rebel Motorcycle Club rock 0 0 0 0 0 0 0 0
I've coded a file format transformation, and the output file to looks like this:
id:ID;genre;notoriete_fr:int;notoriete_us:int;notoriete_uk:int;notoriete_sp:int;notoriete_de:int;notoriete_it:int;notoriete_no:int;notoriete_wd:int;:LABEL
t1;rap;0;-5;-5;-5;-5;-5;-5;-5;Track
t5;rock;0;0;0;0;0;0;0;0;Track
I have two problems:
the output file only has 50% of input file lines
the output file has missing lines, e.g. t2's line is missing
Here's my code, thanks in advance!
Note: I've also added a buffer size to new BufferedWriter()/Reader(), no impact.
public static void main(String[] args) throws Exception {
BufferedReader br = null;
BufferedWriter bw = null;
try{
// prepare input file
File inFile = new File(inputFile);
br = new BufferedReader(new FileReader(inFile));
String line = "";
String cvsSplitBy = "\t";
// prepare output file
File outFile = new File(outputFile);
bw = new BufferedWriter(new FileWriter(outFile));
// Write header
bw.write("id:ID;genre;notoriete_fr:int;notoriete_us:int;notoriete_uk:int;notoriete_sp:int;notoriete_de:int;notoriete_it:int;notoriete_no:int;notoriete_wd:int;:LABEL\n");
while ((line = br.readLine()) != null) {
// READING
line = br.readLine();
String[] features = line.split(cvsSplitBy);
// WRITING
bw.write("t"+features[0]+";"+features[3]+";"+features[4]+";"+features[5]+";"+features[6]+";"+features[7]+";"+features[8]+";"+features[9]+";"+features[10]+";"+features[11]+";Track\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
the output file only has 8.3% of input file lines
As far as you code is concerned, It should be 50% of the lines should be missing. You have the difference in size because the data that is in the parent file is of different format than that in the file you are creating. I am saying this because you code skips the alternate lines.
Let me explain, in your while loop condition you are using line = br.readLine() Which reads the line 1. now in the first line of the while loop you are again using line = br.readLine() this will read the line 2. the file. You are using it to write the data, so line 2 data gets written. Now in the second looping, in the while loop condition you are reading line 3 of the file and in the first line of while loop you are reading line 4 of the file and this line gets written. So you see you get 50% of the output.
Now you think you understand why you are getting lesser lines in the output file. so the simple solution is to get rid of preferable the first line of the while loop and let the condition remain the same.
this behavior can be attributed to the following two lines in the code.
while ((line = br.readLine()) != null) {
// READING
line = br.readLine();
you are reading two lines from the file one during while check and one during the line = br.readline() , causing skipped lines. you should read only at the while loop check.
while ((line = br.readLine()) != null) {
// use line variable value for printing
I have this program that reads a text file. I need to get some data out of it.
The text files look like this:
No. Ret.Time Peak Name Height Area Rel.Area Amount Type
min µS µS*min % mG/L
1 2.98 Fluoride 0.161 0.028 0.72 15.370 BMB
2 3.77 Chloride 28.678 3.784 99.28 2348.830 BMB
Total: 28.839 3.812 100.00 2364.201
I need to start reading from line #29 and from there get the Peak Name and the Amount of each element like Fluoride, Chloride and so on. The example only shows those two elements, but other text files will have more. I know I will need some sort of loop to iterate through those lines starting on line #29 which is where the "1" starts then the "2" which will be the 30th line and so on.
I have tried to make this work, but I am missing something I think and I`m not sure what. Here is my Code.
int lines = 0;
BufferedReader br = new BufferedReader(new FileReader(selectFile.getSelectedFile()));
Scanner sc = new Scanner(new FileReader(selectFile.getSelectedFile()));
String word = null;
while((word =br.readLine()) != null){
lines++;
/*if(lines == 29)
System.out.println(word);*/
if ((lines == 29) && sc.hasNext())
count++;
String value = sc.next();
if (count == 2)
System.out.println(value + ",");
}
Here's some code for you:
int linesToSkip = 28;
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ( (line = br.readLine()) != null) {
if (linesToSkip-- > 0) {
continue;
}
String[] values = line.split(" +");
int index = 0;
for (String value : values) {
System.out.println("values[" + index + "] = " + value);
index++;
}
}
}
Note that I've surrounded it in a try(expr) {} block to ensure that the reader is closed at the end, otherwise you'll consume resources and possibly lock the file from other processes.
I've also renamed the variable you called word as line to make it clearer what it contains (i.e. a string representing a line in the file).
The line.split(" +") uses a regular expression to split a String into its constituent values. In this case your values have spaces between, so we're using " +" which means 'one or more spaces'. I've just looped through the values and printed them out; obviously, you will need to do whatever it is you need to do with them.
I replaced the line count with a linesToSkip variable that decrements. It's less code and explains better what you're trying to achieve. However, if you need the line number for some reason then use that instead, as follows:
if (++lineCount <= 28) {
continue;
}
If I'm reading it correctly, you are mixing two different readers with the BufferedReader and the Scanner, so you are not going to get the results right changing from one to the other (one is not pointing to the same position than the other). You already have the line in word and you can parse it, no need of using the Scanner. Just skip until line 29 (lines > 29) and then parse the values you want, line by line.
You are reading the file twice... try something like this
int lines = 0;
BufferedReader br = new BufferedReader(new FileReader(selectFile.getSelectedFile()));
String line = null;
while ((line = br.readLine()) != null) {
if (++lines < 29)
continue; //this ignores the line
for(String word : line.split("separator here")) {
// this will iterate over every word on that line
// I think you can take it from here
System.out.println(word);
}
}
Hi i'm working on an android app and this is my problem
I have a text file that is maybe 100 lines long it differs from phone to phone but lets say a section is like this
line 1 = 34
line 2 = 94
line 3 = 65
line 4 = 82
line 5 = 29
etc
each line will be equal to some number however that number will be different from phone since my application will be changing this number and it may already be different before my app is installed. So here's my problem i want to search the text file for say "line 3 = " then delete that entire line and replace it with "line 3 = some number"
My main goal is to change that number at the end of line 3 and keep line 3 that is the text exactly the same i only want to edit the number however the problem is that number will always be different
How can i go about doing this? thanks for any help
You can't "insert" or "remove" characters in the middle of a file. I.e., you can't replace 123 with 1234 or 12 in the middle of a file.
So either you "pad" each number so they all have equal width, i.e., you represent 43 as for instance 000043, or you'll probably have to regenerate the whole file.
To regenerate the whole file, I suggest you read the original file line by line, process the lines as appropriate, and write them out to a new, temporary file along the way. Then, when you're through, you replace the old file with the new one.
To process the line I suggest you do something like
String line = "line 3 = 65";
Pattern p = Pattern.compile("line (\\d+) = (\\d+)");
Matcher m = p.matcher(line);
int key, val;
if (m.matches()) {
key = Integer.parseInt(m.group(1));
val = Integer.parseInt(m.group(2));
// Update value if relevant key has been found.
if (key == 3)
val = 123456;
line = String.format("line %d = %d", key, val);
}
// write out line to file...
Thanks guys for the replies but what i ended up doing was using the sed command in bash and the wild card command * to replace the line and then just ran the script through java which went a little like this
Script
busybox sed -i 's/line 3 = .*/line 3 = 70/g' /path/to/file
Java
Command
execCommand("/path/to/script");
Method
public Boolean execCommand(String command)
{
try {
Runtime rt = Runtime.getRuntime();
Process process = rt.exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (IOException e) {
return false;
} catch (InterruptedException e) {
return false;
}
return true;
}
The simplest solution is to read the whole file into memory and then replace the line want to change and then write it back to the file.
For exmple:
String input = "line 1 = 34\nline 2 = 94\nline 3 = 65\nline 4 = 82\nline 5 = 29\n";
String out = input.replaceAll("line 3 = (\\d+)", "line 3 = some number");
...outputs:
line 1 = 34
line 2 = 94
line 3 = some number
line 4 = 82
line 5 = 29
A couple thoughts. An easier way to do this (if possible) would be to store these lines in a collection (like an ArrayList) and do all of your manipulation within your collection.
Another solution can be found here. If you need to replace the contents within a text file, you could call a method periodically to do this:
try {
BufferedReader in = new BufferedReader(new FileReader("in.txt"));
PrintWriter out = new PrintWriter(new File("out.txt"));
String line; //a line in the file
String params[]; //holds the line number and value
while ((line = in.readLine()) != null) {
params = line.split("="); //split the line
if (params[0].equalsIgnoreCase("line 3") && Integer.parseInt(params[1]) == 65) { //find the line we want to replace
out.println(params[0] + " = " + "3"); //output the new line
} else {
out.println(line); //if it's not the line, just output it as-is
}
}
in.close();
out.flush();
out.close();
}catch(Exception e) {
e.printStackTrace();
}