Zczytywanie z pliku - ObjectInputStream - czemu jest problem?

0

To mój kod przepisany z BufferedReader na ObjectInputStream:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class OdczytajPlik2 {
    public static class TworzPlik {
        static double[][]tablica;

        public static void Czytaj() {
            String linia = "";
            try {
                FileInputStream fis = new FileInputStream("NowaTab2.txt");
                  ObjectInputStream bfr = new ObjectInputStream(fis);
                  linia = (String) bfr.readObject();
                   String[] liczbawierszy = (String[]) ((String) bfr.readObject()).split(" ");
                      int wiersz = Integer.parseInt(liczbawierszy[2]);

                       String[] liczbakolumn = (String[]) ((String) bfr.readObject()).split(" ");
                          int kol = Integer.parseInt(liczbakolumn[2]);

                         double tablica[][] = new double [wiersz][kol];

                         for (int x = 0; x<wiersz; x++) {
                                    String[] wyrazS = (String[]) ((String) bfr.readObject()).split(" ");
                                    for (int i = 0; i<tablica.length; i++) { 

                                        double wyrazD = Double.parseDouble(wyrazS[i]);
                                    tablica[x][i] = wyrazD;                    

                         }
}
                         double max = tablica[0][0];
                         double min = tablica[0][0];
                           for (int i = 0; i<tablica.length; i++) {
                               for (int j = 0; j<tablica[i].length; j++) {
                            System.out.print(tablica[i][j] + " ");
                            if (max < tablica[i][j]) {
                                max = tablica[i][j];
                            }
                            if (min > tablica[i][j]) {
                                min = tablica[i][j];
                            }
                               }
                               System.out.println(" ");
                           }

                           System.out.println("Maksymalna wartość tablicy: " + max);
                           System.out.println("Minimalna wartość tablicy: " + min);

            }
            catch (ClassNotFoundException | IOException e) {
                System.out.println("Ups, jest problem");
            }          

        }

        public static void main(String[] args){
                  Czytaj();
              }

}
}

Plik mam w formie:

Macierz

Liczba wierszy: 2

Liczba kolumn: 2

3.409151512972887 0.22054570085972447
4.049554444595676 6.816644995335207

A w konsoli wyświetla mi:

Ups, jest problem

Dlaczego? Co powinienem poprawić?

0

Wypisz wyjątek.

0

Zamienić

 System.out.println("Ups, jest problem");

na

 System.out.println(e);

Jeżeli chcesz czytać za pomocą ObjectInputStream', to plik musi być utworzony za pomocą ObjectOutputStream.

0

Dostaję:
java.io.StreamCorruptedException: invalid stream header: 4D616369

0

Jestem prawie pewien, że plik który zaczyna się od słowa "Macierz" nie jest plikiem wygenerowanym przez ObjectOutputStream.

0
Wibowit napisał(a):

Jestem prawie pewien, że plik który zaczyna się od słowa "Macierz" nie jest plikiem wygenerowanym przez ObjectOutputStream.

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

public class TworzPlik2 {
    static double[][]tablica;

    public static double[][] TworzTab() {
          Scanner odczyt = new Scanner(System.in); 

        System.out.println("Podaj liczbę wierszy:");
          String wiersz = odczyt.nextLine();
          int wierszL = Integer.parseInt(wiersz);
          System.out.println("Podaj liczbę kolumn:");
          String kol = odczyt.nextLine();
          int kolL = Integer.parseInt(kol);
            System.out.println("Podaj maksymalną wartość liczb w tablicy:");
              String zakres = odczyt.nextLine();
              int zakresL = Integer.parseInt(zakres);

              double[][] tablica = new double[wierszL][kolL];
              for (int i = 0; i<tablica.length; i++) {
                  for (int j = 0; j<tablica[i].length; j++) {

                      Random r = new Random();
                      double randomValue = zakresL * r.nextDouble();
                      tablica[i][j] = randomValue;

                  }
              }

              for (int i = 0; i<tablica.length; i++) {
                  for (int j = 0; j<tablica[0].length; j++) {
                      System.out.format("%20s", tablica[i][j] + " ");
                  }
                  System.out.println(" ");

              }

              odczyt.close();

              try {
                  DataOutputStream zapis = new DataOutputStream(new FileOutputStream("NowaTab2.txt"));
                zapis.writeBytes("Macierz" + '\n');
                String newLine = System.getProperty("line.separator");
                zapis.writeBytes(newLine);
                zapis.writeBytes("Liczba wierszy: " + wierszL + '\n');
                zapis.writeBytes(newLine);
                zapis.writeBytes("Liczba kolumn: " + kolL + '\n');
                zapis.writeBytes(newLine);

                  for (int i = 0; i<tablica.length; i++) {
                      for (int j = 0; j<tablica[0].length; j++) {
                  zapis.writeBytes(tablica[i][j] + " ");
                      }
                        zapis.writeBytes(newLine);

                  }
                  zapis.close();

            } catch (IOException e) {
                System.out.println("Wystąpił błąd!");
            }

              return tablica;

    }

      public static void main(String[] args){
          TworzTab();
      }

}

Mój kod.
Aż jeszcze raz utworzyłem kolejny plik, oto efekt wystukania kolejno 2, 2, i 10:

Macierz

Liczba wierszy: 2

Liczba kolumn: 2

8.743699767862553 0.05343341495759768
1.2909527560130396 5.851288516482132

1

DataOutputStream to nie ObjectOutputStream.

2

Zapisujesz za pomocą DataOutputStream, a odczytujesz za pomocą ObjectInputStream. To pierwszy błąd. Dane zapisane przez DataOutputStrem odczytuje się za pomocą DataInputStream, a dane zapisane za pomocą ObjectOutputStream odczytuje się za pomocą ObjectInputStream. Po drugie, w znakomitej większości przypadków jeśli zapisujesz metodą writeXXX to odczytujesz metodą readXXX, tzn ma być 1:1 analogia między kodem zapisującym, a odczytującym. Strumienie nie mają wbudowanej sztucznej inteligencji by się domyślić, że chodziło ci o trochę co innego niż napisałeś w kodzie i że np muszą pominąć kilka bajtów, albo sobie coś wydedukować.

0

Rzeczywiście :)

Na tę chwilę stworzyłem taką zapisywarkę:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Random;
import java.util.Scanner;

public class TworzPlik2 {
    static double[][]tablica;

    public static double[][] TworzTab() {
          Scanner odczyt = new Scanner(System.in); 

        System.out.println("Podaj liczbę wierszy:");
          String wiersz = odczyt.nextLine();
          int wierszL = Integer.parseInt(wiersz);
          System.out.println("Podaj liczbę kolumn:");
          String kol = odczyt.nextLine();
          int kolL = Integer.parseInt(kol);
            System.out.println("Podaj maksymalną wartość liczb w tablicy:");
              String zakres = odczyt.nextLine();
              int zakresL = Integer.parseInt(zakres);

              double[][] tablica = new double[wierszL][kolL];
              for (int i = 0; i<tablica.length; i++) {
                  for (int j = 0; j<tablica[i].length; j++) {

                      Random r = new Random();
                      double randomValue = zakresL * r.nextDouble();
                      tablica[i][j] = randomValue;

                  }
              }

              for (int i = 0; i<tablica.length; i++) {
                  for (int j = 0; j<tablica[0].length; j++) {
                      System.out.format("%20s", tablica[i][j] + " ");
                  }
                  System.out.println(" ");

              }

              odczyt.close();

              try {
                  ObjectOutputStream zapis = new ObjectOutputStream(new FileOutputStream("NowaTab3.txt"));
                zapis.writeBytes("Macierz");
                String newLine = System.getProperty("line.separator");
                zapis.writeBytes(newLine);
                zapis.writeBytes("Liczba wierszy: " + wierszL);
                zapis.writeBytes(newLine);
                zapis.writeBytes("Liczba kolumn: " + kolL);
                zapis.writeBytes(newLine);

                  for (int i = 0; i<tablica.length; i++) {
                      for (int j = 0; j<tablica[0].length; j++) {
                  zapis.writeBytes(tablica[i][j] + " ");
                      }
                        zapis.writeBytes(newLine);
                  }
                  zapis.close();

            } catch (IOException e) {
                System.out.println("Wystąpił błąd!");
            }

              return tablica;

    }

      public static void main(String[] args){
          TworzTab();
      }

}

Mam nadzieję, że chociaż to jest dobrze...
Dostałem taki plik:

’ w|Macierz
Liczba wierszy: 2
Liczba kolumn: 2
9.77027640914799 5.5042117782873445
3.1516410816887843 1.5543464120678685

W otwierarce wyskakuje mi teraz:
java.io.OptionalDataException

Będę musiał coś pokombinować...

I wybaczcie małą obsuwę, komputer mi się zawiesił + aktualizacja systemu ;)

1

Będę musiał coś pokombinować...

Już napisałem o co chodzi. Jak z jednej strony robisz writeXXX, to z drugiej musisz zrobić readXXX. Chociaż z ciągiem bajtów jest trochę nie do końca tak, bo jest para metod writeBytes(String) oraz read(tablica_bajtów, int, int). Zamiast tego jednak polecam użyć writeUTF i readUTF. Metody te nie wymagają dodatkowego zapisywania długości Stringa, bo writeUTF samo tę długość zapisuje. Ogólnie jeśli z jednej strony zrobisz writeKrowa, a z drugiej readKoń no to sorry - nie pyknie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0