0

I am trying to read an integer array from a file. the file format is as follows:

893

410

243

264

357

33

793

...

...

I will later split that array into 4 and calculate it's sum using MPI, but i can't seem to be able to read the file. I get this exception:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at runtime.starter.MulticoreStarter$1.run(MulticoreStarter.java:281)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NumberFormatException: For input string: "893"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at lab3.main(lab3.java:28)
... 6 more

Process finished with exit code 0

So from what i understand, the format of the read string is not correct to be cast as an integer, here is the Code:

        //create an array of length 400
        int[] array = new int[400];

        //read the array from the file using the scanner class
        try {
            Scanner scanner = new Scanner(new File("random1000.txt"));
            for (int i = 0; i < array.length; i++) {
                array[i] = Integer.parseInt(scanner.nextLine());

            }
        }
        catch (FileNotFoundException e) {
            System.out.println("File not found");
        }

I also tried scanner.nextInt() and Integer.valueof() instead of parseInt, here is the error i got for scanner.nextInt()

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at runtime.starter.MulticoreStarter$1.run(MulticoreStarter.java:281)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at lab3.main(lab3.java:30)
... 6 more

It is my first time using the Scanner class and i am fairly new to java, what am i doing wrong and how do i fix this?

Here is the FULL code, i haven't tested any of the mpi stuff out yet, but i tried reading the file without the mpi code and i had the same problem.

import mpi.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class lab3 {


//Build a program that sums a big array (for example 1000 elements) over four processes
public static void main(String[] args) {

    //initialize MPI
    MPI.Init(args);

    //get the rank of the process
    int rank = MPI.COMM_WORLD.Rank();

    //if the rank is 0
    if (rank == 0) {
        // read the array from the file
        int[] array = new int[400];

        //read the array from the file using file reader
        try {
            Scanner scanner = new Scanner(new File("random1000.txt"));
            for (int i = 0; i < array.length; i++) {
                array[i] = scanner.nextInt();

            }
        }
        catch (FileNotFoundException e) {
            System.out.println("File not found");
        }


        //divide the array into 4 parts and send it to the other processes
        int[] array1 = new int[array.length / 4];
        int[] array2 = new int[array.length / 4];
        int[] array3 = new int[array.length / 4];
        int[] array4 = new int[array.length / 4];
        for (int i = 0; i < array.length / 4; i++) {
            array1[i] = array[i];
            array2[i] = array[i + array.length / 4];
            array3[i] = array[i + array.length / 2];
            array4[i] = array[i + array.length / 4 + array.length / 2];
        }
        //send each part to the other processes
        MPI.COMM_WORLD.Send(array2, 0, array2.length, MPI.INT, 1, 0);
        MPI.COMM_WORLD.Send(array3, 0, array3.length, MPI.INT, 2, 0);
        MPI.COMM_WORLD.Send(array4, 0, array4.length, MPI.INT, 3, 0);

        //calculate the sum of the array 1
        int sum1 = 0;
        for (int i = 0; i < array1.length; i++) {
            sum1 += array1[i];
        }

        //receive the summation from the other processes
        int sum2 = 0;
        MPI.COMM_WORLD.Recv(sum2 ,0, 0, MPI.INT, 1, 0);
        int sum3 = 0;
        MPI.COMM_WORLD.Recv(sum3 ,0, 0, MPI.INT, 2, 0);
        int sum4 = 0;
        MPI.COMM_WORLD.Recv(sum4 ,0, 0, MPI.INT, 3, 0);

        //calculate the final sum
        int sum = sum1 + sum2 + sum3 + sum4;

        //print the final sum
        System.out.println("The Final sum is: " + sum);

        //finalize MPI
        MPI.Finalize();
    }
    else {
        //receive the array from the process 0
        int[] array = new int[1000 / 4];
        MPI.COMM_WORLD.Recv(array, 0, array.length, MPI.INT, 0, 0);

        //calculate the sum of the array
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            sum += array[i];
        }

        //send the sum to the process 0
        MPI.COMM_WORLD.Send(sum, 0, 0, MPI.INT, 0, 0);
        //print local sum and rank
        System.out.println("The sum of the array is: " + sum + " and the rank is: " + rank);
    }
}


}

IntelliJ Idea , Windows 11.

EDIT:

i tried doing it this way:

List<Integer> ints = Files.lines(Paths.get("random1000.txt"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
array = ints.stream().mapToInt(i -> i).toArray();

throws java.lang.NumberFormatException: For input string: "893"

Zaka
  • 71
  • 6
  • I'm not sure--but just a suggestion, Tools like Scanner tend to be inflexible and you give up a lot of control. I THINK something like: new File("random1000.txt").getText().split().stream().map(String::trim).map(Integer::parseInt).collect(..... would do the entire job--although I've been going back and forth with Groovy lately and might have some of these methods a little wrong (I think java added getText() to a file, for instance, but it's not on 8) Also the split may return an array instead of a list which would mean starting the stream would be a tad different, but you get the idea. – Bill K Apr 08 '22 at 18:23
  • @user16320675 yes sorry about that, i tried both but i think i posted the wrong trace, will update it with the other one right awat, thanks for letting me know. – Zaka Apr 08 '22 at 19:09
  • @BillK Yep i tried it and it throws the same error, funny thing tho is that it runs on my friend's device, currently looking into why it doesn't run on mine – Zaka Apr 08 '22 at 19:10
  • it works, prints 893 no problem @user16320675 – Zaka Apr 08 '22 at 19:19
  • @user16320675 Thanks for the suggestion, when i typed in numbers manually it was in the same file, I created an empty new text file and entered manual numbers and it worked, like you said maybe the File generator (random numbers generator) had created some bytes at the beggining or somtheing – Zaka Apr 08 '22 at 19:26
  • @user16320675 Sorry, what actually happened was that i copied the file elsewhere, opened it, edited it and replaced the current file, the blame lies on me, your suggestions were extremely helpful, thank you again – Zaka Apr 08 '22 at 19:32
  • My guess is that you created the file with Notepad for Windows. Notepad loves to insert a [byte order mark](https://en.wikipedia.org/wiki/Byte_order_mark) character at the start of the file. The BOM is not a printing character, but you always try `scanner.findWithinHorizon("\ufeff", 0);` to determine whether the BOM is present. – VGR Apr 10 '22 at 02:47

1 Answers1

1

I created a new file and added some random numbers manually and it worked, to my understanding, the random number generator I used to create the text file might have added some extra bytes at the beginning which might be the cause of the problem.

Zaka
  • 71
  • 6