New features in J2SDK 1.4

xiaoxiao2021-03-06  14

New features in J2SDK 1.4

Nio

1.1. Description: In the new I / O system, we will mainly use Channel and Buffer to describe our underlying operations.

1.2. Model:

1.3. Read and write to CHANNEL:

/ **

* @Author cenyongh@mails.gscas.ac.cn

* /

Public class copyfile {

Public static void main (string [] args) throws exception {

String in = args [0];

String Out = args [1];

FileInputStream Fis = New FileInputStream (in);

FileOutputStream Fos = New FileOutputStream (OUT);

Filechannel inc = fis.getchannel ();

FileChannel outc = fos.getchannel ();

Bytebuffer bb = bytebuffer.allocate (1024);

While (true) {

int RET = Inc.Read (BB);

IF (RET == -1) {

Break;

}

bb.flip ();

Outc.write (bb);

bb.clear ();

}

}

}

Note: We didn't read and write directly to Channel, but through Buffer to indirectly operate the CHANNEL. Here are two places to note that we call the flip () and clear () methods in the process of copying, the role of these two methods will be explained later.

1.4. Manual population buffer

/ **

* @Author cenyongh@mails.gscas.ac.cn

* /

Public class writefile {

Public static void main (string [] args) throws exception {

String Out = args [0];

String in = args [0];

FileInputStream Fin = New FileInputStream (in);

FileOutputStream Fout = New FileOutputStream (OUT);

FileChannel Inc = fin.getchannel ();

FileChannel Outc = fout.getChannel ();

Bytebuffer bb = bytebuffer.allocate (256);

For (int i = 0; i <256; i )

bb.put ((byte) i);

bb.flip ();

Outc.write (bb);

bb.clear ();

Inc.Read (bb);

bb.flip ();

For (int i = 0; i

System.out.println (bb.get ());

}

}

}

Note: By calling the PUT () and get () methods on the buffer, we can manually fill the data into the buffer.

1.5. Buffer's status quantity.

Buffer mainly uses three status quantity position, limited, and Capacity to mark the underlying state. Where Capacity characterizes the maximum capacity of the buffer, this value is set when the buffer is assigned, and it is generally not changed as the operation changes. Position characterizes the current read and write position of the buffer, whether it is a read operation or a write operation, will cause the Position to increase the Position. Limit characterizes the maximum readable and write location of Buffer, Limit is always less or equal to Capacity. 1.5.1. Structural diagram:

1.5.2. FLIP () and clear ()

FLIP () {

Limit = position;

Postion = 0;

}

Clear () {

Limit = Capacity;

Position = 0;

}

1.5.3. Example:

/ **

* @Author cenyongh@mails.gscas.ac.cn

* /

Public class copyfile {

Public static void main (string [] args) throws exception {

String in = args [0];

String Out = args [1];

FileInputStream Fis = New FileInputStream (in);

FileOutputStream Fos = New FileOutputStream (OUT);

Filechannel inc = fis.getchannel ();

FileChannel outc = fos.getchannel ();

Bytebuffer bb = bytebuffer.allocate (1024);

Inc.Read (bb);

Show (BB, "After Read");

bb.flip ();

Show (BB, "After Flip");

Outc.write (bb);

Show (BB, "After Write");

bb.clear ();

Show (BB, "After Clear");

}

Public Static Void Show (Bytebuffer BB, String MSG) {

System.out.println (MSG "P:" bb.position () "l:" bb.limit ()

"C:" bb.capacity ());

}

}

Output: after the After Read P:

1024 L:

1024 C: 1024

After Flip P:

0 L:

1024 C: 1024

After Write P:

1024 L:

1024 C: 1024

After clear P:

0 L:

1024 C: 1024

Note: When the read () operation is performed, the program will be as expected to populate the space between POSITION to LIMIT. When using Write () operation,

The program will read the space between POSITION to LIMIT. So, after calling the read () operation, you have to do other operations.

We must call the flip () to make the position of the position to the beginning; and when the Write () operation is used, it should be adjusted.

With clear (), this aspect makes the position back to the beginning while allowing the limit to the largest capacity of Buffer.

1.6. Subbuffer

When the SLICE () operation is called on the buffer, a paragraph of Buffer between [POSITION, LIMIT) is separately used as sub-buffer, and the sub-buffer uses the same space with the parent Buffer, but maintains the respective status quantity. 1.6.1. Structural diagram:

1.6.2. Example:

Bytebuffer Original = bytebuffer.allocate (8);

Original.Position (2);

ORIGINAL.LIMIT (6);

Bytebuffer Slice = Original.Slice ();

1.7. Other types of buffer

We can pack the most basic Bytebuffer into other Charbuffer, FloatBuffer, etc.

1.7.1. Structural diagram:

1.7.2. Example:

Bytebuffer buffer = bytebuffer.allocate (size);

Floatbuffer floatbuffer = buffer.AsfloatBuffer ();

1.8. Multi-format reading on Bytebuffer

When reading bytebuffer, in addition to the read mode of the fixed interval, we can also read in a long manner.

1.8.1. Example:

Fch.read (bb);

bb.flip ();

BYTE B0 = Bb.Get ();

Short s0 = bb.getshort ();

BYTE B1 = bb.get ();

Float f0 = bb.getfloat ();

1.9. Non-blocking I / O

In order to save resources, we can use TMC technology when implementing TCP / UDP-based chat servers. In order to allow the server to block in the accept () method, we can set a waiting timeout value. By using the Selector class, we can make the above methods easier and more efficient.

Public Class ServerStub IMPLEments Runnable {

Private selector selector = null;

Private INT port = 0;

...

Public void run () {

Started = true;

Try {

Selector = selector.open ();

Serversocketchannel Schannel = ServersocketChannel.Open ();

Schannel.configureblocking (false);

Serversocket ssocket = schannel.socket ();

SSOCKET.BIND (New InetsocketAddress);

Schannel.register (selector, selectionKey.op_accept);

SET SKS = NULL;

INT keys = 0;

While (Started) {

Keys = selector.select ();

IF (Keys> 0) {

SKS = selector.selectedKeys ();

Iterator it = SKS.ITERATOR ();

While (it.hasnext ()) {

SelectionKey Key = it.next ();

it.remove ();

IF (key.isreadable ()) {sender = (socketchannel) key.channel ();

String msg = receive (sender);

} else if (Key.isacceptable ()) {

Socketchannel sc = schannel.accept ();

Sc.configureBlocking (False);

Sc.register (selector, selectionKey.op_read);

} else {

Emit ("Something Abnormal");

}

}

}

}

} catch (exception e) {

E.PrintStackTrace ();

}

}

...

}

Note: The use of Selector allows the server to listen to the client in a way in an event response. by

SelectionKey provides constants, pipelines can register him to talk to interested events, for ServersocketChannel he

Only the OP_ACCEPT event can only be registered. When the user calls the selector.select () method, the thread will be blocked until a

Some incidents happen. The user then determines the type of event that occurs and performs the corresponding operation. There are a few things to pay attention to here, the first

It is necessary to use Selector's Channel needs to be set to non-blocking mode (false), second

It is the user needs manual to remove the process you have processed from the collection.

Public Class Clientstub IMPLEMENTS Runnable {

Private selector selector = null;

Private socketchannel channel channel = null;

Private boolean started = false;

...

Public void run () {

Started = true;

Try {

Selector = selector.open ();

Selector SEL = Selector.Open ();

Channel = Socketchannel.open ();

Channel.configureblocking (false);

Channel.register (selector, selectionKey.op_read

| SelectionKey.op_connect;

Channel.Connect (AddR);

SET SKS = NULL;

INT keys = 0;

While (Started) {

Keys = selector.select ();

IF (Keys> 0) {

SKS = selector.selectedKeys ();

Iterator it = SKS.ITERATOR ();

While (it.hasnext ()) {

SelectionKey Key = it.next ();

it.remove ();

IF (Key.IsReadable ()) {

String msg = receive (channel);

} else if (key.isconnectable ()) {

Channel.finishConnect ();

Key.INTERESTOPS (SelectionKey.op_Read);

} else {

Emit ("Something Abnormal");

}

}

}

}

} catch (exception e) {

E.PrintStackTrace ();

}

}

...

}

Note: The implementation of the client program is similar to the basics of the server. The only difference is that the client registers two event types op_read and op_connect at first, and when the client is connected to the server, he will receive an isconnectable SelectionKey. Here we need to call the finishconnect () method first, and then we need to monitor the connection event, so we need to modify the listening event type of Channel in Selector, which requires calling interactops () operations, where the method is the parameter is us The new event type required is very important.

1.10. Coding and decoding

J2SDK 1.4 provides classes for edit / decoding, Charstencoder, and Charstdecoder.

Public Charbuffer Decode (Bytebuffer BB) {

Charset C = Charset.Forname ("GB2312");

CharSetDecoder CD = C.NewDecoder ();

Charbuffer CB = CD.DECode (bb);

Return CB;

}

Note: The method of coding (charstencoder) is similar to the decoding.

2. Image I / O

J2SDK 1.4 provides classes that are specifically designed to read and write. Imageio. If we just want to read or output images simple, then we can directly use the static method provided by ImageIO. And if we want to read / write the picture / write, we can use ImageReader and ImageWriter, as well as a series of listener related to the image.

Public Image Readimage (String filename) {

BufferedImage Bi = imageio.read (New File (FileName));

Return Bi;

}

Public void writeImage () {

BufferedImage Bi = New BufferedImage (Width, Height, BufferedImage.Type_INT_ARGB);

Graphics2d g2 = bi.creategraphics ();

// Drawing operation

Imageio.write (BI, "JPEG", New File ("pic.jpg"));

}

3. log

J2SDK 1.4 provides classes, Logger, and formatter that are dedicated to writing logs.

3.1. Structural diagram:

In the Logger system, we need to get a logger instance, and then by calling the log method on the logger, we will generate a logRecord instance, which will be transferred to all Handler registered on the logger, then Handler uses him inside The Filter object to determine if the LogRecord record is to be handled. If you want to process, pass the logRecord to the Formatter, let him format the output format.

Public class test {

Public static void main (String [] args) {

Logger log = logger.getlogger ("test");

StreamHandler Sh = New StreamHandler (System.out, New SimpleFormatter ()); Log.AddHandler (SH);

Log.info ("Hello World");

}

}

Output: 2005-3-12 1:06:25 Nick.log.test Main

Information: Hello World

2005-3-12 1:06:25 Nick.log.test main

Information: Hello World

Description: Double log records are output here due to the logger of the parent class due to the Logger mechanism.

3.2. Custom Handler, Filter, Formatter

Public class testformatter extends formatter {

Public String Format (LogRecord Record) {

RETURN "Info Message:" Record.getMessage ();

}

}

Public class testfilter implements filter {

Public Boolean Isloggable (LogRecord Record) {

IF (Record.getlevel () == level.info)

Return True;

Else

Return False;

}

}

Public class testHandler extends handler {

Public void Publish (LogRecord R) {

IF (! isloggable (r))

Return;

System.out.println (getformatter (). Format (r));

}

Public void close () throws securityException {}

Public void flush () {}

}

Public class test {

Public static void main (String [] args) {

Logger log = logger.getlogger ("test");

Log.Setlevel (Level.all);

Log.setUseParentHandlers (false);

Testhandler TH = New TestHandler ();

Th.setfilter (New Testfilter ());

Th.setFormatter (New Testformatter ());

Log.addhandler (TH);

Log.info ("info");

Log.fine ("FINE");

}

}

Output: Info Message: Info

Description: In the main program, we call the setUseParentHandlers (false) method, which is to prohibit the current

Logger calls its parent Logger, which is true by default.

3.3. Default Handler and Its Configuration

The Log system provides five default Handler implementations: FileHandler, consolehandler, MemoryHandler, SocketHandler, StreamHandler. With configuration files, we can set its default properties. By setting the value of "java.util.loggin.config.file" in the System.SetProperty () method, you can specify the location of the configuration file. By default, the system uses /jre/lib/logging.properties as the configuration file. FileHandlerconsoleHandlerMemoryHandlerLevelyyyyyyyyyyyyyyystematteryyyyyyyyyystematteryyyy ,yyyyimattery ,y ,,,,, Y Push Y Target Y Host Y Port Y

Logging.properties content:

Nick.log.Log.Level = WARNING

Public class test {

Public static void main (String [] args) {

System.SetProperty ("java.util.logging.config.file",

"./logging.properties");

Logger log = logger.getlogger ("nick.log");

System.out.println (Log.getLevel ());

Log.setUseParentHandlers (false);

StreamHandler Sh = New StreamHandler (System.out, New SimpleFormatter ());

Log.addhandler (sh);

Log.Warning ("Warning");

Log.info ("info");

Log.fine ("FINE");

}

}

Output: Warning

2005-3-12 1:05:44 Nick.log.test main

WARNING: WARNING

4. Regular expression

J2SDK 1.4 introduces support for regular expressions. This mainly includes Pattern and Matcher classes.

Public class test {

Public static void main (String [] args) {

Pattern P = Pattern.Compile ("// s // s");

String InputString = "Well, Hey There Feller";

Matcher matcher = p.matcher (inputstring);

WHILE (matcher.find ()) {

INT Start = matcher.start ();

INT end = matcher.end ();

String matched = INPUTSTRING.SUBSTRING (START, END);

System.out.println (Match);

}

System.out.println ("===== Using Group: =====");

Matcher.reset (); while (matcher.find ()) {

String matched = matcher.group ();

System.out.println (Match);

}

}

}

Output: Well,

HEY

there

===== Using group: =====

Well,

HEY

there

Description: Pattern is compiled by the pattern that needs to be identified, which can improve the identification speed after it. Using Pattern

At the time, I should pay special attention to the regular expression list, and a large number of symbols starting with "/", so in Pattern

The "/ s" we need to write "// s". The plus sign is not a connection, but it means "1 this or multiple times"

The above program demonstrates how to use a pattern to identify a string and extract each matching string.

4.1. Capturing Group

In the regular expression in Pattern, we can define sub-expressions in the original expression, or called Capturing Group. Through Matcher, we can also directly extract the contents of a Capturing Group.

Public class test {

Public static void main (String [] args) {

Pattern P = pattern.Compile ("// s // s (// s ");

String InputString = "Hey There Feller";

Matcher matcher = p.matcher (inputstring);

WHILE (matcher.find ()) {

INT Start = matcher.start (1);

INT end = matcher.end (1);

String matched = INPUTSTRING.SUBSTRING (START, END);

System.out.println (Match);

}

System.out.println ("===== Using Group: =====");

Matcher.reset ();

WHILE (matcher.find ()) {

String matched = matcher.group (1);

System.out.println (Match);

}

}

}

Output: there

===== Using group: =====

there

Note: The number of Capturing Group starts from 1. Group number 0 represents the entire string.

4.2. Replace

Matcher provides methods for replacement. One is a simplicity of finding replacement, using the replaceAll () method. The second more flexible way, can be combined with Capturing Group when used.

Public class test {

Public static void main (String [] args) {

Pattern P = Pattern.Compile ("// s // s");

String InputString = "Hey There Feller";

Matcher matcher = p.matcher (inputstring); string ns = matcher.replaceAll ("Hello");

System.out.println (NS);

}

}

Output: Hello Hello Feller

Public class test {

Public static void main (String [] args) {

Pattern Pattern = Pattern.Compile ("((// w | // s) *) //)")

String InputString = "these Should Be (Square Brackets). (Hello);

StringBuffer SB = new stringbuffer ();

Matcher matcher = pattern.matcher (inputstring);

WHILE (matcher.find ()) {

Matcher.AppendReplacement (SB, "[$ 1]");

}

Matcher.Appendtail (SB);

String news = sb.toString ();

System.out.println (newstring);

}

}

Output: these Should Be [Square Brackets]. [Hello]

Note: This method is replaced, since Capturing Group is added. So more flexible than the previous method. in

Appendreplacement ()

In the method, we use the contents of the second parameter, replace the matching part. And $ X is the value used to reference the corresponding capturing group.

转载请注明原文地址:https://www.9cbs.com/read-46931.html

New Post(0)