I have a 2d array being written to a file from another method. I've defined the contents of the 2d array in my sightings method, but when it passes over to the save method the contents (in at least block [1] [1]) become null. How do I go about making sure the value remains defined?
My code so far:
(Sightings Method)
public void Sighting()
{
Scanner input = new Scanner (System.in);
String MigChoice; //initiates Migrant Choice variable to be stored
String Trail; //initiates Trail to be stored
String NumberSeen; //initiates number to be stored
String Species; //initiates species to be stored
String Date; //initiates date to be stored
String[][] EntryList;
EntryList = new String [500][5];
System.out.print("What species of bird was observed?\n");
Species = input.nextLine();
System.out.print("What trail did this spotting take place on?\nDirectory:\n");
System.out.println("1). Alligator Alley");
System.out.println("2). Eagle Roost");
System.out.println("3). Heron Hideout");
System.out.println("4). Lost Bridge Trail");
System.out.println("5). Marsh Rabbit Run");
System.out.println("6). Otter");
System.out.println("7). Shady Oak");
System.out.println("8). Wading Bird Way");
System.out.println("9). Windmill Whisper");
Trail = input.nextLine();
System.out.println("The species is:\n1.)Migrant\n2.)Residential");
System.out.print("Please enter Migrant or Residential: ");
MigChoice = input.next();
System.out.print("What was the time of this sighting (in mm/dd/yyyy format)?\n");
Date = input.next();
System.out.print("Finally, how many birds were observed?\n");
NumberSeen = input.next();
EntryList [0][0] = Species;
EntryList [0][1] = Trail;
EntryList [0][2] = MigChoice;
EntryList [0][3] = Date;
EntryList [0][4] = NumberSeen;
Save(EntryList);
System.out.print("Thank you for adding an entry!");
System.out.println("Returning to main menu");
Menu();
}
(Save Method)
public void Save(String[][] EntryList) {
try {
String[][] content = EntryList;
File file = new File("CBB.dat");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
if (EntryList[0][0] != null) {
DataInputStream instream;
DataOutputStream outstream;
instream = new DataInputStream(new BufferedInputStream(
new FileInputStream(file))); // buffers the data stream
outstream = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(file)));
FileWriter fw = new FileWriter("CBB.dat", true);
BufferedWriter writer = new BufferedWriter(fw);
for (int row = 0; row < EntryList.length; row++) {
outstream.writeUTF(EntryList[row][0]);
outstream.writeUTF(EntryList[row][1]);
outstream.writeUTF(EntryList[row][2]);
outstream.writeUTF(EntryList[row][3]);
outstream.writeUTF(EntryList[row][4]);
}
outstream.close();
} else
System.out.print("Something is wrong");
} catch (IOException e) {
e.printStackTrace();
}
}
Error Message:
java.lang.NullPointerException
at java.io.DataOutputStream.writeUTF(DataOutputStream.java:330)
at java.io.DataOutputStream.writeUTF(DataOutputStream.java:306)
at Dossier.Save(Dossier.java:158)
at Dossier.Sighting(Dossier.java:133)
The writeUTF will be throw NullPointerException if you pass a null object as parameter.
Writes two bytes of length information to the output stream, followed
by the modified UTF-8 representation of every character in the string
s. If s is null, a NullPointerException is thrown. Each character in
the string s is converted to a group of one, two, or three bytes,
depending on the value of the character.
You can add null check if your loop:
for (int row = 0; row < EntryList.length; row++)
{
for(int col = 0; col < EntryList[row].length;col++) {
if(EntryList[row][col] != null)
outstream.writeUTF(EntryList[row][col]);
}
}
Related
The file contains two strings on different lines then two ints on the same line which are all used in the constructor for an array based on a class in my program called Flight.
Scanner fileIn = null;
try
{
fileIn = new Scanner(new File("flights.txt"));
}catch(FileNotFoundException e) {
throw new IllegalArgumentException("File was not found");
}
int count = 0;
while(fileIn.hasNextLine())
{
fileIn.nextLine();
count += 1;
}
flights = new Flight[count/3];
count = 0;
while(fileIn.hasNextLine())
{
String name = fileIn.nextLine();
String des = fileIn.nextLine();
int h = fileIn.nextInt(); //the two ints that im taking in are on the same line seperated by a space
int m = fileIn.nextInt();
Time t = new Time(h, m);
flights[count] = new Flight(name,des,t); //I need the data to be saved into this array based on the Flight class
count++;
}
So I have created this method which at the end displays the whole line because i am displaying the array after converting and editing it. So my Question is how can i know overwrite the array to the same line i grabbed it from. thanks in advance and here is my code.
public void getData(String path, String accountNumber) {
try {
FileInputStream fis = new FileInputStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
System.out.println("Please Enter the Deposit amount That you would like to add.");
Scanner sn = new Scanner (System.in);
int add = sn.nextInt();
String str;
while ((str = br.readLine()) != null) {
if (str.contains(accountNumber)) {
String[] array = str.split(" ");
int old = Integer.parseInt(array[3]);
int Sum= old + add;
String Sumf = Integer.toString(Sum);
array[3] = Sumf;
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);}
break;
}
}
} catch (Exception ex) {
System.out.println(ex);
}
}
i am using string accountNumber to grab the specific line that i need. after getting the line i am changing it to an array while splitting the index with str.split(" "); . After that i know that i need to edit index number [3]. so i do so and then i put it back into the array. the final thing i need to do is to right the array back now.
You can keep track of the input from the file you are reading and write it back with the modified version.
public void getData(String path, String accountNumber) {
try {
FileInputStream fis = new FileInputStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
System.out.println("Please Enter the Deposit amount That you would like to add.");
Scanner sn = new Scanner (System.in);
int add = sn.nextInt();
String line; // current line
String input = ""; // overall input
while ((line = br.readLine()) != null) {
if (line.contains(accountNumber)) {
String[] array = line.split(" ");
int old = Integer.parseInt(array[3]);
int Sum= old + add;
String Sumf = Integer.toString(Sum);
array[3] = Sumf;
// rebuild the 'line' string with the modified value
line = "";
for (int i = 0; i < array.length; i++)
line+=array[i]+" ";
line = line.substring(0,line.length()-1); // remove the final space
}
// add the 'line' string to the overall input
input+=line+"\n";
}
// write the 'input' String with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream(path);
fileOut.write(input.getBytes());
fileOut.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
This is how i understand the question that you have a file you will read it line by line and will make some changes and want to write it again at the same position. Create a new temp file and write the contents to the temp file, if changed write the changed result if not write it as it is.
And at last rename the temp to your original file name
I am trying to create a split() method that reads a file, line by line, then separates the Strings and Integers into an array that is then written to another file. I have created an array to hold each String called list and one to hold the Integers called scores.
When I try to run my code, it reaches the second element in the list array which is surname = list[1] and then I get the error.
What I am trying to eventually do is split each element and get the average of the Integers so the original line of text would read Mildred Bush 45 65 45 67 65 and my new line of text would read Bush, Mildred: Final score is x.xx.
The error happens at line 7 surname = list[1];
My code:
public void splitTest()
{
String forename, surname, tempStr, InputFileName, OutputFileName;
tempStr = "";
String[] list = new String[6];
list = tempStr.split(" ");
forename = list[0];
surname = list[1];
int[] scores = new int[5];
scores[0] = Integer.parseInt(list[2]);
scores[1] = Integer.parseInt(list[3]);
scores[2] = Integer.parseInt(list[4]);
scores[3] = Integer.parseInt(list[5]);
scores[4] = Integer.parseInt(list[6]);
FileReader fileReader = null;
BufferedReader bufferedReader = null;
FileOutputStream outputStream = null;
PrintWriter printWriter = null;
clrscr();
System.out.println("Please enter the name of the file that is to be READ (e.g. details.txt) : ");
InputFileName = Genio.getString();
System.out.println("Please enter the name of the file that is to be WRITTEN TO (e.g. newDetails.txt) : ");
OutputFileName = Genio.getString();
try {
fileReader = new FileReader(InputFileName);
bufferedReader = new BufferedReader(fileReader);
outputStream = new FileOutputStream(OutputFileName);
printWriter = new PrintWriter(outputStream);
tempStr = bufferedReader.readLine();
while (tempStr != null) {
System.out.println(tempStr);
printWriter.write(tempStr+"\n");
tempStr = bufferedReader.readLine();
}
System.out.println("\n\nYOUR NEW FILE DATA IS DISPLAYED ABOVE!\n\n");
pressKey();
bufferedReader.close();
printWriter.close();
} catch (IOException e) {
System.out.println("Sorry, there has been a problem opening or reading from the file");
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
System.out.println("An error occurred when attempting to close the file");
}
}
if(printWriter != null) {
printWriter.close();
}
}
}
Where it says Genio, this a class that deals with user input.
You initialize the list array with
list = tempStr.split(" ");
The size of that array can be anything. It depends on the number of spaces in tempStr.
You have to check the length of list before accessing its elements.
If you expect the input to contain a certain number of parameters, add a check :
list = tempStr.split(" ");
int[] scores = new int[5];
if (list.length > 6) {
forename = list[0];
surname = list[1];
scores[0] = Integer.parseInt(list[2]);
scores[1] = Integer.parseInt(list[3]);
scores[2] = Integer.parseInt(list[4]);
scores[3] = Integer.parseInt(list[5]);
scores[4] = Integer.parseInt(list[6]);
}
This would prevent the exception. Of course, you have to decide how to handle the situation in which the condition is false.
EDIT :
tempStr = "";
This means there would be exactly one element in list. I'm assuming you meant to put some actual value in this variable.
I have the following code which tries to determine the dimensions of a file, but each time it executes through there is this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
I'm unaware why this is occurring. Can anyone help debug the issue? And explain why it is happening?
public void loadDistances(String fname) throws Exception {
String file = fname;
File f = new File(file);
Scanner in = null;
try {
in = new Scanner(f);
}
catch (FileNotFoundException ex) {
System.out.println("Can't find file " + file);
System.exit(1);
}
int rows = 0;
int cols = 0;
int elements = 0;
while(in.hasNext()){
while(in.next() != null){
System.out.println(elements++);
}
in.nextLine();
rows++;
}
in.close();
cols = (elements + 1) / rows;
// for debug purposes
System.out.println(rows);
System.out.println(cols);
}
Which reads in this file
0 2 3.0
1 0 2.0
2 1 7.0
2 3 1.0
3 0 6.0
// Checking for suggested answer
int tokens = 0;
String line;
Scanner tokenScanner;
Scanner fileScanner;
Scanner lineScanner;
while(fileScanner.hasNextLine()){
line = fileScanner.nextLine();
lineScanner.nextLine() = line;
while(lineScanner.hasNext()){
tokens++;
}
rows++;
}
You assign no data to your variables at all in your scanning loop, and not only that, but you read from the Scanner twice while checking it for data only once, a dangerous thing to do.
while(in.hasNext()){ // **** checking once ****
while(in.next() != null){ // **** read in and waste a token here!
System.out.println(elements++);
}
in.nextLine(); // **** read in and waste a line here
rows++;
}
in.close();
I would:
Use two Scanner variables, one, fileScanner, to read in each line of text in the file,...
And one called lineScanner to read in each token on the line.
I'd use an outer while loop, that checks fileScanner.hasNextLine(), and then calls nextLine() to read the line into a String, say called line.
I'd then create a new Scanner with the line of String created, and assign it into a lineScanner variable.
I'd use an inner while loop that loops while lineScanner.hasNext(), and reads in the data into your your variables.
I'd close the inner lineScanner at the end of the outer while loop so as not to waste resources.
Alternatively, you could use String#split(...) to split the tokens in the line read in, and then parse the Strings into numbers. For example,
public List<RowData> loadDistances(String fname)
throws FileNotFoundException, NumberFormatException {
File file = new File(fname);
Scanner fileScanner = new Scanner(file);
List<RowData> rowList = new ArrayList<RowData>();
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
String[] tokens = line.split("\\s+");
if (tokens.length != 3) {
// throw some custom exception
}
int rowNumber = Integer.parseInt(tokens[0].trim());
int xData = Integer.parseInt(tokens[1].trim());
double yData = Double.parseDouble(tokens[2].trim());
rowList.add(new RowData(rowNumber, xData, yData));
}
if (fileScanner != null) {
fileScanner.close();
}
return rowList;
}
Edit
By using a line Scanner, I recommend creating a second Scanner, passing in the line obtained from the first Scanner, and extracting data from this second Scanner. You could use a while loop if you didn't know how many tokens to expect, but your data appears to be well defined, with each line holding an int, int, and double, and we can use this information to help us extract the proper data. You could use code something like this:
// use previous same code as above except in the while loop:
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine(); // get line
Scanner lineScanner = new Scanner(line); // create Scanner with it
int rowNumber = 0;
int xData = 0;
double yData = 0.0;
if (lineScanner.hasNextInt()) {
rowNumber = lineScanner.nextInt();
} else {
// throw a custom exception since int not found
}
if (lineScanner.hasNextInt()) {
xData = lineScanner.nextInt();
} else {
// throw a custom exception since int not found
}
if (lineScanner.hasNextDouble()) {
yData = lineScanner.nextDouble();
} else {
// throw a custom exception since double not found
}
rowList.add(new RowData(rowNumber, xData, yData));
if (lineScanner != null) {
lineScanner.close();
}
}
For a homework assignment, I need to create a class that that can read and write Byte arrays to/from a file. I have successfully created classes that can read and write CSV and text, however I am having some difficulty, when it comes to arrays. The code below is features the class that I have written. It is largely based on my CSV class, the FileInput class http://www.devjavasoft.org/SecondEdition/SourceCode/Share/FileInput.java) and FileOutput Class (http://www.devjavasoft.org/SecondEdition/SourceCode/Share/FileOutput.java).
When running the program to read a text file I get the following error message:
"Exception in thread "main" java.lang.NullPointerException
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:101)
at java.io.FileReader.<init>(FileReader.java:58)
at com.gc01.FileManager.FileInput.<init>(FileInput.java:22)
at com.gc01.FileManager.ByteManager.readByte(ByteManager.java:28)
at com.gc01.FileManager.ByteManager.main(ByteManager.java:85)"
And my code:
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ByteManager {
public String getByteFile(){
Scanner sc = new Scanner (System.in);
System.out.println("Please enter the file directory of the chosen txt file?");
System.out.println("For Example: /Users/UserName/Downloads/FileName.txt");
///Users/ReeceAkhtar/Desktop/FileName.txt
final String fileName = sc.nextLine();
System.out.println("How many columns are in the file?");
final int columns = sc.nextByte();
System.out.println("How many rows are in the file?");
final int rows = sc.nextByte();
return fileName;
}
public void readByte(final String fileName, int columns, int rows){
FileInput in = new FileInput(fileName);
int [] [] data = new int[rows] [columns];
String [] line;
for (int i = 0; i < rows; i++){
line = in.readString().split("\t");
for (int j = 0; j < columns; i++){
data [i][j] = Byte.parseByte(line[j]);
}
}
System.out.println("******File Read*****");
}
public String chooseFileOutput(){
Scanner sc = new Scanner (System.in);
System.out.println("Please enter the file directory for the output of the chosen file");
System.out.println("For Example: /Users/UserName/Downloads/FileName.txt");
///Users/ReeceAkhtar/Desktop/GeoIPCountryWhois.csv
final String fileNameOUT = sc.nextLine();
System.out.println("How many columns are in the file?");
final int columnsOut = sc.nextByte();
System.out.println("How many rows are in the file?");
final int rowsOut = sc.nextByte();
return fileNameOUT;
}
public void writeByte(final String fileNameOUT, int columnsOut, int rowsOut){
FileOutput createData = new FileOutput (fileNameOUT);
int newData = 0;
System.out.println("Enter data. To finish, enter 'TERMINATE_FILE'");
while(!"TERMINATE_FILE".equals(newData)){
Scanner input = new Scanner (System.in);
int [] [] data = new int[rowsOut] [columnsOut];
String [] line = null;
for (int i = 0; i < rowsOut; i++){
createData.writeInteger(newData = input.nextByte());
System.out.println("\t");
for (int j = 0; j < columnsOut; i++){
data [i][j] = Byte.parseByte(line[j]);
}
}
createData.close();
}
}
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
final ByteManager object = new ByteManager ();
System.out.println("1 for Read File, 2 for Write file");
String choice = in.nextLine();
if("1".equals(choice)){
object.getByteFile();
object.readByte(null, 0, 0);
} else if ("2".equals(choice)){
object.chooseFileOutput();
object.writeByte(null, 0, 0);
} else{
System.out.println("Goodbye!");
System.exit(0);
}
}
}
UPDATE
Thank you for your comments and advice below, I have now run into a another problem that I can not work out. I have re-written my readByte method. However when I now run it, I no longer get compiler errors (thanks to your advice), however I can not get the contents of the file to print. Instead the console just displays "File Read". I have studied various resources yet I can not find the solution. I am sure it is a simple mistake somewhere. The contents of the file I am trying to read is also below.
public String getByteFile(){
Scanner sc = new Scanner (System.in);
System.out.println("Please enter the file directory of the chosen txt file?");
System.out.println("For Example: /Users/UserName/Downloads/FileName.txt");
///Users/ReeceAkhtar/Desktop/FileName.txt
final String fileName = sc.nextLine();
System.out.println("How many columns are in the file?");
final int columns = sc.nextInt();
System.out.println("How many rows are in the file?");
final int rows = sc.nextInt();
return fileName;
}
public void readByte(final String fileName, int rows,int columns){
BufferedReader br = null;
String[] line;
String splitBy = "\t";
int [][] data = new int[rows] [columns];
try {
br = new BufferedReader(new FileReader(fileName));
for (int i = 0; i < rows; i++){
line = br.toString().split(splitBy);
for (int j = 0; j < columns; j++){
data[i] [j] = Integer.parseInt(line[j]);
System.out.println(data[i][j]);
}
}
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("*****File Read*****");
}
File Contents (separated by tab)
123 6565
123 6564
123 6563
123 6562
This code is the source of the error
object.readByte(null, 0, 0);
The parameter null is invalid state for FileInput. It should be a file name string.
You are passing null argument to readByte() from main()
object.readByte(null, 0, 0);
And in readByte()
FileInput in = new FileInput(fileName); //here it throws NPE
Pass valid file name.
NullPointerException
public class NullPointerException
extends RuntimeException
Thrown when an application attempts to use null in a case where an object is required. These include:
Calling the instance method of a null object.
Accessing or modifying the field of a null object.
Taking the length of null as if it were an array.
Accessing or modifying the slots of null as if it were an array.
Throwing null as if it were a Throwable value.