I dont understand why i am not able to read from the file.I am always getting null with Readline() method of BufferedReader .
TestStudent class should be able to perform the following functions:
Create an ArrayList object of Student objects called studentList, using the student data stored in a text file named students.txt (you should create this file such that it stores the student name and ID of several students initially – one line per student)
Allow the user to add as many new Student objects as the user requests to the ArrayList ensuring that each student has a unique student ID
When the user has finished adding new students to the list, the program will override the students.txt file such that it includes the data relating to the new students as well as the original ones
Ability to display a full list of students as well as just the existing student IDs when necessary
Here's what i have done till now.
import java.util.*;
import java.io.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class TestStudent {
public static void main(String[] args) throws IOException {
File f=new File("C:\\Users\\user1\\Desktop\\Students.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
// FileReader reads text files in the default encoding.
FileReader fileReader =
new FileReader(f);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
//File f=new File("Student.txt");
Scanner sc=new Scanner(System.in);
Scanner scan = new Scanner(f);
ArrayList<Student> studentList = new ArrayList<>();
String cont;
do {
System.out.println("Enter Student Name:");
String name=sc.next();
System.out.println("Enter Student ID:");
String id=sc.next();
bw.write(name);
bw.write("\t"+id);
bw.newLine();
System.out.println("Continue Adding?");
cont=sc.next();
}
while(cont.equalsIgnoreCase("y"));
while(bufferedReader.readLine() != null){
String line = bufferedReader.readLine();
String[] record = line.split("\t");
Student myStudent =new Student(record[0],record[1]);
studentList.add(myStudent);
}
for(Student st:studentList)
System.out.println(st.Name+" "+st.Id);
bw.close();
scan.close();
sc.close();
}
}
class Student{
String Name, Id;
with default value red
Student(String string, String string0) {
System.out.println("s");
}
//Following are Mutators methos
public String getName() {
return this.Name;
}
public String getId() {
return this.Id;
}
//Following are accessor Methods
public void setName(String s){
this.Name=s;
}
public void setID(String ID) {
this.Id = ID;
}
public String toString() {
return "Student name is "+getName()+" Student Id is "+getId();
}
public boolean isValidID() {
if(getId().length()!=6)
return false;
else{
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return false;
}
return true;
}
}
public boolean IDExists(Student other) {
if(other.getId().equals(this.getId()))
return true;
else
return false;
}
}
The problem is here:
while(bufferedReader.readLine() != null){
String line = bufferedReader.readLine();
...
}
The first call to readLine() reads the line, but does not assign it - its lost. The next call to readLine() reads the next line.
It should be:
String line = null;
while ((line = bufferedReader.readLine()) != null){
....
}
This reads the next line, assign it to line, and then compares to null.
Then, your student constructor is broken:
Student(String string, String string0) {
System.out.println("s");
}
You never assign string and string0 to anything, and Id and Name are not assigned and always null.
Your code furthermore does not compile:
String Name, Id;
with default value red
This is a syntax error.
Read about How to create a Minimal, Complete, and Verifiable example to ensure your code is working and your question focused on one problem at a time. Most of your problems would be gone simply by making sure you test every part of your program separately and make sure it actually compiles.
you forgot to assign studentID and studentName for new Object in constructor
Student(String string, String string0) {
System.out.println("s");
id = string;
name = string0;
}
and because you write and read the same file so you must close fileWriter before reading
do {
// your code
}
while(cont.equalsIgnoreCase("y"));
// close buffer writer before reading
bw.close()
String line;
while((line = bufferedReader.readLine()) != null){
String[] record = line.split("\t");
Student myStudent =new Student(record[0],record[1]);
studentList.add(myStudent);
}
Related
Here is the code I'm using
import java.util.Scanner;
import java.io.*;
import java.util.ArrayList;
public class Message{
Scanner input;
String emailLine = "";
String line;
ArrayList<String> email = new ArrayList<String>();
String emailString;
String sender;
String subject;
String emailMIN;
String[] newString;
StringBuilder emailStringBuilder = new StringBuilder();
public Message(String m)throws IOException{
File inFile = new File ("mail.txt");
input = new Scanner (inFile);
String message;
getEmails();
}
public void getEmails(){
while(input.hasNextLine()){
line = input.nextLine();
System.out.println("Test, line: " + line);
if(line.equals("<END>")){
System.out.println("Test, <END> reached");
System.out.println("Test, email String: " +
emailStringBuilder.toString());
email.add(emailStringBuilder.toString());
}
else{
emailStringBuilder.append("\n" + line);
}
}
}
I'm trying to pass the email ArrayList into a different class so that I can break up the Strings of the ArrayList into separate Arrays. How do I do this? Also once I get it into a different class, how do I access each element of the ArrayList and break each element up into another ArrayList with each element separated by the lines?
Use message.getEmails() to get your emails.
Below is a sample code
public class Message{
Scanner input;
String emailLine = "";
String line;
List<String> emails = new ArrayList<String>();
String emailString;
String sender;
String subject;
String emailMIN;
String[] newString;
StringBuilder emailStringBuilder = new StringBuilder();
public Message(String m)throws IOException{
File inFile = new File ("mail.txt");
input = new Scanner (inFile);
String message;
populateEmails();
}
public void populateEmails(){
while(input.hasNextLine()){
line = input.nextLine();
System.out.println("Test, line: " + line);
if(line.equals("<END>")){
System.out.println("Test, <END> reached");
System.out.println("Test, email String: " +
emailStringBuilder.toString());
emails.add(emailStringBuilder.toString());
}
else{
emailStringBuilder.append("\n" + line);
}
}
}
public List<String> getEmails() {
return emails;
}
}
Well first of all an ArrayList is not a List of arrays. It's simply a List of items, in your case String.
If you want to pass an ArrayList to a different class you could simply do something like this:
public class MyOtherClass {
public void doSomething(ArrayList<String> myList) {
// do something with "myList"
}
And then in your Message class:
MyOtherClass myClass = new MyOtherClass();
myClass.doSomething(email);
Is this helping?
NOTE
From your editing of the question I think you don't fully understand how ArrayList works. It is not a List of Array! It is simply an array implementation of the List interface for better performance in certain tasks. For more information read the javadocs about ArrayList
EDIT
As peeskillet was suggesting, you could also instantiate a Message class object in your new class and get the ArrayList from there, but then email would have to be a public field in your class Message or declare a getter method for email.
EDIT
Since you added more questions:
You can go through all the elements of an ArrayList like this:
For (String nextString : email) {
System.out.println(nextString); // Or do whatever you want with it :)
}
I am currently trying to figure out how to read and save .txt files to a dynamic array in Java, I do not know how to save the read .txt file into the array. The file I am trying to read is named songCollection.txt.
The specific data parts need to be:
title,artist,genre,album,songID
Below is my current code, any help will be much appreciated. Thanks
Code:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.io.*;
public class song {
private int SongID; // The unique song identifier
private String title; // The song title
private String artist; // The song artist
private String genre; // The genre of the song
private String album; // The album name
private String songData;
public song() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream fstream = new FileInputStream("songCollection.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
Readable fileSong;
String[] songData = new Scanner(fileSong);
while (songData.hasNextLine()) {
String songCollection = songData.nextLine();
songData = songCollection.split(",");
}
}
}
I am not sure what exactly you are looking. But if you are simply looking to store data in then you can store string array in ArrayList or any collection that suits you.
If you want to use it later for fast retrieval you can use any of the map implementation to store the key and value pair
Question: "I do not know how to save the read .txt file into the array"
Answer:
Most text files can be read into your program using a simple Scanner. For example:
Scanner input = new Scanner(fileName);
int[] ints = new int[10];
int i = 0;
while (input.hasNextInt()) {
input.nextInt() = ints[i];
i++
}
input.close()
The only issue with your approch is that you don't know how big of an array you will need. I recommend you store your input in a data structure that dynamically allocates space, like a LinkedList or an UnboundedStack.
Instead of printing out tokens to console you should create a new Song instance and set values to it:
song s = new song();
s.SongId = Integer.parseInt(splitOut[0]);
s.title = splitOut[1];
s.artist = splitOut[2];
...
And then put this song instance to a list.
Also consider implementing Song constructor with all these fields as arguments.
String temp = "";
try{
Scanner input = new Scanner("yourfile.txt");
while(input.hasNext()){
temp = temp + "_" + input.next();
}
input.close();
}
catch(Exception e){
}
String fin[] = temp.split("_");
You should define the constructor of your Song class as:
public Song(int songId, String title, String artist, String genre,
String album, String songData) {
this.songId = songId;
this.title = title;
this.artist = artist;
this.genre = genre;
this.album = album;
this.songData = songData;
}
And here's an example of using BufferedReader to read all song lines into a list (this code requires Java7):
List<Song> songs = new ArrayList<>(); // List of Song objects
try (BufferedReader input = new BufferedReader(new InputStreamReader(
new FileInputStream("songCollection.txt"), Charset.forName("UTF-8")))) {
String line;
while ((line = input.readLine()) != null) {
String[] arr = line.split(",");
songs.add(new Song(Integer.parseInt(arr[0]), arr[1], arr[2], arr[3],
arr[4], arr[5])); // <- Add new Song to list.
}
} catch (IOException e) {
e.printStackTrace();
}
Live example: http://ideone.com/HFn4jY
i making a program where I would read data from text files and store them in tables in mysql.
In my program the user would give the directory of where the files are, then the program would find only the .txt files and would continue. Afterwards a table would be created and it would have 2 fields and in these fields I would insert the values from the text file.
My issue is that i don't know how! I would explain you what I mean! In my program I would create table with fields (ID, Name). The values of these fields must be taken from the text file. All the files are as the below:
As you can see the ID is in the third row of the file and the Name is in the fifth. Could anyone help me how can I import the values for ID and Name in the table?How can i get only these values each time from the files?
The code for doing the first steps is:
public static void main(String args[]) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "", "");
String dirpath = "";
Scanner scanner1 = new Scanner(System.in);
while (true) {
System.out.println("Please give the directory:");
dirpath = scanner1.nextLine();
File fl = new File(dirpath);
if (fl.canRead())
break;
System.out.println("Error:Directory does not exists");
}
try {
String files;
File folder = new File(dirpath);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
if (files.endsWith(".txt") || files.endsWith(".TXT")) {
List<File> txtFiles = new ArrayList<File>();
txtFiles.add(listOfFiles[i]);
String[] parts = files.split("\\.");
String tablename = parts[0];
for (File txtFile : txtFiles) {
List sheetData = new ArrayList();
try {
FileReader in = new FileReader(txtFile);
BufferedReader br = new BufferedReader(in);
String line = br.readLine();
while (line != null) {
System.out.println(line);
line = br.readLine();
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
getCreateTable1(con, tablename);
importData(con, txtFile, tablename);
}
}
}
}
} catch (Exception e) {
System.out.println();
}
}
private static String getCreateTable1(Connection con, String tablename) {
try {
Class.forName("com.mysql.jdbc.Driver");
Statement stmt = con.createStatement();
String createtable = "CREATE TABLE "
+ tablename
+ " ( ID INT , name VARCHAR(255)";
System.out.println("Create a new table in the database");
stmt.executeUpdate(createtable);
} catch (Exception e) {
System.out.println(((SQLException) e).getSQLState());
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
BufferedReader br = new BufferedReader(new FileReader(new File("path/to/file")));
String currentLine = br.readLine();
Map<Integer, String> nameByID = new HashMap<Integer, String>();
while (currentLine != null) {
String[] tokens = currentLine.split("\t");
int id = Integer.parseInt(tokens[2]);
String name = tokens[4];
nameByID.put(id, name);
currentLine = br.readLine();
}
br.close();
nameByID will have the names and IDs you need.
Note that some exception handling is required for calls to create a new BufferedReader, for calls to readLine(), and to close the BufferedReader. I didn't insert this because I couldn't remember it off the top of my head but your IDE should prompt you to insert if you're using something like Netbeans or Eclipse
You should try not to reinvent the wheel.
Use a FileNameExtensionFilter to filter the .txt files, this class is from swing but it's fine to use in plain java.
Check if each line matches a regex pattern, that way you can digest the line at the same time as verifying it.
Create a Person object that holds this information and return a Collection of Person - that way you encapsulate your file reading behavior away from your database access layer.
Put all this in a class called, say, FileReader and you have something like the following:
public class FileReader {
private final Pattern linePattern = Pattern.compile("^(\\w++)\\s++(\\w++)\\s*+$");
private final Pattern lineBreakPattern = Pattern.compile("\r?\n");
private final FileFilter txtFilter = new FileNameExtensionFilter("*.txt", "txt");
private final File txtFolder;
public FileReader(File txtFolder) {
this.txtFolder = txtFolder;
}
public List<Person> readFiles() {
final List<Person> people = new LinkedList<>();
for (final File txtFile : txtFolder.listFiles()) {
if (txtFilter.accept(txtFile)) {
people.add(readFile(txtFile));
}
}
return people;
}
private Person readFile(File txtFile) {
try (final Scanner scanner = new Scanner(txtFile)) {
scanner.useDelimiter(lineBreakPattern);
final Person person = new Person();
while (scanner.hasNext()) {
final String line = scanner.next();
final Matcher matcher = linePattern.matcher(line);
if (matcher.matches()) {
switch (matcher.group(1).toUpperCase()) {
case "ID":
person.setId(Integer.parseInt(matcher.group(2)));
break;
case "NAME":
person.setName(matcher.group(2));
break;
default:
throw new IOException("Illegal line '" + matcher.group() + "'.");
}
}
}
return person;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
public static final class Person {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
So you would create a FileReader with the folder that contains the files and then call readFiles, you then save the returned List<Person> in the database.
Lets go through this class.
The readFiles method loops over all files in the directory and checks whether each one of them matches the txtFilter - this filters out any non .txt file.
The readFiles method also creates and returns a List<Person, this is the result of reading the files. The List is populated by the readFile(File txtFile) method. That method is responsible for reading the individual files and parsing them to a Person.
The Person class is a very simple data transfer object, holding on properties and accessors. No logic.
The readFile method creates a Scanner in a Java 7 try-with-resources construct. It sets the delimiter to a platform independent linebreak pattern (\r?\n means that it matches \r\n or \n) and then loops over the scanner output.
Each line is processed with the linePattern, this probably warrants some explanation:
^(\\w++)\\s++(\\w++)\\s*+$
^ is the "start anchor", i.e. the line starts here
(\\w++) means capture any number of word characters
\\s++ means skip any number of whitespace characters
(\\w++) same as above
\\s*+ means skip zero or more whitespace characters
$ is the "end anchor", i.e. the end of the line
So, if the pattern matches we have a valid line. Moreover, when verifying we grabbed to "groups" of characters, these are our key and value.
Next we use a switch on the first group, this is using Java 7 switches with Strings. We populate the person depending on the value of the key, parsing the int where needed.
Finally we return the populated person.
This class should get you well on your way to accomplishing you goal - the sql insertion of the Person objects into a database is trivial.
You may want to add more verification during the file reading process, for example check that both a NAME and ID were found. I leave this as an exercise.
I'm trying to read data from a .txt file. The format looks like this:
ABC, John, 123
DEF, Mark, 456
GHI, Mary, 789
I am trying to get rid of the commas and put the data into an array or structure (structure most likely).
This is the code I used to to extract each item:
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[]args){
try {
FileInputStream fstream = new FileInputStream("courses.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
At one point I had a print line in the "while" loop to see if the items would be split. They were. Now I'm just at a loss on what to do next. I'm trying to place each grouping into one structure. For example: ID - ABC. First Name - John. Room - 123.
I have a few books on Java at home and tried looking around the web. There is so much out there, and none of it seemed to lead me in the right direction.
Thanks.
Michael
create a class that looks something like this:
class structure {
public String data1;
public String data2;
public String data3;
}
This will form your basic data structure that you can use to hold the kind of data you have mentioned in your question. Now, you might want to follow proper object oriented methods like declaring all your fields as private, and writting getters and setters. you can find more on there here ... http://java.dzone.com/articles/getter-setter-use-or-not-use-0
Now, just outside your while loop, create an ArrayList like this: ArrayList<structure> list = new ArrayList<structure>(); This will be used to hold all the different rows of data that you will parse.
Now, in your while loop do something like this:
structure item = new structure();//create a new instance for each row in the text file.
item.data1 = splitOut[0];
item.data2 = splitOut[1];
item.data3 = splitOut[2];
list.add(item);
this will basically take the data that you parse in each row, put in the data structure that you declared by creating a new instance of it for each new row that is parsed. this finally followed by inserting that data item in the ArrayList using the list.add(item) in the code as shown above.
I would create a nice structure to store your information. I'm not sure if how you want to access the data, but here's a nice example. I'll go off of what you previously put. Please note that I only made the variables public because they're final. They cannot change once you make the Course. If you want the course mutable, create getters and setters and change the instance variables to private. After, you can use the list to retrieve any course you'd like.
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[] args) {
try {
FileInputStream fstream = new FileInputStream("courses.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
List<Course> courses = new LinkedList<Course>();
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
if (splitOut.length == 3) {
courses.add(new Course(splitOut[0], splitOut[1],
splitOut[2]));
} else {
System.out.println("Invalid class: " + strLine);
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
public static class Course {
public final String _id;
public final String _name;
public final String _room;
public Course(String id, String name, String room) {
_id = id;
_name = name;
_room = room;
}
}
}
public class File_ReaderWriter {
private static class Structure{
public String data;
}
public static void main(String[] args) throws IOException{
String allDataString;
FileInputStream fileReader = new FileInputStream ("read_data_file.txt");
DataInputStream in = new DataInputStream(fileReader);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(in));
String[] arrayString = {"ID - ", " NAME - ", " ROOM - "};
int recordNumber = 0;
Structure[] structure = new Structure[10];
for (int i = 0; i < 10; i++)
structure[i] = new Structure();
while((allDataString = bufferReader.readLine()) != null){
String[] splitOut = allDataString.split(", ");
structure[recordNumber].data = "";
for (int i = 0; i < arrayString.length; i++){
structure[recordNumber].data += arrayString[i] + splitOut[i];
}
recordNumber++;
}
bufferReader.close();
for (int i = 0; i < recordNumber; i++){
System.out.println(structure[i].data);
}
}
}
I modify your given code. It works. Try it and if any query then ask.
I have a following test file :
Jon Smith 1980-01-01
Matt Walker 1990-05-12
What is the best way to parse through each line of this file, creating object with (name, surname, birthdate) ? Of course this is just a sample, the real file has many records.
import java.io.*;
class Record
{
String first;
String last;
String date;
public Record(String first, String last, String date){
this.first = first;
this.last = last;
this.date = date;
}
public static void main(String args[]){
try{
FileInputStream fstream = new FileInputStream("textfile.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] tokens = strLine.split(" ");
Record record = new Record(tokens[0],tokens[1],tokens[2]);//process record , etc
}
in.close();
} catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerReadFile {
public static void main(String[] args) {
//
// Create an instance of File for data.txt file.
//
File file = new File("tsetfile.txt");
try {
//
// Create a new Scanner object which will read the data from the
// file passed in. To check if there are more line to read from it
// we check by calling the scanner.hasNextLine() method. We then
// read line one by one till all line is read.
//
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
This:
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Could also be changed to
while (scanner.hasNext()) {
String line = scanner.next();
Which will read whitespace.
You could do
Scanner scanner = new Scanner(file).useDelimiter(",");
To do a custom delimiter
At the time of the post, now you have three different ways to do this. Here you just need to parse the data you need. You could read the the line, then split or read one by one and everything 3 would a new line or a new person.
At first glance, I would suggest the StringTokenizer would be your friend here, but having some experience doing this for real, in business applications, what you probably cannot guarantee is that the Surname is a single name (i.e. someone with a double barrelled surname, not hyphenated would cause you problems.
If you can guarantee the integrity of the data then, you code would be
BufferedReader read = new BufferedReader(new FileReader("yourfile.txt"));
String line = null;
while( (line = read.readLine()) != null) {
StringTokenizer tokens = new StringTokenizer(line);
String firstname = tokens.nextToken();
...etc etc
}
If you cannot guarantee the integrity of your data, then you would need to find the first space, and choose all characters before that as the last name, find the last space and all characters after that as the DOB, and everything inbetween is the surname.
Use a FileReader for reading characters from a file, use a BufferedReader for buffering these characters so you can read them as lines. Then you have a choice.. Personally I'd use String.split() to split on the whitespace giving you a nice String Array, you could also tokenize this string.
Of course you'd have to think about what would happen if someone has a middle name and such.
Look at BufferedReader class. It has readLine method. Then you may want to split each line with space separators to construct get each individual field.