This is my first file
public class ObjectStream
{
public static void main(String args[]) throws FileNotFoundException, IOException
{
java.io.File f=new java.io.File("D:Employee.outt") ;
Employee e=new Employee("John");
Employee e1=new Employee("Mary");
Employee e2=new Employee("Christian");
OutputStream os=new java.io.FileOutputStream(f);
java.io.ObjectOutputStream oos= new ObjectOutputStream(os);
oos.writeObject(e);
oos.writeObject(e1);
oos.writeObject(e2);
}
}
This is my second file
public class Employee implements java.io.Serializable
{
private static int count=100;
private int eid;
private String ename;
public Employee()
{
count++;
this.eid=count;
}
public Employee(String ename)
{
this();
this.ename=ename;
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
Employee.count = count;
}
public int getEid() {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
}
This is my third file
public class MainClass
{
public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException
{
File f=new File("D:Employee.outt");
byte data[]=new byte[(int)f.length()];
InputStream is=new java.io.FileInputStream(f);
java.io.ObjectInputStream ois=new java.io.ObjectInputStream(is);
Object o=ois.readObject();
while(o!=null)
{
Employee e=(Employee)o;
System.out.println(e.getEid());
System.out.println(e.getEname());
o=ois.readObject();
}
ois.close();
is.close();
}
}
I am trying to read objects stored in Employee.outt in via this third file but it is reading all the objects but at the end throwing
Exception in thread "main" java.io.EOFException.
I don't know how to resolve it.
while(o!=null)
This isn't a valid way to read an ObjectInputStream. The readObject() method only returns a null if you wrote a null. At end of stream it throws, guess what, an EOFException, so the correct way to read the stream is to loop calling `readObject() until you catch that exception, then break and close the stream.
at the end of file it is giving EOF exception
That's exactly what EOFException means.
You should close ObjectOutputStreamin ObjectStream class.
oos.writeObject(e);
oos.writeObject(e1);
oos.writeObject(e2);
oos.close();
In the MainClass you can use a try-finally block to close the inputstream.
try
{
InputStream is=new java.io.FileInputStream(f);
java.io.ObjectInputStream ois=new java.io.ObjectInputStream(is);
// READ logic here
}
finally
{
ois.close();
is.close();
}
You really should flush and close the object output stream in "first file".
You only need to close 'ois' in "third file". The other stream is automatically closed for you.
If you know how many objects you're going to write, change "first file" to write the number of objects following first, then change "third file" to read that number and only read that many objects. That way, you never get the EOF exception, because you stop reading when you've read the last object.
As EJP pointed out, you still have to catch the EOFException, because the file you're reading might be damaged.
In First File:
...
oos.writeInt(3);
oos.writeObject(e);
...
In Third File:
...
try {
int numObjects = ois.readInt();
for( int a = 0; a < numObjects; ++a ) {
...
}
} catch( EOFException e ) {
...
}
Related
I am trying to encrypt password before serialization
I am getting OptionalDataException in the following code.
I read many article like "read non transient variable before , EOF in
program, read in same way as you write in file etc ..
but non of this article solving my problem
here are following program where i am getting error.
class MySerialization implements Serializable{
public String username;
public transient String password;
public MySerialization(){
}
public MySerialization(String pass,String user){
this.password=pass;
this.username=user;
}
public String getPassword(){
return this.password;
}
//Write CustomObject in file
private void writeObject(ObjectOutputStream oos) throws Exception{
oos.defaultWriteObject();
String pass= "HAS"+password;
oos.writeChars(pass);
}
private void readObject(ObjectInputStream ois) throws Exception{
ois.defaultReadObject();
String pass= (String)ois.readObject(); //Here getting Exception OptionalDataException
password= pass.substring(3);
}
public String getUsername(){
return this.username;
}
}
class MyTest {
public static void main(String args[]) throws Exception{
MySerialization my1=new MySerialization("123456","User1");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("n.txt"));
oos.writeObject(my1);
oos.close();
MySerialization my2=new MySerialization();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("n.txt"));
my2=(MySerialization )ois.readObject();
System.out.println(my2.getUsername() +" "+my2.getPassword());
ois.close();
}
}
You need to write/read the same types and in the same order. Currently you're writing char's so you should also be reading char's.
One example (also read char):
private void readObject(ObjectInputStream ois) throws Exception{
ois.defaultReadObject();
StringBuilder passBuilder = new StringBuilder();
try {
while (true) {
passBuilder.append(ois.readChar());
}
} catch (EOFException e) {
// Reached end of stream.
} finally {
ois.close();
}
String pass = passBuilder.toString();
password = pass.substring(3);
}
Second example (write Object):
private void writeObject(ObjectOutputStream oos) throws Exception{
oos.defaultWriteObject();
String pass= "HAS"+password;
oos.writeObject(pass);
}
I'm using the kubernetes-client to try copy a directory from a pod, but I'm doing something wrong with the input stream from stdout. I get a java.io.IOException: Pipe broken exception when it tries to read(). I'm pretty sure that no data flows at all. I'm half wondering if I need to read the InputStream on a separate thread or something?
The stream is created like this:
public InputStream copyFiles(String containerId,
String folderName) {
ExecWatch exec = client.pods().withName(containerId).redirectingOutput().exec("tar -C " + folderName + " -c");
// We need to wrap the InputStream so that when the stdout is closed, then the underlying ExecWatch is closed
// also. This will cleanup any Websockets connections.
ChainedCloseInputStreamWrapper inputStreamWrapper = new ChainedCloseInputStreamWrapper(exec.getOutput(), exec);
return inputStreamWrapper;
}
And the InputStream is processed in this function
void copyVideos(final String containerId) {
TarArchiveInputStream tarStream = new TarArchiveInputStream(containerClient.copyFiles(containerId, "/videos/"));
TarArchiveEntry entry;
boolean videoWasCopied = false;
try {
while ((entry = tarStream.getNextTarEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
String fileExtension = entry.getName().substring(entry.getName().lastIndexOf('.'));
testInformation.setFileExtension(fileExtension);
File videoFile = new File(testInformation.getVideoFolderPath(), testInformation.getFileName());
File parent = videoFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
OutputStream outputStream = new FileOutputStream(videoFile);
IOUtils.copy(tarStream, outputStream);
outputStream.close();
videoWasCopied = true;
LOGGER.log(Level.INFO, "{0} Video file copied to: {1}/{2}", new Object[]{getId(),
testInformation.getVideoFolderPath(), testInformation.getFileName()});
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, getId() + " Error while copying the video", e);
ga.trackException(e);
} finally {
if (!videoWasCopied) {
testInformation.setVideoRecorded(false);
}
}
}
The InputStream Wrapper class is just there to close the ExecWatch at the end once the InputStream is closed, it looks like this:
private static class ChainedCloseInputStreamWrapper extends InputStream {
private InputStream delegate;
private Closeable resourceToClose;
public ChainedCloseInputStreamWrapper(InputStream delegate, Closeable resourceToClose) {
this.delegate = delegate;
this.resourceToClose = resourceToClose;
}
#Override
public int read() throws IOException {
return delegate.read();
}
public int available() throws IOException {
return delegate.available();
}
public void close() throws IOException {
logger.info("Shutdown called!");
delegate.close();
// Close our dependent resource
resourceToClose.close();
}
public boolean equals(Object o) {
return delegate.equals(o);
}
public int hashCode() {
return delegate.hashCode();
}
public int read(byte[] array) throws IOException {
return delegate.read(array);
}
public int read(byte[] array,
int n,
int n2) throws IOException {
return delegate.read(array, n, n2);
}
public long skip(long n) throws IOException {
return delegate.skip(n);
}
public void mark(int n) {
delegate.mark(n);
}
public void reset() throws IOException {
delegate.reset();
}
public boolean markSupported() {
return delegate.markSupported();
}
public String toString() {
return delegate.toString();
}
}
Turns out I had the tar command wrong, so it was causing a failure and the stdout PipeInputStream was dead locking. I managed to find a workaround for the deadlock. But the main reason for the failure was that I forgot to tell tar to actually do something! I at least needed a "." to include the current directory.
I've reasearched a lot of websites and I couldn't find answear. I'm trying to write to .txt file my ArrayList which constains class objects. Every time I try to do it I`m getting exception. With reading is the same problem. Here is my code:
public static void write()
{
try
{
FileOutputStream out = new FileOutputStream("clients.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
oout.writeObject(lista);
oout.close();
}
catch(Exception ioe)
{
System.out.println("writing Error!");
welcome();
}
}
public static void read()
{
try
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("clients.txt"));
lista = (List<Client>) ois.readObject();
}
catch (ClassNotFoundException ex)
{
System.out.println("Koniec pliku");
}
catch(IOException ioe)
{
System.out.println("Error!");
welcome();
}
}
I guess you're looking for the Serializable interface of Java. In order to save objects you're class have to implement it.
The question is: What execatly do you want to save? The content of the list so that you can save it in a file and load it afterwards?
This simple example works for me (for the scenario I mention above):
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public User(String name, int ag) {
this.name = name;
this.age = age;
}
#Override
public String toString() {
return (this.name + ' ' + this.age);
}
}
public class Main {
private static List<User> l;
public static void main(String[] args) {
l = new ArrayList<User>();
user1 = new User("John", 22);
user2 = new User("Jo", 33);
l.add(user1);
l.add(user2);
write();
}
public static void write() {
try {
FileOutputStream fos = new FileOutputStream("testout.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(l);
oos.close();
} catch (Exception ioe) {
System.out.println("writing Error!");
}
}
}
Ok I have changed a bit (not each function just the read and write functionality) and this work.
Link to Code.
One important thing is that the Scanner class is not serializable. Therefore, you have to make it static for example.
so i've been sitting above this code for a while , ready the NullPointerException threads, and still can't figure out what is going wrong in my code, so i turn to you.
public class Main {
public static void main(String[] args){
/* Making catalog, loading last state */
Collection catalog = new Collection();
try {
catalog.readFromFile();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
catalog.addShip(new Ship("ABC123", "John", "Suzuki", 50));
}
}
And my Collection class looks like this:
public class Collection {
private List<Ship> shipList;
private String fileName = "catalog.txt";
private int income;
private int space;
public Collection() {
shipList = new ArrayList<Ship>();
income = 0;
space = 500;
File f = new File("catalog.txt");
if(!f.exists()) {
try {
f.createNewFile();
writeToFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void addShip(Ship SHIP){
space -= SHIP.LENGTH;
income += SHIP.COST;
shipList.add(SHIP);
}
public Ship getShip(int INDEX){
return shipList.get(INDEX);
}
public void writeToFile() throws IOException {
FileOutputStream f = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(f);
out.writeObject(shipList);
out.close();
}
#SuppressWarnings("unchecked")
public void readFromFile() throws IOException, ClassNotFoundException {
FileInputStream f = new FileInputStream(fileName);
ObjectInputStream in = new ObjectInputStream(f);
shipList = (ArrayList<Ship>)in.readObject();
in.close();
}
public int getIncome(){
return income;
}
public int getSpace(){
return space;
}
}
My problem is, when i call in main catalog.addship() i get nullptr error. After following the console errors, it says i get the nullptrexc when i call the addShip() on the catalog, following from there i get the error when i add() a Ship to the Collection's shipList. So what i concluded, it is because the shipList in the Collection is uninitialized. But in the constructor i write shipList = new ArrayList<Ship>(); so it is clearly initialized.
The exception stacktrace is the following:
Exception in thread "main" java.lang.NullPointerException
at collection.Collection.addShip(Collection.java:31)
at main.Main.main(Main.java:100)
In your main method, you initialize the ArrayList properly. But then, you make a
catalog.readFromFile()
call. In the readFromFile() method, you re-initialize the ArrayList
shipList = (ArrayList<Ship>)in.readObject();
the in.readObject() is returning null. That is why your shipList variable is null.
Hope this helps!
Java Newbie question :
I need to capture the text being written to a printStream by a 3rd party component.
The PrintStream is defaulted to System.err, but can be changed to another PrintStream.
Looking through the docs, I couldn't find an easy way to direct the contents of a PrintStream to a string writer / buffer.
Can someone please assist?
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream(pipeOut);
System.setOut(new PrintStream(pipeOut));
// now read from pipeIn
import java.io.*;
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("errors.txt");
} catch(IOException ioe) {
System.err.println("redirection not possible: "+ioe);
System.exit(-1);
}
PrintStream ps = new PrintStream(fos);
System.setErr(ps);
System.err.println("goes into file");
}
}
You can create a PrintStream around any other OutputStream.
The simplest way to create one that goes to a buffer in memory would be:
PrintStream p = new PrintStream( new ByteArrayOutputStream() )
Then you could read and reset the contents of the byte array at whatever points you like.
Another possibility would be to use pipes.
InputStream third_party_output = new PipedInputStream();
PrintStream p = new PrintStream( new PipedOutputStream( third_party_output ) );
Then you could read from the third_party_output stream to get the text written by the library.
Are you looking for something like this?
OutputStream redirect = System.err;
PrintStream myPrintStream = new PrintStream(redirect);
myPrintStream.println("hello redirect");
If you can pass myPrintStream to the 3rd party application, you can redirect it anywhere you want.
I use the following class to log System.out and System.err to a set of rotating files (where xxx-001.log is the most recent). It contains a few call to utility methods, which you will need to implement before it will compile - they should be self-explanatory.
import java.io.*;
import java.lang.reflect.*;
public class LoggerOutputStream
extends OutputStream
{
// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************
private FileOutputStream log=null; // the base output stream
private String fnmBase,fnmExt; // filename base, file extension
private int fnmCount,fnmLast; // count for filename index, last filename used
private int logSize,totWritten; // max log size, current number of bytes written
// *****************************************************************************
// INSTANCE CONSTRUCTORS/INIT/CLOSE/FINALIZE
// *****************************************************************************
public LoggerOutputStream(String baseFilename) throws IOException {
this(baseFilename,".log",2,1024000);
}
public LoggerOutputStream(String baseFilename, String extension) throws IOException {
this(baseFilename,extension,2,1024000);
}
public LoggerOutputStream(String baseFilename, String extension, int numberOfFiles, int maxFileSize) throws IOException {
fnmBase=baseFilename;
if(Character.isLetterOrDigit(fnmBase.charAt(fnmBase.length()-1))) { fnmBase=(fnmBase+"-"); }
fnmExt=extension;
if(!fnmExt.startsWith(".")) { fnmExt=('.'+fnmExt); }
fnmCount=numberOfFiles;
logSize=maxFileSize;
if(fnmCount>MAXLOGS) { fnmCount=MAXLOGS; }
fnmLast=0;
for(int xa=1; xa<=MAXLOGS; xa++) {
if(!new File(constructFilename(xa)).exists()) {
while((--xa)>fnmCount) { IoUtil.deleteFile(constructFilename(xa)); }
fnmLast=xa;
break;
}
}
log=null;
openFile(false);
if(numberOfFiles>MAXLOGS) { System.out.println("** Log File Count Limited To "+MAXLOGS); }
}
public void close() throws IOException {
close(false);
}
private void openFile(boolean ovrflw) throws IOException {
close(true);
if (fnmLast< fnmCount) { fnmLast++; }
else if(fnmLast==fnmCount) { IoUtil.deleteFile(constructFilename(fnmCount)); }
for(int xa=fnmLast; xa>0; xa--) { IoUtil.renameFile(constructFilename(xa-1),constructFilename(xa)); }
log=new FileOutputStream(constructFilename(1));
totWritten=0;
}
private String constructFilename(int index) {
return constructFilename(fnmBase,index,fnmExt);
}
private synchronized void close(boolean ovrflw) throws IOException {
if(log!=null) {
log.flush();
log.close();
log=null;
}
}
// *****************************************************************************
// INSTANCE METHODS - ACCESSORS
// *****************************************************************************
public String getFilename() {
return constructFilename(1);
}
public String getFilename(int idx) {
return constructFilename(idx);
}
public synchronized void cycleLogFile() throws IOException {
openFile(true);
}
// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************
public synchronized void flush() throws IOException {
if(log!=null) {
log.flush();
}
}
public synchronized void write(int val) throws IOException {
if(log!=null) {
log.write(val);
totWritten++;
if(val=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
public synchronized void write(byte[] bytes) throws IOException {
if(log!=null) {
log.write(bytes);
totWritten+=bytes.length;
if(bytes.length>0 && bytes[bytes.length-1]=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
public synchronized void write(byte[] bytes, int str, int len) throws IOException {
if(log!=null) {
log.write(bytes,str,len);
totWritten+=len;
if(bytes.length>(str+len-1) && bytes[str+len-1]=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
// *****************************************************************************
// STATIC PROPERTIES
// *****************************************************************************
static public final int MAXLOGS=999; // maximum log files allowed
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
static public String constructFilename(String bas, int idx, String ext) {
if(!bas.endsWith("-") && !bas.endsWith("_") && !bas.endsWith(".")) { bas=(bas+"-"); }
if(!ext.startsWith(".") ) { ext=('.'+ext); }
return (bas+TextUtil.raZeros(idx,3)+ext);
}
} /* END PUBLIC CLASS */