File I/O: file stream → serialization
★File stream
File operations are the simplest, most direct, and easiest way to think, the file operation we are talking about is not just writing data directly to a local file using fileinputstream/fileoutputstream in a "Bare" way (like javamine, a mine clearance game I previously wrote, it is like this to save a game ), in this way, the "bottom layer" is compared.
Main classes and methods and descriptions
- Fileinputstream. Read ()// Read binary data from a local file
- Filereader. Read ()// Read character (text) data from a local file
- Fileoutputstream. Write ()// Save binary data to a local file
- Filewriter. Write ()// Save character data to a local file
★XML
Compared with the simple I/O method above, XML is much more "upscale" and becomes a standard for data exchange. ToDom ModeFor example, it is concerned with the firstConstruct a document tree in memoryThe data is stored on a certain node (it can be a leaf node or a label node attribute). After the data is constructed, it is written to an external file at a time, however, we only need to know the location of the file, and do not know how I/O is operated. Most people may have practiced the XML operation method. Therefore, we only list the relevant methods here, for beginners to know in advance. The main packages are javax. xml. parsers, org. W3C. Dom, and javax. xml. Transform.
Main classes and methods and descriptions
- Documentbuilderfactory. newdocumentbuilder (). parse ()// Parse an external XML file to obtain the DOM tree of a Document Object
- Documentbuilderfactory. newinstance (). newdocumentbuilder (). newdocument ()// Initialize a DOM tree
- Document. getdocumentelement (). appendchild ()// Add a subnode to a label Node
- Document. createtextnode ()// Generate a string Node
- Node. getchildnodes ()// Obtain all the subnodes at the next layer of a node
- Node. removechild ()// Delete the subnode of a node
- Document. getelementsbytagname () search for all the tag nodes with the specified name
- Document. getelementbyid ()// Search for a tag node with the specified name. If there are multiple tags, one is returned, usually the first one.
- Element. getattribute ()// Obtain the value of an attribute of a tag
- Element. setattribute ()// Set the value of an attribute of a tag
- Element. removeattribute ()// Delete an attribute of a tag
- Transformerfactory. newinstance (). newtransformer (). Transform ()// Write a DOM tree to an external XML file
★Serialization
Use Basic file read/write methods to access data.Same typeYou can save the data in the same format. For example, when saving a board in my javamine, you need to save the coordinates of each square, whether there are mines, and whether it is opened, these information groups combine a "composite type"; conversely, if there are multipleDifferent TypesData, we can either break it into several parts, save it in the same type (such as string), or we need to add the logic to the program to parse different types of data format, this is inconvenient. So we expect to use a relatively "high" level to process data, the programmer shouldSpend as little time and code as possible to parse dataIn fact, the serialization operation provides us with such a way.
Serialization may be widely used. It can write an object in a specific encoding format or read it from an external byte stream (I .e., objectinputstream/objectoutputstream. Serialization of an object is very simple. You just need to implement the serializable interface, and you don't even need to add any method for it:
- Public ClassMyserialImplementsJava. Io.Serializable
- {
- //...
- }
However, there is a condition:Each attribute of the class you want to serialize must be "serializable ".. This sentence is a bit confusing. Actually, allBasic Type(INT, Char, Boolean, and so on)All are "serializable ".You can check the JDK documentation and find that many classes have actually implemented serializable (that is, they are already "serializable ), therefore, the objects and basic data types of these classes can be directly used as the internal attributes of the class you need to serialize. What if I encounter a property that is not "serializable? Sorry, the class of this attribute must implement the serializable interface in advance, so recursion,Until all attributes are "serializable".
Main classes and methods and descriptions
- Objectoutputstream. writeobject ()// Serialize an object to an external byte stream
- Objectinputstream. readobject ()// Read from the external byte stream and reconstruct the object
In practical applications, the "serializable" interface does not define any methods, as if it is just a tag (or a Java keyword). Once the virtual machine sees this"MarkWill try to call itselfPredefined serialization MechanismUnless you define a private readobject () or writeobject () method while implementing the serializable interface. This is strange. However, if you do not want the system to use the default serialization method, you must define the two methods mentioned above:
- Public ClassMyserialImplementsJava. Io.Serializable
- {
- Private VoidWriteobject (Java. Io.ObjectoutputstreamOut)ThrowsIoexception
- {
- //...
- }
- Private VoidReadobject (Java. Io.ObjectinputstreamIn)ThrowsIoexception,Classnotfoundexception
- {
- //...
- }
- //...
- }
For example, you can call the default serialization method objectoutputstream in the preceding writeobject. defaultwriteobject (); for example, if you are unwilling to serialize some sensitive attributes and information, you can also call objectoutputstream. the writeobject () method explicitly specifies the attributes to be serialized. We will refer to custom serialization Methods later.
★Bean
The above serialization is only a basic application. After you serialize an object to an external file, use NotePad to open the file, you can only guess from a few readable characters that this is an information file related to this class. This requires you to be familiar with the byte encoding method of the serialized file, it will be quite painful (related encoding methods are mentioned in the first volume of core Java 2. If you are interested, you can refer to the references ), in some cases, we may need serialized files for better readability. On the other hand, as the core concept of Java components "JavaBeans", since JDK 1.4, its specifications also require support for the"Long-term persistence"(Long-term persistence ).
Open the JDK document. There is a class named "encoder" in the Java. Beans package, which is a producer class that can serialize beans. There are two main classes related to it: xmlecoder and xmldecoder. Obviously, this is a tool for saving and reading beans in XML file format. Their usage is also very simple, similar to objectoutputstream/objectinputstream above.
Main classes and methods and descriptions
- Xmlencoder. writeobject ()// Serialize an object to an external byte stream
- Xmldecoder. readobject ()// Read from the external byte stream and reconstruct the object
If a bean is in the following format:
- Public ClassMybean
- {
- IntI;
- Char[] C;
- StringS;
- //... (Get and set operations are omitted )...
- }
The XML file serialized by xmlecoder has the following format:
<? 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 visual components such as AWT and swing are bean, which can be serialized in this way. Below is an XML file serialized from a jframe 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>
Therefore, if the data you want to save is of a type that is not too complex, making it bean reserialization is also a convenient choice.
★Properties
As mentioned in a previous article about the collection framework, properties is a typical example of the historical collection class. It is not used to introduce its collection features here. Everyone may be familiar with someConfiguration FileSuch as Windows INI files, Apache conf files, and properties files in Java."Keyword-value" pair. "Environment Variable"I know this concept. It is also a" key-value "pair. In the past, I often saw problems such as how to obtain information about a system, in fact, many of them are saved in environment variables.
- System. Getproperties (). List (System. Out );
You can get a list of all 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/bin
Java. VM. Version = 1.4.2 _ 05-b04
Java. VM. Vendor = Sun Microsystems Inc.
Java. venduo. url = http://java.sun.com/
Path. Separator =;
Java. VM. Name = Java hotspot (TM) Client VM
File. encoding. PKG = sun. Io
User. Country = Cn
Sun. OS. Patch. Level = Service Pack 1
Java. VM. Specification. Name = Java virtual machine specification
User. dir = D:/My Documents/project/Eclipse/swtdemo
Java. runtime. Version = 1.4.2 _ 05-b04
Java. AWT. graphicsenv = sun. AWT. win32graphicsenvironment
Java. endorsed. dirs = C:/program files/Java/j2re1.4.2 _ 05/Li...
OS. Arch = x86
Java. Io. tmpdir = C:/docume ~ 1/cn2lx0q0/locals ~ 1/temp/
Line. Separator =
Java. VM. Specification. Vendor = Sun Microsystems Inc.
User. Variant =
OS. Name = Windows XP
Sun. java2d. fontpath =
Java. Library. Path = C:/program files/Java/j2re1.4.2 _ 05/bi...
Java. Specification. Name = Java platform API Specification
Java. Class. Version = 48.0
Java. util. prefs. preferencesfactory = java. util. prefs. windowspreferencesfac...
OS. Version = 5.1
User. Home = D:/users/cn2lx0q0
User. timezone =
Java. AWT. printerjob = sun. AWT. Windows. wprinterjob
File. Encoding = GBK
Java. Specification. Version = 1.4
User. Name = cn2lx0q0
Java. Class. Path = D:/My Documents/project/Eclipse/swtdemo/bi...
Java. VM. Specification. Version = 1.0
Sun. Arch. Data. Model = 32
Java. Home = C:/program files/Java/j2re1.4.2 _ 05
Java. Specification. Vendor = Sun Microsystems Inc.
User. Language = ZH
AWT. Toolkit = sun. AWT. Windows. wtoolkit
Java.vm.info = Mixed Mode
Java. Version = 1.4.2 _ 05
Java. 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 = little
Sun. Io. Unicode. Encoding = unicodelittle
Sun. CPU. isalist = Pentium istmi386
Main classes and methods and descriptions
- Load ()// Read attributes from an external stream
- Store ()// Save attributes to external streams (especially files)
- Getproperty ()// Obtain a specified attribute
- Setproperty ()// Set a specified attribute
- List ()// List all the "key-value" pairs contained in this properties object
- System. Getproperties ()// Obtain the current environment variable of the system
You can save a properties file as follows:
- Properties prop =NewProperties ();
- Prop. setproperty ("key1", "value1 ");
- ...
- Fileoutputstream out =NewFileoutputstream ("config. properties ");
- Prop. Store (Out, "-- this is the file header. You can add a comment --");
★Preferences
If I say that Java does not use JNI to operate the Windows registry, do you believe it? Many software menus contain "setting" or "Preferences" options to set or modify software configurations. These configuration information can be saved to a configuration file as described above, if it is on Windows, it may also be saved to the system registry. From JDK 1.4, Java. util adds a Java program that specifically processes user and system configuration information. util. prefs package, one of which class preferences is a kind of "advanced" stuff. In essence, preferences itself is a platform-independent thing, but the implementation of its SPI (Service Provider Interface) by different operating systems is platform-related. Therefore, in different systems, you may see that the preferences are saved as local files, LDAP directory items, and database entries. For example, on Windows, the preferences are saved to the system registry. In addition, you can export your preferences as XML files or import them from XML files.
Main classes and methods and descriptions
- Systemnodeforpackage ()// Obtain a preferences object based on the specified class object. The Registry path of this object starts with "HKEY_LOCAL_MACHINE /".
- Systemroot ()// Get the preferences object with the Registry path HKEY_LOCAL_MACHINE/software/javasoft/prefs as the root node
- Usernodeforpackage ()// Obtain a preferences object based on the specified class object. The Registry path of this object starts with "HKEY_CURRENT_USER /".
- Userroot ()// Obtain the preferences object with the Registry path HKEY_CURRENT_USER/software/export oft/prefs as the root node
- Putxxx ()// Set the value of an attribute. Here, xxx can be of the basic numeric type, such as Int or long, but the first letter is uppercase, indicating that the parameter is of the corresponding type, you can also directly use put without writing. The parameter is a string.
- Getxxx ()// Obtain the attribute value
- Exportnode ()// Export all preferences as an XML file
- Exportsubtree ()// Export some preferences as an XML file
- Importpreferences ()// Import preferences from XML files
You can save the data as follows:
- Preferences myprefs1 = preferences. usernodeforpackage (This);// This method creates a registry entry in the path of the current class under "HKEY_CURRENT_USER /".
- Preferences myprefs2 = preferences. systemnodeforpackage (This);// This method creates a registry entry in the path of the current class under "HKEY_LOCAL_MACHINE /"
- Preferences myprefs3 = preferences. userroot (). node ("com. jungleford. Demo ");// This method is to create a registry key under "HKEY_CURRENT_USER/software/javasoft/prefs/" and press the "com/jungleford/demo" path.
- Preferences myprefs4 = preferences. systemroot (). node ("com. jungleford. Demo ");// This method is to create a registry key under "HKEY_LOCAL_MACHINE/software/javasoft/prefs/" and press the "com/jungleford/demo" path.
- Myprefs1.putint ("key1", 10 );
- Myprefs1.putdouble ("key2",-7.15 );
- Myprefs1.put ("key3", "value3 ");
- Fileoutputstream out =NewFileoutputstream ("prefs. xml ");
- Myprefs1.exportnode (out );
Network I/O: Socket → RMI
★Socket
Socket programming may be very familiar to everyone, so we will not discuss it much, but it is also worth considering to save data to a remote server or read data from a network socket.
★RMI
RMI is actually the Java version of RPC (Remote Procedure Call). It uses Socket as the basic transmission method and is also the most important application of serialization. At present, network transmission is basically from the programming point of view.In stream modeSocket is an example. An important goal of converting an object into a word Throttling is to facilitate network transmission.
Imagine the traditionalStandalone EnvironmentFor the program design in Java, there are two cases for passing the parameters of function (method) calls (note the difference with C function calls ):Basic Data TypeIn this case, it is the same as the C language.Value TransferMethod; If yesObject, The object is passedReference, Including the returned value is also a reference, rather than a complete object copy! ImagineDifferent virtual machinesCall methods between them. Even two objects of the same name are likely to be different references! In addition, due to the pressure stack of the called method, the memory "field" is completely occupied by the caller. When the called method returns, the caller's address is written back to the program counter (PC) to restore the caller's status. If there are two virtual machines, it is impossible to save the caller's status by simply pressing the stack. For various reasons, we need to create a "proxy" object between the RMI communication entities. For example, "stub" is equivalent to the proxy of the remote server object on the client, and stub is like this, of course this is the end.
Parameters and return values are transmitted between local and remote objects (not necessarily different machines in physical locations, as long as they are not "remote" in the same virtual machine). There may be several situations:
- Value Transfer: This includes two sub-scenarios: if it is a basic data type, all are "serializable" and all are serialized into a deletable byte stream; if it is an object, it is not a "remote object" (the so-called "remote object" implements Java. RMI. remote interface object), the original object should be passed as a reference, but because of the above reasons, the reference is not enough to prove the identity of the object, so the passed is stillA serialized copy(Of course, this object must also meet the above "serializable" conditions ).
- Reference transfer: only remote objects can be referenced and passed ". The so-called "Reference" here should not be understood as a real symbol. It is actually a local stub that stays in (client), and the real object on the remote server is exactly the same.ImagesThat's all! It is just because it is a bit "privileged" (it does not need to be serialized), and there is an instance in the local memory, which is actually referenced by this "twins ".
This shows how important serialization plays in RMI.
Database I/O: CMP, Hibernate
★What is "persistence"
Friends who have used VMware probably know that when a guest OS is running and click "Suspend" to suspend the virtual OS, it will save the entire virtual memory content to the disk, for example, if you allocate MB of running memory to the virtual OS, after the VM is suspended, you will find a file of MB in the directory where the virtual OS is located, this is the complete image of the virtual OS memory! This memory mirroring method is actually the concept of "persistence.
★CMP and Hibernate
Because I am not very familiar with J2EE, I can find some materials at will, so I am worried that it is not in place. I will not make a specific summary this time. People need to learn ...... It's a really painful thing.
Serialization and further exploration
From the discussion of the above technologies, it is not difficult to understand that serialization is the two selling points that Java can boast in an outstanding way ?? Distributed and cross-platform (OS independent) is an important foundation. Tij ("Thinking in Java") refers to serialization as "lightweight persistence" when talking about I/O systems "?? "Lightweight persistence" is really interesting.
★Why is it "sequential?
In the opening remarks, I said that "serialization" is more often called "serialization" rather than "serialization", for some reason. Before introducing this reason, let's review some basic computer knowledge. We know that the memory space of modern computers isLinear addressing(What is "linear", you know, is that an element has only one unique "precursor" and a unique "Successor". Of course, the header and tail elements are exceptions. For addresses, of course, there may not be two of its next addresses, otherwise it will be messy.) the concept of "Address" is promoted to the data structure, which is equivalent to "Pointer". This is probably known in the lower grades of the undergraduate course. Note that since it is linear, the "Address" can be regarded as the "Serial Number" of the memory space, indicating that its organization is sequential.Serial number"Or" Serial Number "is a manifestation of the" serialization "mechanism. Why? For example, we have two objects, A and B, which are instances of class A and B. They are all serializable, And A and B both have an attribute of type C, according to the principles we mentioned earlier, C must also be serializable.
- ImportJava. Io .*;
- ...
- ClassAImplements Serializable
- {
- C;
- ...
- }
- ClassBImplements Serializable
- {
- C;
- ...
- }
- ClassCImplements Serializable
- {
- ...
- }
- A;
- B;
- C C1;
- ...
Note: when instantiating a and B, we intend to make their C attributes use references of the same C type object, such as C1. Please think about it, but when we serialize A and B, are their C attributes stored in an external byte stream (not just files) in one copy or two copies? Serialization is used hereSimilar to the "pointer" scheme: It marks a"Serial number"(Serial number), but when serializing an object, if one of its attribute objects has been serialized, only the serial number of this attribute is written to the output stream; when a serialized object is restored from a byte stream, the corresponding stream is also found based on the serial number. This is the origin of the "serialization" name! Here we can see that "serialization" is very similar to "Pointer", but "Pointer" is the address chain of the memory space, and serialization usesSerial number chain in external stream".
The "Serial Number" instead of the memory address is used to identify a serialized object. Because the object is restored from the stream to the memory, the address may not be the original address ?? All we need is the reference relationship between these objects, rather than the rigid original location. This is even more necessary in RMI. Objects (streams) are transmitted between two different machines ), it is impossible to expect them to have the same memory address on both machines.
★More flexible "serialization": the transient attribute and externalizable
Serializable is really convenient, so that you can easily save the objects in the memory to the external without having to do any extra work. However, there are two problems that constrain the power of serializable:
One is efficiency. core Java 2 states that serializable's use of the system's default serialization mechanism will affect the running speed of the software because it needs to reference numbers and check numbers for each attribute, in addition, the I/O operation time (I/O and memory read/write difference is an order of magnitude), the cost is of course considerable.
Another problem is the "Bare" serializableNot customizableIt's silly to serialize everything for you, whether you want to do it or not. In fact, you can have at least three custom serialization options. One of the methods mentioned above is to add the private writeobject () and readobject () Methods to the implements serializable class (this serializable is not bare ,), in these two methods, you have the final say about what to serialize and what not to serialize. Of course you can call objectoutputstream in these two methods respectively. defaultwriteobject () and objectinputstream. defaultreadobject () is still executedDefault serialization action(Then you will not be useless in code? You can also use the objectoutputstream. writeobject () and objectinputstream. readobject () Methods to serialize your desired attributes. But as soon as the virtual machine sees that you have defined these two methods, it will no longer use the default mechanism.
If you just want to skip some attributes to prevent them from being serialized, the above actions seem troublesome. A simpler method is to add attributes that do not want to be serialized.TransientKeyword indicates that it is a "Transient variable". By default, these attributes are not inserted into the external stream during serialization. Of course, if you define writeobject () and readobject () methods, you can still serialize transient variables. Digress, ImageTransient,Violate,FinallyBeginners may not pay much attention to such keywords, but some companies now prefer to ask the following questions :(
Another solution is to implement the externalizable interface instead of serializable. Let's look at the source code of these two interfaces and find that they are similar and even confusing. We must remember that: externalizable defaults andDo not save any object-related information! You define any action to save and restore objects. Externalizable contains two public methods:
- Public VoidWriteexternal (objectoutput out)ThrowsIoexception;
- Public VoidReadexternal (objectinput in)ThrowsIoexception,Classnotfoundexception;
At first glance, this is almost the same as the writeobject () and readobject () above, but serializable and externalizable follow two different processes: serializable when the object does not exist, the entire object can be reconstructed only by using the external byte sequence. However, when externalizable recreates an object, it first calls the default constructor of the class (that is, the constructor without parameters) so that the memory has such an instance first, and then call the readexternal method to restore the attributes in the instance. Therefore, if the default constructor and the readexternal method do not assign values to those attributes, in particular, if they are non-basic types, they will be null ). Note that,Transient can only be used in the implementation of serializable instead of externalizable..
★Serialization and cloning
According to the recursive definition of "serializable", a serialized object looks like an external clone of the object memory image. If the referenced attribute is not shared, it should beDeep clone. There are many questions about cloning. I will not elaborate on them here. If you are interested, refer to an article on IBM developerworks: pointers in Java, references, and object clone.
Some Inspiration
As a practical application, when I wrote the Simple Mail Client jexp, I used to compare several methods to save the message objects (mainly key attributes and mail content) to the local machine, for example, XML, properties, and so on, we finally chose the serialization method, because this method is the simplest, it can be regarded as "learning to use. Here, "Access Program Status" is actually just a topic. What I want to talk about ?? Just like what we discussed earlier about logging ?? In front of Java, you can have a variety of solutions for the same problem: familiar with file operations, you may think properties, XML or bean is more convenient, then I found out that there is a preferences, and I will probably feel "a day out of the sky" again. When you come into contact with many new methods, the result will be "same things" again ", review the serialization mechanism itself. This is not only Java, but also scientific.