Java - Use Scanner to read big text files - java

I have a very big text file with customer information. I would like to read all the customer information from the text file.
This is how my text file is organized:
Costomer 1:
Name:
Erik Andersson
Adress:
Street1
Phone number:
085610540
Costomer 2:
Name:
Lars Larsson
Adress:
Street1
Phone number:
085610540
I would like to be able read all the customer information. Is there any good way to it with? I have read about Scanner and Pattern and was wondering if it is good idea to use them in this case? My text file is very big and contains hundreds of customers.
Dose any one have any idea how I could read all the information from the text file? I have created a class with customer variabled, I only need help with the reading from the text file. I want to read the information in an organized way.
All help is very very appreciated.

Like so:
public void getEmployees(File f) throws Exception {
// An ArrayList of your Employee-Object to hold multiple Employees
ArrayList<Employee> employees = new ArrayList<Employee>();
// The reader to read from your File
BufferedReader in = new BufferedReader(new FileReader(f.getAbsolutePath()));
// This will later contain one single line from your file
String line = "";
// Temporary fields for the constructor of your Employee-class
int number;
String name;
String adress;
String phone;
// Read the File untill the end is reached (when "readLine()" returns "null")
// the "line"-String contains one single line from your file.
while ( (line = in.readLine()) != null ) {
// See if your Line contains the Customers ID:
if (line.startsWith("Customer")) {
// Parse the number to an "int" because the read value
// is a String.
number = Integer.parseInt(s.substring("Customer ".length()).substring(0,s.indexOf(':')));
} else if (line.startsWith("Adress:")) {
// The Adress is noted in the next line, so we
// read the next line:
adress = in.readLine();
} else if (line.startsWith("Phone number:")) {
// Same as the Adress:
phone = in.readLine();
} else if (line.startsWith("Name:")){
// Same as the Adress:
name = in.readLine();
} else if ( line.equals("") ){
// The empty line marks the end of one set of Data
// Now we can create your Employee-Object with the
// read values:
employees.add(new Employee(number,name,adress,phone));
}
}
// After we processed the whole file, we return the Employee-Array
Employee[] emplyeeArray = (Employee[])employees.toArray();
}
Please give +1 and correct for ur hw lol

As a little extension to stas answer:
The originally posted code doesn't work, because a continue skips the current loop-iteration. So unless the line starts with "", nothing is ever done.

Related

How To Read A Specific Part Of A Line In A Text File In Java?

I have a text file in which I have written some information line by line like this:
name|Number|amount|PIN
How can I read back data In a way that (for example) I will be able to use just the "name" part in a method?
The sample code is shown in the image below.
in the beginning declare a List to collect the accounts:
import java.util.ArrayList;
...
public Account[] inReader() { //BTW: why do you pass an Account[] here?
ArrayList accountList = new ArrayList();
...
}
replace the for(String records : dataRecords) {...} with
String name = dataRecords[0];
String cardNumber = dataRecords[1];
int pin = Integer.parseInt(dataRecords[2]); //to convert the String back to int
double balance = Double.parseDouble(dataRecords[3]);
Account account = new Account(name, cardNumber, pin, balance);
accountList.add(account);
because you already proceed record by record (while ((line = br.readLine())!=null) {...})
in the end return accountList.toArray(new Account[0]);
You can read the text line by line and then use the "|" delimiter to separate the columns.
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
You could read the file line-by-line and split on the delimiter '|'.
The following example assumes the filepath is in args[0] and would read then output the name component of the input:
public static void main(String[] args) {
File file = new File(args[0]);
BufferedReader br = new BufferedReader(new FileReader(file));
while(String line = br.readLine()) != null) {
String[] details = line.split("|");
System.out.println(details[0]);
}
}
As mentioned in the comment above, you can simply split the line on your delimiter, |, and go from there.
Something like:
public class Account {
// ...
public static Account parseLine(String line) {
String[] split = line.split("|");
return new Account(split[0], split[1], split[2], split[3]);
}
}
should work fine (assuming you have a constructor which takes the four things you're putting in). If your Account class has more information than this, you can create an AccountView or similarly named class which does only contain the details you have available here. With this, just iterate line by line, parse your lines to one of these Objects, and use it's properties (including the already available getters) when calling other methods which need name, etc.
First, you need to read the whole content of the file or line by line.
Then, for each line you need to create a function to split the line text by a configurable delimiter. This function can receive the column number and it should return the needed value. For example: extractData(line, 0) should return 'name', extractData(line, 2) should return 'amount' etc.
Also, you need some validation: what if there are only 3 columns and you expect 4? You can throw and exception or you can return null/empty.
There are many possible ways to do it. One of them is to make an object that will hold the data. Example since you know that your data will always have name, number, amount and pin then you can make a class like this:
public class MyData {
private String name;
private String number;
private double amount;
private String pin;
// Add getters and setters below
}
Then while reading the text file you can make a list of MyData and add each data. You can do it like this:
try {
BufferedReader reader = new BufferedReader(new FileReader("path\file.txt"));
String line = reader.readLine();
ArrayList<MyData> myDataList = new ArrayList<MyData>();
while (line != null) {
String[] dataParts = line.split("|"); // since your delimiter is "|"
MyData myData = new MyData();
myData.setName(dataParts[0]);
myData.setNumber(dataParts[1]);
myData.setAmount(Double.parseDouble(dataParts[2]));
myData.setPin(dataParts[3]);
myDataList.add(myData);
// read next line
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
Then you can use the data like this:
myDataList.get(0).getName(); // if you want to get the name of line 1
myDataList.get(1).getPin(); // if you want to get the pin of line 2
You can convert the file into a csv file and use a library specific for reading csv files, e.g. OpenCSV. This will give you more flexibility in handling the data in the file.

Accept arbitrary multi-line input of String type and store it in a variable

Is there any possible way to accept a arbitrary(unknown) no. of input lines of string from the user until user explicitly enters -1 and store it in a string for further manipulation.
From what I gather, you're trying to get input from a user until that user types -1. If thats the case, please see my function below.
public static void main (String[] args)
{
// Scanner is used for I/O
Scanner input = new Scanner(System.in);
// Prompt user to enter text
System.out.println("Enter something ");
// Get input from scanner by using next()
String text = input.next();
// this variable is used to store all previous entries
String storage = "";
// While the user does not enter -1, keep receiving input
// Store user text into a running total variable (storage)
while (!text.equals("-1")) {
System.out.println("You entered: " + text);
text = input.next();
storage = storage + "\n" + text
}
}
I've left comments in that code block but I'll reiterate it here. First we declare our I/O object so that we can get input from the keyboard. We then ask the user to "Enter something" and wait for the user to enter something. This process is repeated in the while loop until the user specifically types -1.
Your question makes no sense... You're talking about taking input from a user, but also reaching the end of a file, implying you are taking reading input from a file. Which is it?
If you're trying to say that for each line in a file, the user must enter something for some action to be taken, then yes, that can be done.
I'll assume you already have a File object or String containing the file path, named file.
// make a stream for the file
BufferedReader fileReader = new BufferedReader(new FileReader(file));
// make a stream for the console
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
// declare a String to store the file input
String fileInput;
// use a StringBuilder to construct the user input lines
StringBuilder inputLines = new StringBuilder();
// while there is a line to be read
while ((fileInput = fileReader.readLine()) != null) {
/*
** maybe some output here to instruct the user?
*/
// get some input from the user
String userInput = consoleReader.readLine();
// if the user wants to stop
if (userInput.equals("-1")) {
// exit the loop
break;
}
// else append the input
inputLines.append(userInput+"\r\n");
}
// close your streams
fileReader.close();
consoleReader.close();
// perform your further manipulation
doSomething(inputLines.toString());
Those classes are located in java.io.*. Also, remember to catch or have your method throw IOException.
If you want to perform your manipulation each time you have some input instead of doing it all at the end, get rid of the StringBuilder, and move doSomething(userInput) into the loop before the if statement.

How to delete a line from a textfile using java?

I wanted to delete a line from a textfile after asking the user what he/she wants to delete but I don't know what to do next in my code.
The textfile looks like this:
1::name::mobileNum::homeNum::fax::birthday::email::website::address // line the user wants to delete
2::name::mobileNum::homeNum::fax::birthday::email::website::address
3::name::mobileNum::homeNum::fax::birthday::email::website::address
Here's my code:
public static void readFromFile(String ans, String file) throws Exception {
BufferedReader fileIn = new BufferedReader(new FileReader(file));
GetUserInput console = new GetUserInput();
String checkLine = fileIn.readLine();
while(checkLine!=null) {
String [] splitDetails = checkLine.split("::");
Contact details = new Contact(splitDetails[0], splitDetails[1], splitDetails[2], splitDetails[3], splitDetails[4], splitDetails[5], splitDetails[6], splitDetails[7], splitDetails[8]);
checkLine = fileIn.readLine();
if(ans.equals(splitDetails[0])) {
// not sure what the code will look like here.
// in this part, it should delete the line the user wants to delete in the textfile
}
}
}
So the output of the textfile should be like this:
2::name::mobileNum::homeNum::fax::birthday::email::website::address
3::name::mobileNum::homeNum::fax::birthday::email::website::address
Also, I want the line number 2 and 3 to be adjusted to 1 and 2:
1::name::mobileNum::homeNum::fax::birthday::email::website::address
2::name::mobileNum::homeNum::fax::birthday::email::website::address
How would I do this?
Here's a working code, assuming you are using Java >= 7:
public static void removeLine(String ans, String file) throws IOException {
boolean foundLine = false;
try (BufferedReader br = Files.newBufferedReader(Paths.get(file));
BufferedWriter bw = Files.newBufferedWriter(Paths.get(file + ".tmp"))) {
String line;
while ((line = br.readLine()) != null) {
String[] tokens = line.split("::", 2);
if (tokens[0].equals(ans)) {
foundLine = true;
} else {
if (foundLine) {
bw.write((Integer.parseInt(tokens[0]) - 1) + "::" + tokens[1]);
} else {
bw.write(line);
}
bw.newLine();
}
}
}
Files.move(Paths.get(file + ".tmp"), Paths.get(file), StandardCopyOption.REPLACE_EXISTING);
}
It is not possible to delete a line from a file. What you need to do is read the existing file, write the contents you want to keep to a temporary file and then rename the temporary file to overwrite the input file.
Here, the temporary file is created in the same directory as the input file, with the extension .tmp added (note that you can also use Files.createTempFile for this).
For each line that is read, we check if this is the line the user wants to delete.
If it is, we update a boolean variable telling us that we just hit the line to be deleted and we do not copy this line to the temporary file.
If it is not, we have a choice:
Either we did not yet hit the line to be deleted. Then we simply copy what we read to the temporary file
Or we did and we need to decrement the first number and copy the rest of the line to the temporary file.
The current line is splitted with the help of String.split(regex, limit) (it splits the line only two times, thereby creating an array of 2 Strings: first part is the number, second part is the rest of the line).
Finally, the temporary file overwrites the input file with Files.move (we need to use the REPLACE_EXISTING option).

Read data from file into an array Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In my program, I am asking users for input for a subject name and a subject code which i pass through to a subjects.txt file eg:
Inside the TestSubject class -
//ask the user to input a subject name
System.out.println("Please enter a Subject Name");
//assign each input to a side
String subjectName = input.nextLine();
//ask the user to input a subject code
System.out.println("Please enter a Subject Code");
String subjectCode = input.nextLine();
//add records to the file
subject.addRecords(subjectName, subjectCode);
Inside the subject class -
//add the records of valid subject name and subject code
public void addRecords(String name, String code) {
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("subjects.txt", true)))) {
out.printf(name);
out.printf("\n");
out.printf(code);
out.printf("\n");
out.close();
}catch (IOException e) {
}
}
I then want to read this file and pass the data through to an arraylist. The file might look something like:
Testing 1
ABC123
Testing 2
DEF456
Testing3
GHI789
I want to pass it through to an arraylist so then I can then process other methods against this array such as sorting, see if any are the same etc.
//read data from subjects file and place in an array
public void readData(){
Scanner input = new Scanner("subjects.txt");
while (input.hasNext()) {
String subjectName = input.nextLine();
String subjectCode = input.nextLine();
}
ArrayList<String> subjectNames = new ArrayList<String>();
ArrayList<String> subjectCodes = new ArrayList<String>();
//add the input to the arrays
subjectNames.add(subjectName);
subjectNames.add(subjectCode);
//display the contents of the array
System.out.println(subjectNames.toString());
System.out.println(subjectCodes.toString());
}
Even if there is a good tutorial around that I might be able to be pointed in the right direction...
Thanks for editing your post. Much easier to help when I can see what's causing problems.
You're checking hasNext() once every two lines. Should be checked every line because you shouldn't trust the text file to be what you expect and should display an informative error message when it isn't.
You're also declaring the strings inside the scope of the loop so nothing outside the loop even knows what they are. Shoving subjectCode into into the subjectNames collection is probably not what you want. As it is, each nextline() is stepping on the last string value. That means you're forgetting all the work done in previous iterations of the loop.
The collections.add() calls, not the strings, should be in the loop. Make sure to declare the collections before the loop and put their add calls in the loop. See if you get useful results.
Give "Reading a plain text file in Java" a read.
Regarding your tutorial query, I often find some good basic examples on this site including one for reading from a file as referenced in the link. Using the main principles of that example here is one way you could try and read the lines from your file:
public static void main(String[] args){
ArrayList<String> subjectNames = new ArrayList<String>();
ArrayList<String> subjectCodes = new ArrayList<String>();
//Path leading to the text file
Path data = Paths.get(System.getProperty("user.home"), "Desktop", "file.txt");
int count = 0;//Will indicate which list to add the current line to
//Create a buffered reader to read in the lines of the file
try(BufferedReader reader = new BufferedReader(new FileReader(data.toFile()))){
String line = "";
while((line = reader.readLine()) != null){//This statement reads each line until null indicating end of file
count++;//Increment number changing from odd to even or vice versa
if(count % 2 == 0){//If number is even then add to subject codes
subjectCodes.add(line);
} else {//Otherwise add to subject names
subjectNames.add(line);
}
}
} catch (IOException io){
System.out.println("IO Error: " + io.getMessage());
}
System.out.println("Codes: ");
display(subjectCodes);
System.out.println("\nNames: ");
display(subjectNames);
}
private static void display(Collection<String> c){
for(String s :c){
System.out.println(s);
}
Hope it helps!

Converting text dumped in textfile to Csv and Array

i have been using an actionListenerto pass text from numerous TextFields into a text file named writetouser.txtthis works fine though i have noticed that this text is just dumped and is not in the format of an array. For the purposes of this application it is necessary that i am able to search this text file and show values based on searches entered. I have a file which reads the data from the text file and have attempted to convert the data to CSV's so it is is readable as an array. i am wondering what must be entered instead of user, pass in order to take the text from inside the filewritetouser.txt.
Addendum:
public void ReadUser()
{
try{
// Open the file
FileInputStream fstream = new FileInputStream("writetouser.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
//System.out.println (strLine);
String[] items = strLine.split(",");
String[][] usersArray = new String [10][2];
for (String item : items) {
System.out.println(item);
}
}
//Close the input stream
in.close();
}catch (Exception e){
//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
here is an example of the data which i am trying to separate. it is entered into textfile as
inputUser = user + ", " + pass;
writetouser.WriteToUser(inputUser);
dburgess, 2345
I think what you want is:
String[] items = strLine.split(",");
I notice that this line is commented out:
//System.out.println (strLine);
Which suggests to me that you were probably trying to ensure that you're getting the line you expect from your file. If you are getting what you expect, we're clear to move on. If not, there's a problem in how the file is being read, or the data isn't formatted how you expect.
If we're good so far, we've arrived at the problem of parsing and displaying the content of the file. I'm assuming that you're trying to write the contents of the file to your terminal and expecting one format, but getting another.
I think what you'll see right now is something like this:
Username: dburgess
Password: 2345
(with no more than 1 username/password pair printed).
And I'm guessing you want something like this:
Username: dburgess Password: 2345
Username: someOtherUser Password: SomeOtherpass
Username: blahblah Password: etcPass
....
Username: thelastOne Password: Icanhazpassword?
There are a lot of assumptions there (I'm still not entirely sure what you're trying to do) -- if those assumptions are correct, let me know; I'll post some formatting tips.
Upon reviewing my code i noticed that the two pieces of code below were doing the exact same thing which is why i was being presented with each piece of info twice.
A
for (String item : items) {...}
B
for (int i = 0; i < items.length; i++) {
String item = items[i];
....
}

Categories