Read serialized array of arrays - java

I saved a file with a serialized String array that contains 3 arrays (1 String and 2 Double).
How can i read it back and redo the 3 arrays?
Here's how I write it :
String[] storeAllArrays[] = {prod, cant, pret};
ObjectOutputStream out;
try {
out = new ObjectOutputStream(new FileOutputStream("test.ser"));
out.writeObject(storeAllArrays);
out.flush();
out.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
}
EDIT : Here's what i tried :
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("test.ser"));
String[] arrayT = (String[]) in.readObject();
in.close();
JOptionPane.showMessageDialog(this, ArrayT);
} catch (IOException ex) {
Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
}

Simple example of serializing and deserializing
String[] prod = { "pr", "od" };
String[] cant = { "10.0", "20.0" };
String[] pret = { "30.0", "40.0" };
String[] storeAllArrays[] = {prod, cant, pret};
Logger logger = Logger.getLogger(SerializerSample.class.getName());
String serializedPath = "/tmp/store_test.ser";
ObjectOutputStream out;
try {
out = new ObjectOutputStream(new FileOutputStream(serializedPath));
out.writeObject(storeAllArrays);
out.flush();
out.close();
} catch (FileNotFoundException ex) {
logger.log(Level.SEVERE, null, ex);
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
try {
InputStream file = new FileInputStream(serializedPath);
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream(buffer);
String[] storeAllArraysREAD[] = (String[][]) input.readObject();
logger.log(Level.INFO, storeAllArraysREAD.toString());
} catch (ClassNotFoundException ex) {
logger.log(Level.SEVERE, "Cannot perform input. Class not found.",
ex);
} catch (IOException ex) {
logger.log(Level.SEVERE, "Cannot perform input.", ex);
}

I would write the String and two doubles, as a String and two doubles.
DataOutputStream dos = new DataOutputStream(new FileOutputStream("test.data"));
dos.writeUTF(prod);
dos.writeDouble(cant);
dos.writeDouble(pret);
dos.close();
to read
DataInputStream dis = new DataInputStream(new FileInputStream("test.data"));
prod = dis.readUTF();
cant = dis.readDouble();
pret = dis.readDouble();
dis.close();
if you must use ObjectOutputStream you can use ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.data"));
String[] array = (String[]) dis.readObject();
dis.close();

Have you ever heard of ObjectInputStream? It's for reading files created with ObjectOutputStream. You construct one like this:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.ser"));
Then you can read your arrays in like this:
Object[] array = (Object[]) ois.readObject();

Related

Serialize ArrayList<ArrayList<MyPoint>> isnt working

Having a ArrayList>, how do I serialize?
ArrayList<ArrayList<MyPoint>> polygons;
try {
FileOutputStream fileOut = openFileOutput("polygons.ser", MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(pv.polygons);
out.close();
fileOut.close();
Log.d("Polygons Output", pv.polygons.toString());
Log.d("Polygons Output Out", out.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fileIn = openFileInput("polygons.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
ArrayList<ArrayList<MyPoint>> arr = new ArrayList<>();
pv.polygons = (ArrayList<ArrayList<MyPoint>>) in.readObject();
in.close();
fileIn.close();
} catch (IOException io) {
io.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Log.d shows me ArrayList of [[Point(0,0) ,....]].
The outputStream is in onSaveInstance and the inputStream is in onCreate().
MyPoint extends Point implements Serializable...
Why does it not work?

Java socket receives byte array where each byte is 0

I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
But somehow, byte array which client receives, contains only 0 bytes, so my output file is empty. here is the code:
Server:
try {
serverSocket=new ServerSocket(7575);
serverSocket.setSoTimeout(1000000);
System.out.println("serverSocket created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Error in creating new serverSocket on port 7575");
}
for(int i=0;i<array.length;i++)
System.out.println(array[i]);
Socket socket=null;
try {
System.out.println("Waiting for client...");
socket=serverSocket.accept();
System.out.println("Client accepted.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
PrintWriter outWriter=null;
DataOutputStream outputStream=null;
OutputStream os=null;
BufferedOutputStream bos=null;
try {
os=socket.getOutputStream();
outputStream=new DataOutputStream(os);
outWriter=new PrintWriter(socket.getOutputStream());
bos=new BufferedOutputStream(socket.getOutputStream());
System.out.println("Server streams created.");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("sending name "+name);
outWriter.println(name);
outWriter.flush();
outWriter.println(array.length);
outWriter.println("array.length"+array.length);
outWriter.flush();
try {
os.write(array);
os.flush();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt send array of bytes");
}
try {
os.close();
outputStream.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
client:
public class Client implements Runnable {
private Socket socket;
private String folderPath;
public Client(String p)
{
folderPath=p;
}
#Override
public void run()
{
try {
System.out.println("Client connecting to localhost on 7575 port...");
socket=new Socket("localhost", 7575);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader reader=null;
BufferedInputStream bis=null;
InputStream input=null;
DataInputStream in=null;
try {
System.out.println("creating streams");
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
input=socket.getInputStream();
in=new DataInputStream(input);
bis=new BufferedInputStream(socket.getInputStream());
System.out.println("streams created!");
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
String name="";
int size=0;
String s="32";
try {
name=reader.readLine();
s=reader.readLine();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
if(s!=null)
size=Integer.parseInt(s);
System.out.println("name: "+name);
System.out.println("size: "+size);
byte [] arr=new byte[size];
try {
input.read(arr);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("couldnt read the byte array");
}
for(int i=0;i<arr.length;i++)
System.out.println(arr[i]);
FileOutputStream fos=null;
try {
fos=new FileOutputStream(folderPath+"/"+name);
} catch (FileNotFoundException ex) {
System.out.println("Could write the file");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.write(arr);
fos.flush();
} catch (IOException ex) {
System.out.println("Could write the file2");
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in.close();
input.close();
reader.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Mixing binary and text modes on the same stream is tricky. You would be advised not to do it. Using DataInputStream (for the name, count and file content) is one possible solution. (And that is what I would try). Another would be to encode the file content as text (e.g. using Base64 encoding).
The problem with your current "mixed stream: code is on the client side. When you read the name and size from the BufferedReader, you will cause the reader to read and buffer up to 4096 bytes from the socket. The problem is that some of those bytes are file content. So when you then try to read the content from the underlying InputStream here:
input.read(arr);
you may find that there is nothing left to read. Result: an empty or corrupted file.
There's another problem too. Your code assumes that the input.read(arr) statement is going to read the rest of the stream, or until it fills the byte array. This assumption is incorrect. When you are reading from a socket stream, the read is liable to return only the bytes that are currently available (in the client-side network stack).
Once again, the result is liable to be a corrupted file. (In this case truncated.)
The read code should look something like this:
int count = 0;
while (count < size) {
int bytesRead = is.read(bytes, count, bytes.length - count);
if (bytesRead == -1) {
throw EOFException("didn't get a complete file");
}
count += bytesRead;
}
Finally:
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
You really should be using "try with resources" to ensure that the streams are all closed properly. Doing it by hand is cumbersome, and risks resource leaks.
you can use DataOutputStream to directly write some string(message) on output stream using writeUTF() function. And then u can receive your message using object of DataInputStream class by using readUTF() method.
u can send data using following:-
String message="something";
DataOutputStream out=new DataOutputStream(socket.getOutputStream());
out.writeUTF(message);
and u can receive data or message using following:-
DataInputStream in=new DataInputStream(socket.getInputStream());
String message=in.readUTF();
i basically used these method to read data from input stream and write data to outputstream many times and it worked every time, so u should check this way too.
I am making a program which takes a file, and sends it via socket to client. Client receives it and saves it to a file. That is what it is supposed to do.
If you have no need to inspect the content of what is being passed through, then straight InputStream and OutputStream are the way to go, in my opinion. The code is straightforward and fast as it avoids any overhead imposed by higher-level stream types that inspect the content for encoding, etc. This also reduces the opportunity for corrupting the information.
I agree with Stephen C's answer except for
Reading the file content into byte arrays at both ends wastes memory, and is going to be problematic for a really large file.
With the specific requirement to simply move one file to another system with no need to look at the values, this isn't an issue if you know how to handle the content. The basic flow is
client: InputStream in = getFileInputStream();
OutputStream out = socket.getOutputStream();
byte[] bytes = new byte[BUFFER_SIZE]; // could be anything
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
in.close();
out.close();
server: InputStream in = socket.getInputStream();
OutputStream out = getFileOutputStream();
// the rest is the exact same thing as the client
This will handle any arbitrarily sized file, limited only by disk size of the server.
Here is an example I whipped up. It's admittedly hacky (the use of the FILE_COUNTER and STOP_KEY for example) but I'm only attempting to show various aspects of having a user enter a file and then send it between a client and server.
public class FileSenderDemo {
private static final int PORT = 7999;
private static final String STOP_KEY = "server.stop";
private static final int[] FILE_COUNTER = {0};
public static void main(String[] args) {
FileSenderDemo sender = new FileSenderDemo();
Thread client = new Thread(sender.getClient());
Thread server = new Thread(sender.getServer());
server.start();
client.start();
try {
server.join();
client.join();
} catch (InterruptedException e) {
FILE_COUNTER[0] = 999 ;
System.setProperty(STOP_KEY,"stop");
throw new IllegalStateException(e);
}
}
public void send(File f, OutputStream out) throws IOException{
try(BufferedInputStream in = new BufferedInputStream(new FileInputStream(f),1<<11)){
byte[] bytes = new byte[1<<11];
int bytesRead;
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
}
}
public Runnable getClient() {
return () -> {
while(FILE_COUNTER[0] < 3 && System.getProperty(STOP_KEY) == null) {
Socket socket;
try {
socket = new Socket("localhost", PORT);
} catch (IOException e) {
throw new IllegalStateException("CLIENT: Can't create the client: " + e.getMessage(), e);
}
File f = getFile();
try (BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream())) {
send(f, out);
} catch (IOException e) {
System.out.println("CLIENT: Failed to send file " + f.getAbsolutePath()+" due to: " + e.getMessage());
e.printStackTrace(System.err);
} finally {
FILE_COUNTER[0]++;
}
}
System.setProperty(STOP_KEY,"stop");
};
}
public File getFile(){
Scanner scanner = new Scanner(System.in);
System.out.println("CLIENT: Enter a file Name: ");
return new File(scanner.next());
}
public Runnable getServer(){
return () -> {
OutputStream out = null;
try{
ServerSocket server = new ServerSocket(PORT);
server.setSoTimeout(20000);
while(System.getProperty(STOP_KEY) == null){
Socket socket = null;
try {
socket = server.accept();
}catch (SocketTimeoutException e){
System.out.println("SERVER: Waited 20 seconds for an accept. Now checking if we need to stop.");
continue;
}
String fileName = "receivedFile_"+System.currentTimeMillis()+".content";
File outFile = new File(fileName);
out = new BufferedOutputStream(new FileOutputStream(outFile));
InputStream in = socket.getInputStream();
int bytesRead;
byte[] bytes = new byte[1<<12];
while((bytesRead = in.read(bytes)) != -1){
out.write(bytes,0,bytesRead);
}
out.close();
socket.close();
System.out.println("SERVER: Just created a new file: " + outFile.getAbsolutePath());
}
System.out.println("SERVER: " + STOP_KEY + " was not null, so quit.");
}catch (IOException e){
throw new IllegalStateException("SERVER: failed to receive the file content",e);
}finally {
if(out != null){
try{out.close();}catch (IOException e){}
}
}
};
}
}

How do I resolve the ClassCastException while retrieving an array of objects from a .txt file?

I have created an array of objects of type Employee and i am putting the objects in a .txt file.
Below is the method that accepts Employee objects a parameter and puts it into the .txt file
public void putDataintoFile(Employee[] obj) {
File file = new File("employeedetails.txt");
try {
FileOutputStream fos = new FileOutputStream(file);
try {
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.close();
fos.close();
}
catch (IOException ex) {
Logger.getLogger(EmployeeService1.class.getName()).log(Level.SEVERE, null, ex);
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(EmployeeService1.class.getName()).log(Level.SEVERE, null, ex);
}
}
This above method is invoked from a seperate "Execetor class " which then calls my getDataFromFile() method below
public void getDataFromFile() {
System.out.println("Reached HERE");
try {
FileInputStream fin = new FileInputStream("employeedetails.txt");
try {
ObjectInputStream oin= new ObjectInputStream(fin);
try {
Employee e =(Employee)oin.readObject();
System.out.println("Reached HERE");
System.out.println(e.toString());
} catch (ClassNotFoundException ex) {
Logger.getLogger(EmployeeService1.class.getName()).log(Level.SEVERE, null, ex);
}
oin.close();
fin.close();
}
catch (IOException ex) {
Logger.getLogger(EmployeeService1.class.getName()).log(Level.SEVERE, null, ex);
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(EmployeeService1.class.getName()).log(Level.SEVERE, null, ex);
}
}
On executign I get an error which says.
Exception in thread "main" java.lang.ClassCastException: [LMypackage.Employee; cannot
be cast to Mypackage.Employee
at Mypackage.EmployeeService1.getDataFromFile(EmployeeService1.java:225)
at Mypackage.Executor.main(Executor.java:71)
I have implemented Serializable interface in my Employee Classs
Can anyone help me ?
You're writing an array and trying to read a single object.
This is stated in the exception message, which leads to the read/write code, which is fairly obvious despite all the superfluous vertical whitespace.
Also, in general, don't call not-text files .txt.

Java program to read objects from a .ser file located in a server

My idea is that I want to read an object from a serialized file located in a server. How to do that?
I can only read .txt file using the following code :
void getInfo() {
try {
URL url;
URLConnection urlConn;
DataInputStream dis;
url = new URL("http://localhost/Test.txt");
// Note: a more portable URL:
//url = new URL(getCodeBase().toString() + "/ToDoList/ToDoList.txt");
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
dis = new DataInputStream(urlConn.getInputStream());
String s;
while ((s = dis.readLine()) != null) {
System.out.println(s);
}
dis.close();
} catch (MalformedURLException mue) {
System.out.println("Error!!!");
} catch (IOException ioe) {
System.out.println("Error!!!");
}
}
You can do this with this method
public Object deserialize(InputStream is) {
ObjectInputStream in;
Object obj;
try {
in = new ObjectInputStream(is);
obj = in.readObject();
in.close();
return obj;
}
catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
catch (ClassNotFoundException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
feed it with urlConn.getInputStream() and you'll get the Object. DataInputStream is not fit to read serialized objets that are done with ObjectOutputStream. Use ObjectInputStream respectively.
To write an object to the file there's another method
public void serialize(Object obj, String fileName) {
FileOutputStream fos;
ObjectOutputStream out;
try {
fos = new FileOutputStream(fileName);
out = new ObjectOutputStream(fos);
out.writeObject(obj);
out.close();
}
catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}

Java socket inpustream stuck

I have problem with reading from socket inputStream. But only in one method in class. Here is my code:
server:
private void copyFile(String mainPath, String path) {
outS.println("Sending file!");
outS.println(path);
outS.flush();
BufferedInputStream fis = null;
OutputStream os;
File file = new File(mainPath);
String str;
byte[] buffer = new byte[4096];
long numOfChunks = file.length() / 4096, num = 0, lng;
try {
fis = new BufferedInputStream(new FileInputStream(file));
os = socket.getOutputStream();
outS.println(numOfChunks);
fis.read(buffer, 0, 4096);
os.write(buffer, 0, buffer.length);
os.flush();
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Clerk, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Clerk, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fis.close();
} catch (IOException ex) {
Logger.getLogger(Clerk.class.getName()).log(Level.SEVERE, null, ex);
}
}
waitEnd();
}
client:
private void copyFile(String destination) {
FileOutputStream fos = null;
long numOfChunks, num = 0;
SBuffer sBuffer;
byte[] buffer = new byte[4096];
InputStream is;
try {
fos = new FileOutputStream(new File(destination));
BufferedOutputStream bos = new BufferedOutputStream(fos);
is = socket.getInputStream();
numOfChunks = Long.parseLong(inS.readLine());
System.out.println(num + "/" + numOfChunks);
int bytesRead = is.read(buffer, 0, buffer.length);
bos.write(buffer, 0, bytesRead);
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Client, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Client, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
outS.println("end");
outS.flush();
}
Let me explain few things. Everythings goes fine, but client on line int bytesRead = is.read(buffer, 0, buffer.length) will stuck, because nothing is in stream (is.available = 0 ). And i don't know why. Although i send it from server many times.
And I can't close stream, because socket will close too.
Method waitEnd() waits for string "end" in socket's input stream.
I have searched many tutorials and things on internet, but no one help.
Code which establish connection:
Server:
public void run() {
try {
ssocket = new ServerSocket(2332);
Socket socket = ssocket.accept();
clerk = new Clerk(socket, mainPath);
(new Thread(clerk)).start();
} catch (IOException ex) {
}
try {
ssocket.close();
} catch (IOException ex) {
}
}
public Clerk(Socket socket, String path) {
this.socket = socket;
mainTree = new FileTree(path);
}
public Client(String address, String[] dirs) {
try {
socket = new Socket(address, 2332);
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
Client and clerk has same method run:
#Override
public void run() {
try {
inS = new BufferedReader(iss);
outS = new PrintWriter(socket.getOutputStream(), true);
oos = new ObjectOutputStream(socket.getOutputStream());
iss = new InputStreamReader(socket.getInputStream());
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException ex) {
}
msg();
try {
inS.close();
iss.close();
outS.close();
ois.close();
oos.close();
socket.close();
} catch (IOException ex) {
}
}
Resolved. I created second socket for file transfer only.

Categories

Resources