Java Note 10

Chapter 17

Files, Streams and Object Serialization

method skip()

public long skip(long n) throws IOException

We can't do seek but we can do read and skip

Create Stream => I/O => Close Stream

package com.tony;
​
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
​
public class Demo {
    public static void main(String[] args) throws IOException {
        System.out.println("Hello");
        InputStream inputStream;
        BufferedReader bufferedReader=
                new BufferedReader(new FileReader("1.txt"));
​
        System.out.println(bufferedReader.readLine());
​
        bufferedReader.close();
    }
}

Basic use

package com.tony;
​
​
import java.io.*;
​
​
public class SkipCharacterOOutStream extends FilterOutputStream {
    /**
     * Creates an output stream filter built on top of the specified
     * underlying output stream.
     *
     * @param out the underlying output stream to be assigned to
     *            the field <tt>this.out</tt> for later use, or
     *            <code>null</code> if this instance is to be
     *            created without an underlying stream.
     */
    public SkipCharacterOOutStream(OutputStream out) {
        super(out);
    }
​
    @Override
    public void write(int b) throws IOException {
        if (b != 'O' && b != 'o') {
            super.write(b);
        }
    }
​
    public static void main(String[] args) throws IOException {
        byte[] bytes = new byte[1024];
        int content = System.in.read(bytes);
        SkipCharacterOOutStream skipCharacterOOutStream =
                new SkipCharacterOOutStream(System.out);
        skipCharacterOOutStream.write(bytes);
        skipCharacterOOutStream.close();
    }
}
​

Personalized use

    /**
     * Sets the file-pointer offset, measured from the beginning of this
     * file, at which the next read or write occurs.  The offset may be
     * set beyond the end of the file. Setting the offset beyond the end
     * of the file does not change the file length.  The file length will
     * change only by writing after the offset has been set beyond the end
     * of the file.
     *
     * @param      pos   the offset position, measured in bytes from the
     *                   beginning of the file, at which to set the file
     *                   pointer.
     * @exception  IOException  if {@code pos} is less than
     *                          {@code 0} or if an I/O error occurs.
     */
public void seek(long pos) throws IOException {
    if (pos < 0) {
        throw new IOException("Negative seek offset");
    } else {
        seek0(pos);
    }
}

public class RandomAccessFile implements DataOutput, DataInput, Closeable

This class makes us able to randomly access a file

What is serialization and deserialization?

package java.io;
​
/**
 * Serializability of a class is enabled by the class implementing the
 * java.io.Serializable interface. Classes that do not implement this
 * interface will not have any of their state serialized or
 * deserialized.  All subtypes of a serializable class are themselves
 * serializable.  The serialization interface has no methods or fields
 * and serves only to identify the semantics of being serializable. <p>
 *
 * To allow subtypes of non-serializable classes to be serialized, the
 * subtype may assume responsibility for saving and restoring the
 * state of the supertype's public, protected, and (if accessible)
 * package fields.  The subtype may assume this responsibility only if
 * the class it extends has an accessible no-arg constructor to
 * initialize the class's state.  It is an error to declare a class
 * Serializable if this is not the case.  The error will be detected at
 * runtime. <p>
 *
 * During deserialization, the fields of non-serializable classes will
 * be initialized using the public or protected no-arg constructor of
 * the class.  A no-arg constructor must be accessible to the subclass
 * that is serializable.  The fields of serializable subclasses will
 * be restored from the stream. <p>
 *
 * When traversing a graph, an object may be encountered that does not
 * support the Serializable interface. In this case the
 * NotSerializableException will be thrown and will identify the class
 * of the non-serializable object. <p>
 *
 * Classes that require special handling during the serialization and
 * deserialization process must implement special methods with these exact
 * signatures:
 *
 * <PRE>
 * private void writeObject(java.io.ObjectOutputStream out)
 *     throws IOException
 * private void readObject(java.io.ObjectInputStream in)
 *     throws IOException, ClassNotFoundException;
 * private void readObjectNoData()
 *     throws ObjectStreamException;
 * </PRE>
 *
 * <p>The writeObject method is responsible for writing the state of the
 * object for its particular class so that the corresponding
 * readObject method can restore it.  The default mechanism for saving
 * the Object's fields can be invoked by calling
 * out.defaultWriteObject. The method does not need to concern
 * itself with the state belonging to its superclasses or subclasses.
 * State is saved by writing the individual fields to the
 * ObjectOutputStream using the writeObject method or by using the
 * methods for primitive data types supported by DataOutput.
 *
 * <p>The readObject method is responsible for reading from the stream and
 * restoring the classes fields. It may call in.defaultReadObject to invoke
 * the default mechanism for restoring the object's non-static and
 * non-transient fields.  The defaultReadObject method uses information in
 * the stream to assign the fields of the object saved in the stream with the
 * correspondingly named fields in the current object.  This handles the case
 * when the class has evolved to add new fields. The method does not need to
 * concern itself with the state belonging to its superclasses or subclasses.
 * State is saved by writing the individual fields to the
 * ObjectOutputStream using the writeObject method or by using the
 * methods for primitive data types supported by DataOutput.
 *
 * <p>The readObjectNoData method is responsible for initializing the state of
 * the object for its particular class in the event that the serialization
 * stream does not list the given class as a superclass of the object being
 * deserialized.  This may occur in cases where the receiving party uses a
 * different version of the deserialized instance's class than the sending
 * party, and the receiver's version extends classes that are not extended by
 * the sender's version.  This may also occur if the serialization stream has
 * been tampered; hence, readObjectNoData is useful for initializing
 * deserialized objects properly despite a "hostile" or incomplete source
 * stream.
 *
 * <p>Serializable classes that need to designate an alternative object to be
 * used when writing an object to the stream should implement this
 * special method with the exact signature:
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
 * </PRE><p>
 *
 * This writeReplace method is invoked by serialization if the method
 * exists and it would be accessible from a method defined within the
 * class of the object being serialized. Thus, the method can have private,
 * protected and package-private access. Subclass access to this method
 * follows java accessibility rules. <p>
 *
 * Classes that need to designate a replacement when an instance of it
 * is read from the stream should implement this special method with the
 * exact signature.
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
 * </PRE><p>
 *
 * This readResolve method follows the same invocation rules and
 * accessibility rules as writeReplace.<p>
 *
 * The serialization runtime associates with each serializable class a version
 * number, called a serialVersionUID, which is used during deserialization to
 * verify that the sender and receiver of a serialized object have loaded
 * classes for that object that are compatible with respect to serialization.
 * If the receiver has loaded a class for the object that has a different
 * serialVersionUID than that of the corresponding sender's class, then
 * deserialization will result in an {@link InvalidClassException}.  A
 * serializable class can declare its own serialVersionUID explicitly by
 * declaring a field named <code>"serialVersionUID"</code> that must be static,
 * final, and of type <code>long</code>:
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
 * </PRE>
 *
 * If a serializable class does not explicitly declare a serialVersionUID, then
 * the serialization runtime will calculate a default serialVersionUID value
 * for that class based on various aspects of the class, as described in the
 * Java(TM) Object Serialization Specification.  However, it is <em>strongly
 * recommended</em> that all serializable classes explicitly declare
 * serialVersionUID values, since the default serialVersionUID computation is
 * highly sensitive to class details that may vary depending on compiler
 * implementations, and can thus result in unexpected
 * <code>InvalidClassException</code>s during deserialization.  Therefore, to
 * guarantee a consistent serialVersionUID value across different java compiler
 * implementations, a serializable class must declare an explicit
 * serialVersionUID value.  It is also strongly advised that explicit
 * serialVersionUID declarations use the <code>private</code> modifier where
 * possible, since such declarations apply only to the immediately declaring
 * class--serialVersionUID fields are not useful as inherited members. Array
 * classes cannot declare an explicit serialVersionUID, so they always have
 * the default computed value, but the requirement for matching
 * serialVersionUID values is waived for array classes.
 *
 * @author  unascribed
 * @see java.io.ObjectOutputStream
 * @see java.io.ObjectInputStream
 * @see java.io.ObjectOutput
 * @see java.io.ObjectInput
 * @see java.io.Externalizable
 * @since   JDK1.1
 */
public interface Serializable {
}

This interface has no specific method but simply announcement

In the same process but different thread, JVM shares location info and references are always available

Using IPC(Inter Process Communication) we can share the object between processes(Different JVM in the same OS)

But if not on the same machine?

We can use serialization to convert the object into byte stream and using TCP/IP or something like that to share the object

private static final long seriaVersionUID is used for checking version of class definition

If we put it to something like "1L", this is called a default one

When put to default, we won't check whether the two number are the same

If we use generated one, then different version will be warned and refuse to continue

Serialization is deeply inside, any object related to this one will be serialized(Like cloned)

Serialization demo:

package com.tony;
​
import java.io.*;
​
public class test {
    static Person p1 = new Person("abc",1);
    static Person p2 = new Person("def",2);
    static Person p3;
    static Person p4;
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectOutputStream oos =
                new ObjectOutputStream(new FileOutputStream("test.txt"));
        oos.writeObject(p1);
        oos.writeObject(p2);
        oos.close();
​
        ObjectInputStream ois =
                new ObjectInputStream(new FileInputStream("test.txt"));
        p3 = (Person) ois.readObject();
        p4 = (Person) ois.readObject();
        System.out.println(p3);
        System.out.println(p4);
​
    }
​
}
class Person implements Serializable {
    String pname;
    int pid;
​
    public Person(String pname, int pid) {
        this.pname = pname;
        this.pid = pid;
    }
​
    @Override
    public String toString() {
        return "Person{" +
                "pname='" + pname + '\'' +
                ", pid=" + pid +
                '}';
    }
}

BytesArrayInputStream is used to do I/O for the bytes array in RAM

Some method in class File

  • isFile()

  • isDirectory()

  • exists()

  • canRead()

  • canWrite()

  • delete()

  • createNewFile()

  • ....


Chapter 26

Multithreading

Java Concurrent Programming

Threads in JVM may not match threads in the OS

JVM achieves a good mapping between this two

Significantly harder to debug than single thread program

Threads are divided into two kinds

  • worker thread

  • daemon thread

If all the worker threads are finished, JVM will start to exit

Daemon Threads may not finish what it should do

package com.tony;
​
public class hello {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                f();
            }
        });
        t.setDaemon(true);
        t.start();
        f();
        System.out.println("Main finished........");
    }
​
    public static void f() {
        for (int i=0;i<300; i++){
            System.out.print(Thread.currentThread().getName());
            System.out.println(" "+i);
        }
    }
}

Thread t may not print all the 300 numbers

 /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

Important method join()

Can we call the thread again after it dies?

No.

Method start() doesn't directly start the method, it makes the thread ready to run and the scheduling program will decide whether it should start

System.out.println(Runtime.getRuntime().availableProcessors());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值