Saving array into the file (Java) - java

I need to solve such task:
Randomly generate the length of the array - save this int into file ("input.txt)" as a first digit;
Randomly generate array elements - save each element into the file ("input.txt")
But the array elements won't save into file.
As I can see from console array has got digits, but they don't save into file.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
new Main().run();
}
Random rand;
Scanner sc;
PrintWriter pr, pr2;
public void run() throws FileNotFoundException {
pr2 = new PrintWriter(new File("input.txt"));
pr = new PrintWriter(new File("output.txt"));
rand = new Random();
int a = rand.nextInt((int) Math.pow(10, 3));
System.out.println(a);
pr2.print(a);
pr2.close();
sc = new Scanner(new File("input.txt"));
int[] arr = new int[a];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt((int) Math.pow(10, 3));
}
for (int i = 0; i < arr.length; i++) {
System.out.println("" + i + ": " + arr[i]);
pr2.print(arr[i]);
}
pr2.close();
return;
}
}

You're closing the stream with pr2.close(); and then trying to print something through it. Then you close it again. Remove the first pr2.close(); And it should all work.
Also you're having unnecessary Scanner object and second PrintWriter.

Your problem is that you're calling pr2.close() right after you write the length of the array. Once you close the PrintWriter, it will no longer allow anything to be written to the file; thus, when you later try to write the values in the array to pr2, pr2 says, "gosh, I know this guy wants me to write something but I'm closed, I just can't do it!" and so nothing gets written.
The PrintWriter works by storing all of your write(...) and print(...) calls into memory, and then actually writing them into your text file when you call the close() or flush() method. Although it's not necessary, if you wanted functional similarity to your current use of the first close() call, you could use flush() instead, but make sure that you do call close() when you are completely done using the Scanner (otherwise you're just asking for a memory leak).

Related

Scan array of doubles in a file | Java

I was trying to scan a file that has an array of doubles. I'm using the code below but it's only outputting 0.0 for every entry. Why is this and how can I fix it?
Scanner scanner = new Scanner("file.txt");
double[] array = new double[256 * 256];
for (int i = 0; i < array.length; i++) {
if (scanner.hasNextDouble()) {
array[i] = scanner.nextDouble();
}
}
System.out.println(array[0]);
An example of the file I'm scanning is
0.22131145 0.22131145 0.22131145 0.22841525 0.22841525 ...
The main issue is with the instantiation of the Scanner object. In this case you need to pass a File object into it, not just a string, and make sure you specify the correct file path. Refer to the official documentation for advice.
Secondly, you need to use a while-loop. An if-statement will execute only once, but you would want the Scanner to continue looking whilst there is info inside the file.
Thirdly, don't use an array for storing the values. It's too risky because you need to know the size of the array beforehand, meaning that you would need to loop twice, which would be inefficient, or you are hard coding, as you are doing here. If someone were to add or remove values from the file, you will get unexpected results. Rather use a dynamic data structure such as a List.
public static void main(String[] args) throws FileNotFoundException {
String filepath = "file.txt";
Scanner scanner = new Scanner(new File(filepath));
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(Double.valueOf(scanner.next()));
}
scanner.close();
System.out.println(list.get(0));
}
There are four problems with your code:
Blocker: Scanner expects a File object but you haven't used it in this way. You need to use the following syntax:
Scanner scanner = new Scanner(new File("file.txt"));
Performance: You can improve the performance of your program by including scanner.hasNextDouble() in the condition which checks the value of i, as shown below:
for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
array[i] = scanner.nextDouble();
}
This will terminate the loop as soon as scanner.hasNextDouble() returns false; otherwise, the loop in your code will continue to run until i < array.length evaluates to false irrespective of the value returned by scanner.hasNextDouble().
Resource leak: You have not closed the Scanner object. Put the following line after the loop finishes:
scanner.close();
Missed functionality: You haven't printed the complete array. Your statement, System.out.println(array[0]) will print only the first element in the array. Change it as follows to print the complete array:
System.out.println(Arrays.toString(array));
Given below the code incorporating all the above-mentioned comments:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("file.txt"));
double[] array = new double[256 * 256];
for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
array[i] = scanner.nextDouble();
}
scanner.close();
System.out.println(Arrays.toString(array));
}
}
Memory utilization: You have used a fixed-sized array which is fine if the number of elements to be stored is equal to the size of the array. However, if it is not the case (i.e. if the number of elements to be stored can be less than or more than the specified size), you should use a Collection e.g. an ArrayList which is a kind of dynamic array. This will help you in many ways: (a) You will save memory if the number of elements to be stored is less than the specified size (b) You do not need to change your code in order to increase the size of the array when you need to store more elements than you have already specified (c) The Collection provides with a rich API to deal with elements. By leveraging this API, your code can be crisp, more performant, maitainable etc.
Given below the code incorporating the 5th point:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("file.txt"));
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(scanner.nextDouble());
}
scanner.close();
System.out.println(list);
}
}

Java read integer arrays from multiple files

I'm relatively new to Java, so I have to look up how to do things constantly. I'm working on a project that involves analyzing a number of familiar sorts such as heap sort, merge sort, etc. I wrote a bit of code to produce a variety of different arrays, each in their own .txt file. Here is a portion of the code:
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
public class ArrayBuilder {
public static void main(String[] args) throws IOException {
for(int i = 2; i < 7; i++) {
int aLength = (int)Math.pow(10, i);
buildAscendingArray(aLength);
buildDescendingArray(aLength);
buildRandomArray(aLength);
}
}
public static void buildAscendingArray(int arrayLength) throws IOException {
File file = new File("arrays_" + arrayLength + "A.txt");
PrintWriter printWriter = new PrintWriter(file);
int[] array = new int[arrayLength];
for(int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
printWriter.println(Arrays.toString(array));
printWriter.close();
}
I didn't include the random and descending methods as they are more or less the same so trying to save room. So...
I already have all the sorts coded, I'm just trying to figure out how to read in the integer arrays so I can run them through the different sorts. I'm also trying to factor adding in System.nanoTime() to clock the time it takes to run each sort so I can compare them given the various inputs. Not sure if this needs to be added into the method for each sort or whether it can be implemented in the call ie. System.nanoTime(heapsort(array))) ?
Ultimately I'm looking for some help on getting the .txt files into a usable array in order to pass it through each sort. I output all to text files in the first place to make sure the exact same array is run through each sort.
I'm somewhat familiar with Scanner, but have also read about FileRead and/or BufferedReader and possibly some other approaches. I'm just not experienced enough to know what would work best in this situation and the best way to implement it. Help would be much appreciated.
If you just need to save arrays to file storage and construct them back you can use serialization.
This class is just to give you an idea of how it would work.
public class ArrayReaderWriter {
public static void main(String[] args) throws Exception {
writeArray(20);
readArray(20);
}
public static void writeArray(int arrayLength) throws IOException {
File file = new File("arrays_" + arrayLength + "A.ser");
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
int[] array = new int[arrayLength];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
os.writeObject(array);
}
public static void readArray(int arrayLength) throws IOException, ClassNotFoundException {
File file = new File("arrays_" + arrayLength + "A.ser");
ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
int[] array = (int[]) is.readObject();
// Printing here to verify
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Note: I can understand saving the random array if you want to run the different sorts with the same array in different executions. But the ascending and descending arrays can always be constructed on every execution.
Regarding System.nanoTime()
See https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime-- for a detailed explanation.
EDIT
If you have already generated the text files use #Antoniossss solution. You will only need to modify the delimiter as I mentioned in my comment since you are reading existing files.
Test
Scanner scanner = new Scanner("[1, 2, 3]");
scanner.useDelimiter("(\\s)*[\\[,\\]](\\s)*");
while(scanner.hasNextInt()) {
System.out.println(scanner.nextInt());
}
Output
1
2
3
Use some delimetered file format for such purposes and read it using scanner.
Lets say our delimeter is character is ;. Store your array like this
File file = new File("arrays_" + arrayLength + "A.txt");
PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
printWriter.print(1);
for(int i = 1; i < array.length; i++) {
printWriter.print(';'); // delimeter
printWriter.print(i+1);
}
printWriter.close();
To read it back, use Scanner in simillar way to the following code;
ArrayList<Integer> arr=new ArrayList<>();
Scanner scan=new Scanener(new File("yourfile));
scan.useDelimeter(';');
while(scan.hasNextInt()){
arr.add(scan.nextInt());
}
Should work just fine. You can always use a newline as a delimeter as well.
EDIT: If you dont need to have array storred in human readable form, you can use serialization just like #Shire Resident explained in his answer.

Getting Objects From A Text File

I have a text file like this;
7-Georgia
1-Andrew
6-John
8-Luke
9-Erica
3-Kim
2-Jude
5-Phil
4-Leo
The first column is id and second is name. How can I get these id's and names? So far I wrote this;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class Main {
#SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
#SuppressWarnings("unused")
Scanner fromFile = new Scanner(new File("id_name.txt"));
fromFile.useDelimiter("-");
while(fromFile.hasNext()){
String temp = fromFile.next();
System.out.println(temp);
}
while(fromFile.hasNext()){
String temp= fromFile.next();
int[] fileID;
fileID= new int[9];
for(int i=0; i<9; i++){
fileID[i]= Integer.parseInt(temp);
}
System.out.println(fileID);
}
}
}
But this doesn't get the id's. I'm not sure how to fix this, I'd be grateful if you help me.
You have two while loops in your code. Typically one while loop will go through every item until the condition is no longer true. I think you need to rework this to have a better "flow of control" which might mean using only one while loop (with sections to grab the number and then the name.
I imagine that you are looking for results from the second while loop, but by the time you get to it, the first while loop will have exhausted all of your data.
Finally, printing an array will print out the array reference identifier. If you want to actually print the contents of the array, you need a loop over the elements within the array, and you need to print out each array element explicitly.
As an alternative to the array printing technique above (which you should master), you can also use the Arrays.toString(<insert array here>) method call. However, in many cases it will give you a format that is not desired. That's why you need to know the above technique too.
Also, you have one hidden issue. You (in the second while loop) make the assumption that there are only nine inputs. Pay close attention to what you are writing. Every time you have to reach for a number, consider whether it is a "magic" number. Magic numbers are numbers that are in your code with no explanation or reason why they exist. They are indicators of errors in the code made by assumptions that probably won't last the test of time.
For example, you are using the number 9 because you have seen the input file. The next input file will probably not have nine entries in it, and your program will probably not work right if you gave it an input with eight entries, or an input with ten entries. Perhaps you should rewrite the loop to remove the magic number, by making the logic process while there is still (some) input.
Try this on for size
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
Scanner fromFile = new Scanner(new File("id_name.txt"));
} catch (FileNotFoundException e) {
System.err.println("File not found");
}
String[] arr = new String[9];
String[] oth = new String[9];
int i = 0;
while(fromFile.hasNextLine()) {
String temp = fromFile.nextLine();
oth[i] = temp.substring(0,1);
arr[i] = temp.substring(2);
i++;
}
int[] fileID;
fileID = new int[9];
for(int j = 0; j < 9; j++) {
fileID[j] = Integer.parseInt(oth[j]);
}
}
}
this should go through and retrieve the numbers(.substring(0,1)) and then the names(.substring(2)), and then converting the numbers to int values.
Try the following:
File file=new File("id_name.txt");
int[] fileID;
fileID= new int[9];
String[] result = file.nextLine().split("-");
for (int x = 0; x < result.length; x++){
if (Character.isDigit(result[x])) { // use the isDigit method to get the ids
System.out.println("this is an id");
fileID[i]= Integer.parseInt(result[x]);
}
Actually my friend, there are several mistakes here.
1) When the first while loop completes, it leaves fromfile.hasNext() as false Hence the second loop never starts.
>> To fix this, You need to put it all in one while loop.
2) fileID is an array. You cannot print it using System.out.println(fileID).
>> You have to tell what kind of output you want. The code will depend on that. For simply printing all the values, you need to make a for loop that prints each value separartely. You should use fileID.length for the no. of times you need to loop it.
3) Basically, fromfile.next() is not the way to do it.
>> You need to use fromfile.nextLine().

Infinite loop with integer text file reading in Java

Hi I have a fairly simple program but I am having trouble understanding why I have an inifite loop when I am running it. The file I am reading from has 10 integers in it. I am using Eclipse Juno and the output in the console is counting by 1 starting at 281363 infinitely. How can I fix this? Thanks in advance.
import java.util.*;
import java.io.*;
public class TestScoreAnalyzer
{
public static void main(String[] args) throws FileNotFoundException
{
int arraySize = 0;
File file = new File("C:\\Users\\Quinn\\workspace\\CPS121\\src\\
additionalAssignments\\scoresSample.txt");
Scanner inputFile = new Scanner(file);
while(inputFile.hasNextInt())
{
arraySize++;
System.out.println(arraySize);
}
inputFile.close();
}
}
You're never calling inputFile.nextInt() - you're only calling hasNextInt(), which doesn't actually advance the location in the file. You probably want:
while (inputFile.hasNextInt())
{
arraySize++;
System.out.println(arraySize);
int value = inputFile.nextInt();
// Do something with the value?
}
http://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt()
Scanner isnt moving on - its just saying the next one is an int (looks at the same one each time)

problems with parsing a text file in Java

I have looked at all the links and cannot seem to get what I am looking for. I have a text file I need to read in. First the text file format:
3 STL NY Chi //all on one line
STL NY 575 //on its own line
NY Chi 550 //on its own line
STL Chi 225 //on its own line
I need to read the int into an int variable, say we call it count. Then the actual cities on that same line into an array. The next lines need to read into an array to where the mileage is associated with the array, such as [STL NY]=575. I can only use arrays. No hash tables, list, stacks or queues. Here is what I got so far and honestly it isn't much. I could really use some help for I am pretty stumped on the "howto" on this.
import java.io.*;
import java.util.*;
public class P3 {
/**
* #param args the command line arguments
*/
public static int count;
public static void main(String[] args) {
try {
FileInputStream dataFile = new FileInputStream("Data.txt");
//BufferedReader br = new BufferedReader(new InputStreamReader(dataFile));
String line = br.readLine();
}
catch (IOException e) {
System.err.println ("Unable to open file");
System.exit(-1);
}
}
}
I think I'm getting there, but I am getting an error code of: "non-static variable cities cannot be referenced from a static context." I am trying to test my code by printing. Can anyone help me with this printing? I would like to see what is in the arrays to make sure I did it correctly. Here is my code:
package p3;
import java.io.*;
import java.util.*;
class citiesDist {
String cityOne;
String cityTwo;
int miles;
}
class city {
String cityName;
int numberLinks;
citiesDist[] citiesDists;
}
public class P3 {
city[] cities;
void initCity(int len) {
for (int i = 0; i < len; i++) {
cities[i] = new city();
}
}
void initCitiesDist (int index, int len) {
for (int i = 0; i < len; i++) {
cities[index].citiesDists[i] = new citiesDist();
}
}
void parseFile() throws FileNotFoundException, IOException {
FileInputStream fstream = new FileInputStream("Data.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
int numberCities = Integer.parseInt(br.readLine());
cities = new city[numberCities];
initCity(numberCities);
for (int i = 0; i < numberCities; i++) {
String line = br.readLine();
int numberLink = Integer.parseInt(line.split(" ")[1]);
cities[i].cityName = line.split(" ")[0];
cities[i].numberLinks = numberLink;
initCitiesDist (i, numberLink);
for (int j = 0; j < numberLink; j++){
line = br.readLine();
cities[i].citiesDists[j].cityOne = line.split(" ")[0];
cities[i].citiesDists[j].cityTwo = line.split(" ")[1];
cities[i].citiesDists[j].miles = Integer.parseInt(line.split(" ")[2]);
}
}
}
public static void main(String args[]) {
System.out.println("city" + cities.city);
}
}
If you're ever stumped on code, don't think about the programming language; it only serves to further muddle your logic. (Separate the algorithm from the language.) When you have a clear idea of what you want to accomplish, add your language in (insofar as, "how do I accomplish this particular task?").
Ultimate Goal
From your design, your goal is to have a graph relating the distances between each city. It would appear something like this:
[STL][NY] [Chi]
[STL][0] [575][25]
[NY] [575][0] [550]
[Chi][25] [550][0]
This isn't too terribly difficult to accomplish, in terms of the file input and the Scanner class.
First Steps
You have to extract the dimensions of your graph (which is a 3 by 3). This is provided for you in the first line of your input file. Getting an integer from a Scanner with a File in it isn't too difficult, just make sure you have the proper classes imported, as well as the proper error handling (either try...catch or throwing the exception).
Scanner sc = new Scanner(new File("input.txt"));
You'll need two arrays - one for the cities, and one for the distances themselves. We don't know how large they are (you never assume the data in a file, you just assume the form of the data), so we have to get that from the file itself. Luckily, we are given an integer followed by the cities themselves. We will read this integer once and use it in multiple different locations.
String[] cities = new String[sc.nextInt()];
int[][] distances = new int[cities.length][cities.length];
for(int i = 0; i < cities.length; i++) {
// Surely there's a method in Scanner that returns String that reads the _next_ token...
}
The Exercise to the Reader
You now have your data structure set up and ready to go. What you would need to do from here is bridge the gap between the cities array and distances array. Consider the order in which they arrived in the file, and the order in which we're encountering them. You would be well-served with some methodology or way to answer the question, 'Which came first - STL or NY?'
Give it a whirl and see if you can get further.

Categories