Several methods of accessing program state--java I/O application

Source: Internet
Author: User
Tags format define array variables socket stub variable ibm developerworks
Program
Jungleford says

There have been one months without a blog, for many reasons, such as the laboratory project is off work, huge busy, such as looking for a job and related things, and February most of the time to accompany the father and mother, home dialing speed can be imagined ... But the main still did not find a suitable topic, or said this time lazy (Pro graduation early syndrome), net in See "Hanvuda" and historical aspects of the book, there are other messy light readings, is not seriously play Java, haha! Now the work is almost implemented, fortunately not too bad, petty young jungleford life and began to enter the right track!    These are some nonsense in the new year. A little chat today about the "program state save" question, we can easily think of "serialization" (serialization, some books are translated to "sequential" or "serialized", but the word "serial" always reminds me of the communication and hardware interfaces, so I'm more accustomed to the term "serialization" , not to mention this term is a background, I will talk about the origin of this name, of course, serialization is a convenient and efficient way of data access, but it has a wider application. Broadly speaking, it's about some applications of I/O.

File I/o: file flow → serialization

★ File Stream File operation is the simplest and most straightforward and most easily thought of a way, we say file operation is not only through fileinputstream/fileoutputstream so "naked" The way to write data directly to the local file (like I wrote a mine-clearing of a small game javamine is to save the state of a bureau), so as to compare the "bottom" of the.
Primary class and Method description Fileinputstream.read () reads the binary format data from the local file Filereader.read () reads character (text) data from local file Fileoutputstream.write () Save binary data to local file Filewriter.write () Save character data to local file
Compared with the simple I/O approach above, XML appears to be "upscale", so that it becomes a standard for data interchange (★xml). DOM, for example, is concerned with first constructing the document tree in memory, the data is stored on a node (can be a leaf node, can also be the attribute of the label node), the construction of a one-time write to the external file, but we only need to know the location of the file, do not know how I/O is operating, XML operations may have been practiced by most people, so there are only a few related methods available for beginners to understand beforehand. The main package is javax.xml.parsers,org.w3c.dom,javax.xml.transform.
The main class and method Description Documentbuilderfactory.newdocumentbuilder (). Parse () parses an external XML file, Gets a Document object's DOM tree Documentbuilderfactory.newinstance (). Newdocumentbuilder (). NewDocument () Initializes a DOM tree document.getdocumentelement (). AppendChild () Adds a child node to a label node document.createTextNode () generates a String node node.getchildnodes () Gets all the next-layer nodes of a node node.removechild () deletes the child node document of a node. getElementsByTagName () finds a label node for all the specified names document.getElementById () finds a label node for the specified name, and returns one if there are multiple matches. Usually the first element.getattribute () Gets the value of a property of a label Element.setattribute () sets the value of a property of a label Element.removeattribute () Deletes a property of a label transformerfactory.newinstance (). Newtransformer (). Transform () writes a DOM tree to an external XML file
★ Serialize access to data using basic file read-write methods, if we just save the same type of data, we can save it in the same format, such as saving a disk in my javamine, I need to save the coordinates of each square, whether there are mines, whether they are turned over, etc., these information groups synthesize a "compound type Instead, if there are many different types of data, we either break it down into parts, save it in the same type (for example, string), or we need to add logic to the program to parse different types of data formats, which is inconvenient.    So we expect to process data at a more "high" level, and programmers should spend as little time and code as possible parsing the data, in fact, serialization provides us with such a path. Serialization (serialization) Everyone may have contact, it can write an object in a specific encoding format or from an external byte stream (that is, objectinputstream/objectoutputstream) read. Serializing an object is very simple, just implement the serializable interface, without even adding any special methods to it:
public class Myserial implements java.io.serializable{...}
But there is one condition: the class that you want to serialize, each of its properties must be "serializable". This sentence is a bit awkward, in fact all the basic types (that is, int,char,boolean, etc.) are "serializable", and you can look at the JDK document, you will find that many classes have actually implemented the serializable (that is, is already "serializable"), The objects of these classes and the basic data types can then be used directly as internal attributes of the class that you need to serialize. What if you encounter a property that is not serializable? Sorry, the class of this attribute also needs to implement the serializable interface in advance, so recursively until all the properties are serializable.
The primary class and method description Objectoutputstream.writeobject () Serializes an object to an external byte stream Objectinputstream.readobject () reads and reconstructs an object from an external stream of bytes
From a practical point of view, the "Serializable" interface does not define any method, as if it were just a tag (or something like a Java keyword), and once the virtual machine sees the "tag", it tries to invoke its own predefined serialization mechanism. Unless you have a private readobject () or WriteObject () method defined while implementing the Serializable interface. This is strange. But if you don't want the system to serialize in the default way, you must define the two methods mentioned above:
public class Myserial implements java.io.serializable{private void WriteObject (Java.io.ObjectOutputStream out) throws I  oexception {...}  private void ReadObject (Java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {...} ...}
For example, you can invoke the default serialization method () in the WriteObject () above () Objectoutputstream.defaultwriteobject (), for example, if you are unwilling to serialize certain sensitive attributes and information, You can also call the Objectoutputstream.writeobject () method to explicitly specify which attributes need to be serialized. About the user customizable serialization method, which we'll mention later.

★bean above serialization is just a basic application, you can serialize an object to an external file, open the file in Notepad, only from a few readable characters guessed that this is about this class information file, which requires you familiar with the serialization of the byte encoding of the file, That would be more painful (in the first volume of Core Java 2, the associated encoding is mentioned, you can view resources if you are interested), and in some cases we may need to have a serialized file with better readability.    On the other hand, as the core concept of the Java component "JavaBeans", starting with JDK 1.4, the specification also requires "long term persistence" (long-term persistence) that supports text. To open the JDK document, there is a class named "Encoder" in the Java.beans package, which is a utility class that can serialize the bean. The two main classes associated with it are Xmlecoder and Xmldecoder, which is clearly a tool for saving and reading beans in the format of an XML file. Their usage is also very simple, and similar to the above objectoutputstream/objectinputstream comparison.
The primary class and method description Xmlencoder.writeobject () Serializes an object to an external byte stream Xmldecoder.readobject () reads and reconstructs an object from an external stream of bytes
If a bean is in the following format:
public class mybean{int i;  Char[] C;  String s; ... (Get and set operations omitted) ...}
The XML file that is serialized through Xmlecoder has this form:
<?xml version= "1.0" encoding= "UTF-8" ><java version= "1.4.0" class= "Java.beans.XMLDecoder" >   <object class= "Mybean" >    <void property= "I" >       <int>1</int>    </void>    <void property= "C ">      <array class=" char "length=" 3 ">         <void index= "0" >          <int> a</int>        </void>         <void index= "1" >          <int>b</ int>        </void>         <void index= "2" >          <int>c</int >        </void>      </array>     </void>    <void property= "S" >       <string>fox jump!</string>     </void>  </object ></java>
Many of the visual components, such as AWT and swing, are beans and, of course, can be serialized in this way, and the following is a jframe serialized XML file extracted from the JDK document:
<?xml version= "1.0" encoding= "UTF-8" ><java version= "1.0" class= "Java.beans.XMLDecoder" >   <object class= "Javax.swing.JFrame" >    <void property= "name" >       <string>frame1</string>    </void>     <void property= "Bounds" >      <object class= "Java.awt.Rectangle" >        <int>0</int>         <int>0</int>        <int>200</ int>        <int>200</int>       </object>    </void>    <void property= " ContentPane ">      <void method=" Add ">         <objeCT class= "Javax.swing.JButton" >          <void property= "Label" >            <string>hello</ string>          </void>         </object>      </void>     </void>    <void property= "Visible" >       <boolean>true</boolean>    </void>  </object></java >
So, the data you want to keep is something that is not too complex, and it's a handy choice to make it into a bean-serialization format.

★properties in a small article on the set framework that I have summarized previously, properties is a typical example of a historical collection class, not primarily about its set characteristics. You may often contact a number of configuration files, such as Windows INI file, Apache conf file, as well as Java properties files, and so on, the data in these files in the "keyword-value" to save the way. The concept of "environment variable" knows it, it is also a kind of "key-value" to, before also often see version asked "How to get system So-and-so information" problems, in fact, many are stored in environment variables, as long as a
System.getproperties (). List (System.out);
You can get a list of all the environment variables:

--Listing Properties--java.runtime.name=java (TM) 2 runtime environment, Stand...sun.boot.library.path=c:\program Files\java\j2re1.4.2_05\binjava.vm.version=1.4.2_05-b04java.vm.vendor=sun Microsystems Inc.java.vendor.url=http ://java.sun.com/path.separator=;java.vm.name=java HotSpot (TM) Client vmfile.encoding.pkg=sun.iouser.country= Cnsun.os.patch.level=service Pack 1java.vm.specification.name=java Virtual Machine specificationuser.dir=d:\my Documents\ Project \eclipse wtdemojava.runtime.version=1.4.2_05-b04java.awt.graphicsenv= Sun.awt.win32graphicsenvironmentjava.endorsed.dirs=c:\program Files\java\j2re1.4.2_05\li ... Os.arch=x86java.io.tmpdir=c:\docume~1\cn2lx0q0\locals~1\temp\line.separator=

Java.vm.specification.vendor=sun Microsystems Inc.user.variant=os.name=windows XPsun.java2d.fontpath= Java.library.path=c:\program Files\java\j2re1.4.2_05\bi...java.specification.name=java Platform API Specificationjava.class.version=48.0java.util.prefs.preferencesfactory=java.util.prefs.windowspreferencesfac ... os.version=5.1user.home=d:\users\cn2lx0q0user.timezone=java.awt.printerjob= Sun.awt.windows.wprinterjobfile.encoding=gbkjava.specification.version=1.4user.name=cn2lx0q0java.class.path=d : \my Documents\ Project \eclipse wtdemo\bi...java.vm.specification.version=1.0sun.arch.data.model=32java.home=c:\ Program Files\java\j2re1.4.2_05java.specification.vendor=sun Microsystems inc.user.language=zhawt.toolkit= Sun.awt.windows.wtoolkitjava.vm.info=mixed Modejava.version=1.4.2_05java.ext.dirs=c:\program Files\Java\ J2re1.4.2_05\li ... Sun.boot.class.path=c:\program Files\java\j2re1.4.2_05\li ... Java.vendor=sun Microsystems INC.FILE.SEPARATOR=\JAVA.VENDOR.URL.BUG=HTTP://JAVA.SUN.COM/CGI-BIN/BUGREPORT...SUn.cpu.endian=littlesun.io.unicode.encoding=unicodelittlesun.cpu.isalist=pentium i486 i386
The main class and method description load () reads the property store from an external stream () saves the property to the external stream (especially the file) GetProperty () gets a specified property setproperty () sets a specified property list () List all "Key-value" contained in this properties object to System.getproperties () to obtain the current environment variable of the system
You can save a properties file like this:
Properties prop = new properties ();p rop.setproperty ("Key1", "value1"); FileOutputStream out = The new FileOutputStream ("Config.properties");p Rop.store (out, "-Here is the file header, you can add a comment-");
★preferences If I said that Java could operate the Windows registry without using JNI, would you believe it? Many software menus have "Setting" or "Preferences" options for setting or modifying software configurations that can be saved to a configuration file like the one described above, and may be saved to the system registry if it is a Windows platform. Starting with JDK 1.4, Java has added a java.util.prefs package that deals specifically with user and system configuration information under Java.util, and one class preferences is a more "advanced" gadget. Essentially, preferences itself is a platform-independent thing, but different OS implementations of its SPI (Service Provider Interface) are platform-dependent, so in different systems you may see preferences saved as local files, LDAP directory entries, database entries, and so on, like the Windows platform, it is saved to the system registry. Not only that, you can also export preferences to an XML file or import from an XML file.
The main class and method description Systemnodeforpackage () Gets a preferences object based on the specified class object, and the registry path of the object is systemroot from "Hkey_local_machine\" () Gets the Preferences object Usernodeforpackage () with the registry path HKEY_LOCAL_MACHINE Oftware\javasoft\prefs as the root node. Gets a preferences object based on the specified class object, and the registry path of the object is obtained from the "Hkey_current_user\" Userroot () to the registry path HKEY_CURRENT_USER Oftware\ Javasoft\prefs the Preferences object for the root node putxxx () sets the value of a property where xxx can be a basic numeric type, such as int, long, and so on, but with the first letter capitalized, indicating that the parameter is the appropriate type, or not writing and directly using put, parameter is the string getxxx () Gets the value of a property exportnode () Exports all preferences to an XML file Exportsubtree () exports a partial preference to an XML file Importpreferences () Import preferences from an XML file
You can save the data in the following steps:

Preferences MYPREFS1 = Preferences.usernodeforpackage (this);//This method is in the "Hkey_current_user\" A registry key is established under the path of the current class Preferences MYPREFS2 = Preferences.systemnodeforpackage (this);/This method is "hkey_local_machine\" A registry key is established under the path of the current class Preferences MYPREFS3 = Preferences.userroot (). Node ("Com.jungleford.demo");//This method is in "Hkey_current_ USER oftware\javasoft\prefs\ "Com\jungleford\demo" under the path to establish a registry key Preferences MyPrefs4 = Preferences.systemroot (). Node ("Com.jungleford.demo");//This method is to press "Com\jungleford\demo" under "HKEY_LOCAL_MACHINE Oftware\javasoft\prefs\" The path to establish a registry entry Myprefs1.putint ("Key1", ten); Myprefs1.putdouble ("Key2", -7.15); Myprefs1.put ("Key3", "value3"); FileOutputStream out = new FileOutputStream ("Prefs.xml"), Myprefs1.exportnode (out);

Network I/o:socket→rmi

★socket Socket programming may be very familiar to everyone, so there is no more discussion, just that through the socket to save the data to the remote server or from the network socket read data is also a way to consider.

The ★rmi RMI mechanism is actually the Java version of RPC (remote Procedure Call), which uses sockets as the basic transmission and is the most important application of serialization.    Now the network transmission from the point of view of the programming is basically the flow of operation, socket is an example, the object to convert to a word throttling an important goal is to facilitate the network transmission. Imagine the traditional design of a stand-alone environment, for the parameter passing of a function (method) invocation of the Java language (note the difference from the C language function call), there are two scenarios: if the basic data type is the same as the C language, the value is passed; if it is an object, is passed a reference to the object, including the return value is also a reference, not a complete copy of the Object! Imagine making a method call between different virtual machines, even if you have two objects of the same type with exactly the same name, they are probably different references! In addition to the method invocation process, because of the call process of the stack, the memory "scene" is completely occupied by the caller, when the invoked method returns, the caller's address is written back to the program counter (PC), and the caller's state is restored, and if it is two virtual machines, it is not possible to save the caller's state by simply pressing the stack.    For a variety of reasons, we need to set up the RMI communication entity between the "proxy" object, such as "stub" is equivalent to the remote server object on the client agent, stub is so, of course, this is something. There are several possible scenarios where local objects pass parameters and return values between remote objects (not necessarily the different machines on the physical location, as long as they are not "remote" in the same virtual machine):
Value passing: This includes two seed cases: if it is a basic data type, it is "serializable", all serialized into a transitive byte stream; if it is an object and not a "remote object" (so-called "remote object" Is the object that implements the Java.rmi.Remote interface, the object is supposed to pass a reference, but for the above reason the reference is not sufficient to prove the object's identity, so the pass is still a serialized copy (of course the object must satisfy the "serializable" condition above). Reference passing: The only "remote object" that can be passed is reference. The so-called "reference" here does not understand that it is really just a symbol, it is actually a left in the (client) local stub, and the remote server that the real object on the image of the exact picture!     Just because it has a bit of "privilege" (no need to be serialized), there is already an instance in the local memory that actually refers to this "twin". Thus, serialization plays an important role in RMI.


Database i/o:cmp, Hibernate

★ What is "persistence" friends with VMware probably know that when a guest OS is running, click "Suspend" to suspend the virtual OS, it will save the entire virtual memory content to disk, such as you for virtual OS allocated 128M of running memory, After that, you'll find a 128M file in the directory where the virtual OS is located, which is the full image of the virtual OS memory! This kind of memory mirroring means is actually "persistence" (persistence) The origin of the concept.

★CMP and hibernate because I am not too familiar with the things of the Java EE, casually find some material to see, so worry about not in place, this time not to make a concrete summary, people to learn ... It's a pain in the ~~~>_<~~~.

Re-discussion of serialization

It is not difficult to understand from the above technical discussions that serialization is an important foundation for Java's ability to achieve the two main selling points that it advocates-distributed (distributed) and Cross-platform (OS independent). Tij (that is, "thinking in Java") when it comes to I/O systems, it's really interesting to call serialization "lightweight persistence"-"lightweight persistence".

★ Why is it called "sequence"? In my opening remarks I said it was more customary to refer to "serialization" as "serialization" rather than "serializable", for a reason. Before introducing this reason, review some basic knowledge of computer, we know that the memory space of modern computer is all linear address (what is "linear" know, is that an element has only one "forerunner" and only "successor", of course, the tail element is an exception; for addresses, Its next address is of course impossible to have two, otherwise it is out of the question, "address" the concept of extension to the data structure, the equivalent of "pointers", this in the junior college probably know. Note that, since it is linear, the "address" can be seen as the "serial number" of memory space, indicating that its organization is in order, "serial number" or "Serial number" is a manifestation of the "serialization" mechanism. Why do you say that? For example, we have two objects A and B, respectively, examples of classes A and B, all of which are serializable, and A and B have a property of type C, and C of course must be serializable, according to the principles we said earlier.

Import Java.io.*;...class A implements serializable{c C; ...}

Class B implements serializable{C C; ...}

Class C implements serializable{...}

A A; b b; C C1;

Note that here we are instantiating A and B with the intention of having their C attribute use a reference to the same C-type object. For example C1, then imagine, but when we serialize A and B, are their C attributes stored in an external byte stream (of course not just a file) a copy or two copies? Serialization uses a scenario similar to "pointers" here: It marks a "serial number" for each serialized object, but when serializing an object, if one of its property objects is already serialized, only the sequence number of that property is written to the output stream serial , when the serialized object is recovered from the byte stream, the corresponding flow is also recovered according to the sequence number. This is the origin of the "serialization" Name!    Here we see "serialization" and "pointers" are very similar, except that "pointer" is the address chain of the memory space, and serialization is using the "serial number chain" in the external stream. Identifies a serialized object using "serial number" instead of a memory address. Because restoring objects to memory from a stream may not necessarily be the same address--all we need is a reference relationship between these objects, rather than a rigid original location, which is more necessary in RMI, Passing objects (streams) between two different machines simply cannot be expected to have the same memory address on both machines.

★ More Flexible "serialization": Transient properties and externalizable    serializable are really convenient, It's easy to save an object in memory to the outside without having to do any extra work. But there are two problems that serializable the power of the:    . One is efficiency, as noted in Core Java 2, serializable using the system default serialization mechanism can affect the speed of the software, Because of the need for reference numbers and numbers for each attribute, plus I/O operation time (I/O and memory read and write poor is an order of magnitude size), the cost is certainly considerable.      Another problem is that the "naked" serializable is not customizable, and it's silly to serialize everything, whether you want to do it or not. In fact, you can have at least three kinds of custom serialization options. One of the things mentioned earlier, is to add a private writeobject () and ReadObject () method in the Implements serializable class (this serializable is not naked, ^_^), and in both ways, The serialization, what should not be serialized, it's up to you, of course, you can call Objectoutputstream.defaultwriteobject () in the two method bodies respectively. and Objectinputstream.defaultreadobject () still perform the default serialization action (then you don't have to work the code?) OH), you can also use the Objectoutputstream.writeobject () and Objectinputstream.readobject () method to serialize your favorite attributes. But when the virtual machine sees you define both methods, it no longer uses the default mechanism.      if just to skip certain properties and not let it serialize, the action above seems to be troublesome, and the simpler approach is to add the transient keyword to the attribute that you don't want to serialize, which means it's a "transient variable." The default serialization does not plug these attributes into the external stream. Of course, if you define WriteObject () and ReadObject () methods, you can still serialize the transient variables. The digression, such as transient, violate, finally such a keyword beginner may not attach importance to, and now some company recruitment is like to ask such questions:(     Another solution is to implement the Externalizable interface without realizing the serializable. We look at the source code of these two interfaces and find them to be similar and even confusing. We should keep in mind that: Externalizable does not save any object-related information by default! Any action to save and restore objects is your own definition. The externalizable contains two public methods:
public void Writeexternal (ObjectOutput out) throws Ioexception;public void Readexternal (ObjectInput in) throws IOException, ClassNotFoundException;
At first glance this is almost the same as the WriteObject () and ReadObject (), but Serializable and externalizable walk through two different processes: serializable in the absence of objects, The entire object can be reconstructed from an external byte sequence only, but when externalizable rebuilds the object, it first invokes the default constructor of the class (that is, the constructor without parameters) so that an instance of memory is first. The Readexternal method is then invoked to restore the properties in the instance, so if those properties that are not assigned in the default constructor and in the Readexternal method, especially if they are of a non basic type, they will be null (NULL). It should be noted here that transient can only be used in the implementation of serializable rather than externalizable.

★ Serialization and cloning from the "serializable" recursive definition, a serialized object looks like an object memory image of the external cloning, if there is no shared reference of the attribute, it should be a deep clone. On the topic of cloning there can be a lot of talk, here is not in detail, interested can refer to an article on IBM developerworks: Java pointers, references and the object of the clone

A little revelation

As a practical application, when I wrote that Simple mail client jexp, I used to compare several ways to save the message object (mainly the contents of several key attributes and messages) to local methods, such as XML, properties, etc., and finally chose the way to serialize, Because this method is the simplest, it can be regarded as "practical". The "Access program status" is actually just a primer topic, and what I want to say is--as we discussed in the previous discussion about logging--you can have many kinds of solution about the same problem in front of Java: Familiar with file manipulation, you may feel that properties, XML or Bean is more convenient, and then found that there are preferences such a dongdong, probably will feel "behind", and wait until you contact a lot of new methods, the result will be "the same way", to re-examine the serialization mechanism itself. This is not just Java, science is the same truth.

Resources
Core Java 2. by Cay S. Horstmann, Gary Cornell J2SE advanced. by javaresearch.org thinking in Java. by Bruce Eckel j2se 1.4.2 documentation. By java.sun.com Java Network programming. by Elliotte R. Harold Java Distributed objects: RMI and CORBA. by IBM DeveloperWorks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.