I recieve a file each day that:
is stab delimited
has 5 or more columns
has 3 common columns - lastName, firstName, address
Problem: the column order of the file changes regularly
Goal: print column data for lastName, firstName, address regardless of column order
I have been using the following code and manually changing the datavalues to match the columns.
testfile1.txt
1st day file format
ID lastName address phone firstName
45 Gates 111 some lane 777-888-9999 Bill
2nd day file format
address ID phone firstName lastName
111 some lane 81 444-555-1111 John Doe
-
import java.io.BufferedReader;
import java.io.FileReader;
public class test2 {
public static void main(String args[]) throws Exception {
String dataFileName = "C:/testfiles/testfile1.txt";
String line;
int lineNumber = 0;
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
bReader.readLine();
while ((line = bReader.readLine()) != null) {
lineNumber++;
String datavalue[] = line.split("\t");
String lastName = datavalue[1];
String firstName = datavalue[5];
String address = datavalue[3];
System.out.println(lastName + "'" + firstName + "," + address);
}
}
}
This is a first approach. I would try it somehow like this:
int colLastName, colFirstName, colAddress;
line = bReader.readLine();
String columnOrder []= line.split("\t");
for (int i=0; i< columnOrder.length; i++){
if (columnOrder[i].equals("lastName")){
colLastName = i;
}
else if (columnOrder[i].equals("firstName"){
colFirstName = i;
}
else if (columnOrder[i].equals("address"){
colAddress = i;
}
}
while ((line = bReader.readLine()) != null) {
lineNumber++;
String datavalue[] = line.split("\t");
String lastName = datavalue[colLastName];
String firstName = datavalue[colFirstName];
String address = datavalue[colAddress];
System.out.println(lastName + "'" + firstName + "," + address);
}
I think you can try something like below -
import java.io.BufferedReader;
import java.io.FileReader;
public class test2 {
public static void main(String args[]) throws Exception {
String dataFileName = "C:/testfiles/testfile1.txt";
String line;
boolean isFirstColumn = true;
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
int[] order_Fname_Lname_Address = new int[3];
while ((line = bReader.readLine()) != null) {
String datavalue[] = line.split("\t");
if(isFirstColumn) {
for (int i = 0; i < datavalue.length; i++) {
switch (datavalue[i]) {
case "firstName":
order_Fname_Lname_Address[0] = i;
break;
case "lastName":
order_Fname_Lname_Address[1] = i;
break;
case "address":
order_Fname_Lname_Address[2] = i;
break;
}
}
isFirstColumn = false;
continue;
}
String firstName = datavalue[order_Fname_Lname_Address[0]];
String lastName = datavalue[order_Fname_Lname_Address[1]];
String address = datavalue[order_Fname_Lname_Address[2]];
System.out.println(lastName + " " + firstName + "," + address);
}
bReader.close();
}
}
Related
I created a class object array and but now when I try to print it using printf method then it doesn't print those values, I tried checking if the values are correct using println and it works fine with it. One more thing which was weird is that when I pass the end index of the array then it prints them. for example class object array is of size 20 (0-19), when I pass 19th index to the method which prints it then it is working but for 0-18 it is not working.
package com.insurance.company;
import java.util.List;
/**
*
* #author Lenovo
*/
public class InsuranceCompany {
private String companyName;
private String telephone;
private String webAddress;
private double brokerPercentage;
private String description;
private List<String> insuranceTypes;
public InsuranceCompany(){}
public InsuranceCompany(String companyName, String telephone, String webAddress, double brokerPercentage, String description, List<String> insuranceTypes) {
this.companyName = companyName;
this.telephone = telephone;
this.webAddress = webAddress;
this.brokerPercentage = brokerPercentage;
this.description = description;
this.insuranceTypes = insuranceTypes;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(companyName);
sb.append(" " + telephone);
sb.append(" " + webAddress);
for(int i = 0; i < insuranceTypes.size(); i++){
sb.append(" " + insuranceTypes.get(i));
}
sb.append(" " + brokerPercentage);
sb.append(" " + description);
return sb.toString();
}
public String getCompanyName() {
return companyName;
}
public String getTelephone() {
return telephone;
}
public String getWebAddress() {
return webAddress;
}
public double getBrokerPercentage() {
return brokerPercentage;
}
public String getDescription() {
return description;
}
public List<String> getInsuranceTypes() {
return insuranceTypes;
}
}
package com.insurance.company;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InsurancePortal {
//function to load data from file
private static String loadDataFromFile(String path)throws Exception{
String data;
data = new String(Files.readAllBytes(Paths.get(path)));
return data;
}
//function to list all insurance companies
private static void listInuranceCompanies(InsuranceCompany[] company){
System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
System.out.printf("| %3s | %-20s | %-111s |%n", "ID", "Company Name", "Cover Types");
//System.out.flush();
System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
for(int j = 0; j < company.length; j++){
System.out.printf("| %3d | %-20s |", j+1, company[j].getCompanyName());
for(int i = 0; i < 7; i++){
if(i < company[j].getInsuranceTypes().size()){
System.out.printf(" %15S", company[j].getInsuranceTypes().get(i));
}else{
System.out.printf(" %15s", " ");
}
}
System.out.print(" |\n");
System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
}
}
//function to search cover
public static void listSingleCompanyDetails(InsuranceCompany selectedCompany){
System.out.println(selectedCompany.getCompanyName()+"\n--------------------------------------------------");
//System.out.flush();
System.out.printf("| %-18S | %-28S |%n", selectedCompany.getCompanyName(), selectedCompany.getDescription());
//System.out.flush();
System.out.println("--------------------------------------------------");
System.out.println("--------------------------------------------------");
System.out.println("--------------------------------------------------");
System.out.println("--------------------------------------------------");
System.out.println("--------------------------------------------------");
}
public static void main(String arge[]) throws Exception{
String dataFile = System.getProperty("user.dir") + File.separator + "insurance-data.txt";
String[] data = loadDataFromFile(dataFile).split("\n");
/*for(String str: data){
System.out.println(str);
}*/
int rows = data.length;
InsuranceCompany[] company = new InsuranceCompany[rows];
//Initialising objects for every row of data in the file
for(int j = 0; j < rows; j++){
String row = data[j];
//System.out.println(row);
String companyName, telephone, webAddress, description;
double brokerPercentage;
List<String> insuranceTypes = new ArrayList<>();
//Splitting for Company Name
String[] splittedArray = row.split(":", 2);
companyName = splittedArray[0];
row = splittedArray[1];
//Splitting for telephone
splittedArray = row.split(":", 2);
telephone = splittedArray[0];
row = splittedArray[1];
//splitting for web address
splittedArray = row.split(":", 2);
webAddress = splittedArray[0];
row = splittedArray[1];
//splitiing for insurance types
splittedArray = row.split(":", 2);
String[] insuranceTypeList = splittedArray[0].split(",");
for(String str : insuranceTypeList){
insuranceTypes.add(str);
}
row = splittedArray[1];
//splitting for broker percentage
splittedArray = row.split(":", 2);
brokerPercentage = Double.parseDouble(splittedArray[0]);
row = splittedArray[1];
//splitting for description
splittedArray = row.split(":", 2);
description = splittedArray[0];
//System.out.println(companyName+ " " + telephone + " " +webAddress + " " + brokerPercentage + " " + description);
/*for(int i = 0; i < insuranceTypes.size(); i++){
System.out.print(insuranceTypes.get(i)+" ");
}*/
company[j] = new InsuranceCompany(companyName, telephone, webAddress, brokerPercentage, description, insuranceTypes);
//System.out.println(company[j].getCompanyName());
}
boolean run = true;
while(run){
int choice;
Scanner sc = new Scanner(System.in);
System.out.print("\nList insurance companies.......1\n"
+ "Select insurance company.......2\n"
+ "Search cover...................3\n"
+ "Exit...........................0\n"
+ "\nEnter choice:> ");
choice = sc.nextInt();
switch(choice){
case 1 :
listInuranceCompanies(company);
break;
case 2 :
System.out.print("Enter company ID from list [1 - "+(company.length)+"] :> ");
int selectedCompany;
selectedCompany = sc.nextInt();
listSingleCompanyDetails(company[selectedCompany-1]);
break;
case 0 :
System.exit(0);
break;
default: System.out.println("Invalid choice!, please try again.");
}
}
}
}
I'm trying to use the BufferedFileReader to read a Document with saved Information. It's working good, but it always skips the first line of the code. Is it because I'm calling readLine() in the for loop? If so how could I change it?
private void createViewUser() {
String[] stringFirstName = new String[10];
String[] stringName = new String[10];
String[] stringAge= new String[10];
try {
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
for (int i = 0; br.readLine() != null; i++) {
stringFirstName[i] = br.readLine();
stringName[i] = br.readLine();
stringAge[i] = br.readLine();
firstname[i] = new JTextField();
firstname[i].setBounds(100, 100 + 50 * i, 100, 30);
view.add(firstname[i]);
name[i] = new JTextField();
name[i].setBounds(200, 100 + 50 * i, 100, 30);
view.add(name[i]);
age[i] = new JTextField();
age[i].setBounds(300, 100 + 50 * i, 100, 30);
view.add(age[i]);
firstname[i].setText(stringFirstName[i]);
name[i].setText(stringName[i]);
age[i].setText(stringAge[i]);
}
fr.close();
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Exactly, each time before going into the for loop your program reads a line and checks if it is not null.
More you will also skip a line because of this condition. (not sure if it's desired or not)
You kinda got the answer yourself ;)
you're reading first line in the for loop:
for (int i = 0; br.readLine() /* HERE*/ != null; i++) {
You could do something like this:
String line = br.readLine();
for(int i = 0; line != null ; i++){
stringFirstName[i] = line;
line = br.readLine();
}
Hello you can init String var to fix it:
String line = br.readLine();
for (int i = 0; line != null; i++) {
stringFirstName[i] = line;
stringName[i] = br.readLine();
stringAge[i] = br.readLine();
It's doesn't work because it's load first line on for loop verification for (int i = 0; br.readLine() != null; i++) {
Good luck.
Your question involves several steps, but the most important issue for your purposes is how to efficiently and safely read data held in a text file when the data is presented in groups of three lines, something like:
first_name_1
last_name_1
age_1
first_name_2
last_name_2
age_2
first_name_3
last_name_3
age_3
first_name_4
last_name_4
age_4
where of course the names are replaced with real names, and likewise the age_? is replaced with a real number.
If you're going to go the BufferedReader route, I think that the safest thing to do is get all three Strings in each grouping within the while loop's boolean condition, something like:
BufferedReader reader = new BufferedReader(....);
// declare empty Strings first
String firstName = "";
String lastName = "";
String ageString = ""; // need to get age *first* as a String
while ((firstName = reader.readLine()) != null // get all 3 Strings here
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) { // boolean condition ends here
int age = Integer.parseInt(ageString.trim()); // NumberFormatException risk here
// ....
}
This way, if any of the Strings in the text file are missing, the whole while loop ends, and bad data is not obtained.
Other recommendations, create a plain-old Java object to hold your Person data, the names and the age, a class with 3 fields, 2 that are Strings for the names, and one int field for the age. Give it a decent constructor, getter methods.... For example:
public class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
#Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]";
}
}
This way, the while loop above could be used to simply create Person objects:
List<Person> persons = new ArrayList<>(); // an ArrayList of Person to hold the data
while ((firstName = reader.readLine()) != null // get all 3 Strings here
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) { // the while loop ends here
int age = Integer.parseInt(ageString.trim());
Person person = new Person(firstName, lastName, age); // create a new Person object
persons.add(person); // put it into the arraylist
}
OK, how about displaying this information into a JTable -- that's easy.
Create a DefaultTableModel with the correct column names:
private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
and then create a JTable with this model:
private JTable table = new JTable(model);
Then iterate through the ArrayList<Person> and fill our model with data:
for (Person person : personList) {
Vector<Object> rowData = new Vector<>();
rowData.add(person.getFirstName());
rowData.add(person.getLastName());
rowData.add(person.getAge());
model.addRow(rowData);
}
and the JTable is created and filled with data, just like that.
OK, assuming a data file called PersonData.txt that is located in the same directory as our class files, like so:
And assuming that this file holds our data like so:
John
Smith
21
Fred
Flinstone
53
Barny
Rubble
52
Mary
Contrary
22
Bo
Peep
12
Donald
Trump
75
Donald
Duck
40
Mickey
Mouse
45
Minnie
Mouse
41
Ebenezer
Scrooge
80
Bob
Cratchit
33
Ralph
Kramden
55
Alice
Kramden
48
Ed
Norton
54
Then using our Person.java class, we can create a GUI to hold and display our data like so:
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class PersonDisplay extends JPanel {
private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
private static final String PERSON_DATA_PATH = "PersonData.txt";
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
private JTable table = new JTable(model);
public PersonDisplay(List<Person> personList) {
for (Person person : personList) {
Vector<Object> rowData = new Vector<>();
rowData.add(person.getFirstName());
rowData.add(person.getLastName());
rowData.add(person.getAge());
model.addRow(rowData);
}
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
private static void createAndShowGui(List<Person> personList) {
PersonDisplay mainPanel = new PersonDisplay(personList);
JFrame frame = new JFrame("Person Display");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static List<Person> readInPersons(InputStream is) throws IOException {
List<Person> persons = new ArrayList<>();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String firstName = "";
String lastName = "";
String ageString = "";
while ((firstName = reader.readLine()) != null
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) {
int age = Integer.parseInt(ageString.trim());
Person person = new Person(firstName, lastName, age);
persons.add(person);
}
return persons;
}
public static void main(String[] args) {
try {
InputStream inputStream = PersonDisplay.class.getResourceAsStream(PERSON_DATA_PATH);
List<Person> personList = readInPersons(inputStream);
SwingUtilities.invokeLater(() -> createAndShowGui(personList));
} catch (IOException e) {
e.printStackTrace();
}
}
}
and when displayed, it would look like:
I would like to know how can I check for a specific string on a line of a text file, save it in an array, and then move on to the next line of that text file.
For e.g.:
(what he is/ year edition/name/age/profession/number)
competitor 2014 joseph 21 student 20232341
competitor 2013 michael 23 engineer 23425123
As output, it would give me this:
Song Festival'2014
here are the competitors:
Joseph, student of 21 years - 20232341
Song Festival'2013
are the competitors
Michael, engineer of 23 years - 23425123
edit: java language
For this you would use a BufferedReader, you can format things in the text file using the tab (indent) which would be read from the BufferedReader as '\t' I'll write an example for you in a moment.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class StackoverflowExample {
private static final int INFORMATION_CAP = 100;
private static String[][] INFORMATION = new String[INFORMATION_CAP][INFORMATION_CAP];
public StackoverflowExample() {
String currentLine;
String[] textData;
int lineID = 0;
boolean endOfFile = false;
try {
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
currentLine = reader.readLine();
while(!endOfFile && currentLine != null) {
currentLine = currentLine.trim();
textData = currentLine.split("\\t");
String userType = textData[0];
String year = textData[1];
String name = textData[2];
String age = textData[3];
String profession = textData[4];
String number = textData[5];
INFORMATION[lineID] = new String[] { userType, year, name, age, profession, number };
lineID++;
currentLine = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new StackoverflowExample();
for(int i = 0; i < INFORMATION.length; i++) {
System.out.println("Type: " + INFORMATION[i][0] +
"year: " + INFORMATION[i][1] +
"name: " + INFORMATION[i][2] +
"age: " + INFORMATION[i][3] +
"profession: " + INFORMATION[i][4] +
"number: " + INFORMATION[i][5]);
}
}
}
Create a text file called "textfile.txt" in your projects main directory, and format it like this
type(tab)year(tab)name(tab)age(tab)profession(tab)number(newline)
In the input file, there are 2 columns: 1) stem, 2) affixes. In my coding, i recognise each of the columns as tokens i.e. tokens[1] and tokens[2]. However, for tokens[2] the contents are: ng ny nge
stem affixes
---- -------
nyak ng ny nge
my problem here, how can I declare the contents under tokens[2]? Below are my the snippet of the coding:
try {
FileInputStream fstream2 = new FileInputStream(file2);
DataInputStream in2 = new DataInputStream(fstream2);
BufferedReader br2 = new BufferedReader(new InputStreamReader(in2));
String str2 = "";
String affixes = " ";
while ((str2 = br2.readLine()) != null) {
System.out.println("Original:" + str2);
tokens = str2.split("\\s");
if (tokens.length < 4) {
continue;
}
String stem = tokens[1];
System.out.println("stem is: " + stem);
// here is my point
affixes = tokens[3].split(" ");
for (int x=0; x < tokens.length; x++)
System.out.println("affix is: " + affixes);
}
in2.close();
} catch (Exception e) {
System.err.println(e);
} //end of try2
You are using tokens as an array (tokens[1]) and assigning the value of a String.split(" ") to it. So it makes things clear that the type of tokens is a String[] array.
Next,
you are trying to set the value for affixes after splitting tokens[3], we know that tokens[3] is of type String so calling the split function on that string will yield another String[] array.
so the following is wrong because you are creating a String whereas you need String[]
String affixes = " ";
so the correct type should go like this:
String[] affixes = null;
then you can go ahead and assign it an array.
affixes = tokens[3].split(" ");
Are you looking for something like this?
public static void main(String[] args) {
String line = "nyak ng ny nge";
MyObject object = new MyObject(line);
System.out.println("Stem: " + object.stem);
System.out.println("Affixes: ");
for (String affix : object.affixes) {
System.out.println(" " + affix);
}
}
static class MyObject {
public final String stem;
public final String[] affixes;
public MyObject(String line) {
String[] stemSplit = line.split(" +", 2);
stem = stemSplit[0];
affixes = stemSplit[1].split(" +");
}
}
Output:
Stem: nyak
Affixes:
ng
ny
nge
I have a problem with my code. I need to do several operations on a log file with this structure:
190.12.1.100 2011-03-02 12:12 test.html
190.12.1.100 2011-03-03 13:18 data.html
128.33.100.1 2011-03-03 15:25 test.html
128.33.100.1 2011-03-04 18:30 info.html
I need to get the number of visits per month, number of visits per page and number of unique visitors based on the IP. That is not the question, I managed to get all three operations working. The problem is, only the first choice runs correctly while the other choices just return values of 0 afterwards, as if the file is empty, so i am guessing i made a mistake with the I/O somewhere. Here's the code:
import java.io.*;
import java.util.*;
public class WebServerAnalyzer {
private Map<String, Integer> hm1;
private Map<String, Integer> hm2;
private int[] months;
private Scanner input;
public WebServerAnalyzer() throws IOException {
hm1 = new HashMap<String, Integer>();
hm2 = new HashMap<String, Integer>();
months = new int[12];
for (int i = 0; i < 12; i++) {
months[i] = 0;
}
File file = new File("webserver.log");
try {
input = new Scanner(file);
} catch (FileNotFoundException fne) {
input = null;
}
}
public String nextLine() {
String line = null;
if (input != null && input.hasNextLine()) {
line = input.nextLine();
}
return line;
}
public int getMonth(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
if (dtok.countTokens() == 3) {
String year = dtok.nextToken();
String month = dtok.nextToken();
String day = dtok.nextToken();
int m = Integer.parseInt(month);
return m;
}
}
return -1;
}
public String getIP(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
return ip;
}
return null;
}
public String getPage(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
return page;
}
return null;
}
public void visitsPerMonth() {
String line = null;
do {
line = nextLine();
if (line != null) {
int m = getMonth(line);
if (m != -1) {
months[m - 1]++;
}
}
} while (line != null);
// Print the result
String[] monthName = {"JAN ", "FEB ", "MAR ",
"APR ", "MAY ", "JUN ", "JUL ", "AUG ", "SEP ",
"OCT ", "NOV ", "DEC "};
for (int i = 0; i < 12; i++) {
System.out.println(monthName[i] + months[i]);
}
}
public int count() throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream("webserver.log"));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n')
++count;
}
}
return count;
} finally {
is.close();
}
}
public void UniqueIP() throws IOException{
String line = null;
for (int x = 0; x <count(); x++){
line = nextLine();
if (line != null) {
if(hm1.containsKey(getIP(line)) == false) {
hm1.put(getIP(line), 1);
} else {
hm1.put(getIP(line), hm1.get(getIP(line)) +1 );
}
}
}
Set set = hm1.entrySet();
Iterator i = set.iterator();
System.out.println("\nNumber of unique visitors: " + hm1.size());
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + " - ");
System.out.println(me.getValue() + " visits");
}
}
public void pageVisits() throws IOException{
String line = null;
for (int x = 0; x <count(); x++){
line = nextLine();
if (line != null) {
if(hm2.containsKey(getPage(line)) == false)
hm2.put(getPage(line), 1);
else
hm2.put(getPage(line), hm2.get(getPage(line)) +1 );
}
}
Set set = hm2.entrySet();
Iterator i = set.iterator();
System.out.println("\nNumber of pages visited: " + hm2.size());
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + " - ");
System.out.println(me.getValue() + " visits");
}
}
Any help figuring out the problem would be much appreciated as I am quite stuck.
I didn't read the code thoroughly yet, but I guess you're not setting the read position back to the beginning of the file when you start a new operation. Thus nextLine() would return null.
You should create a new Scanner for each operation and close it afterwards. AFAIK scanner doesn't provide a method to go back to the first byte.
Currently I could also think of 3 alternatives:
Use a BufferedReader and call reset() for each new operation. This should cause the reader to go back to byte 0 provided you didn't call mark() somewhere.
Read the file contents once and iterate over the lines in memory, i.e. put all lines into a List<String> and then start at each line.
Read the file once, parse each line and construct an apropriate data structure that contains the data you need. For example, you could use a TreeMap<Date, Map<Page, Map<IPAdress, List<Visit>>>>, i.e. you'd store the visits per ip address per page for each date. You could then select the appropriate submaps by date, page and ip address.
The reset method of BufferedReader that Thomas recommended would only work if the file size is smaller than the buffer size or if you called mark with a large enough read ahead limit.
I would recommend reading throught the file once and to update your maps and month array for each line. BTW, you don't need a Scanner just to read lines, BufferedReader has a readLine method itself.
BufferedReader br = ...;
String line;
while (null != (line = br.readLine())) {
String ip = getIP(line);
String page = getPage(line);
int month = getMonth(line);
// update hashmaps and arrays
}