JAVA网站制作之J2SDK 1.4中的新功能类
java也能做一些底层语言开发做的事情(难度很高,不是java顶尖高手是做不来的),1.NIO
1.1.申明:在新的I/O体系傍边,我们将次要利用Channel和Buffer来形貌我们底层的操纵。
1.2.模子:
1.3.对Channel举行读写:
/**
*@authorcenyongh@mails.gscas.ac.cn
*/
publicclassCopyFile{
publicstaticvoidmain(String[]args)throwsException{
Stringin=args;
Stringout=args;
FileInputStreamfis=newFileInputStream(in);
FileOutputStreamfos=newFileOutputStream(out);
FileChannelinc=fis.getChannel();
FileChanneloutc=fos.getChannel();
ByteBufferbb=ByteBuffer.allocate(1024);
while(true){
intret=inc.read(bb);
if(ret==-1){
break;
}
bb.flip();
outc.write(bb);
bb.clear();
}
}
}
注:我们并没有间接对Channel举行读写,而是经由过程Buffer来对Channel举行直接操纵。这里有两个中央要注重,就是我们在拷贝的历程傍边挪用了flip()和clear()办法,这两个办法的感化,将在前面解说。
1.4.手工添补Buffer
/**
*@authorcenyongh@mails.gscas.ac.cn
*/
publicclassWriteFile{
publicstaticvoidmain(String[]args)throwsException{
Stringout=args;
Stringin=args;
FileInputStreamfin=newFileInputStream(in);
FileOutputStreamfout=newFileOutputStream(out);
FileChannelinc=fin.getChannel();
FileChanneloutc=fout.getChannel();
ByteBufferbb=ByteBuffer.allocate(256);
for(inti=0;i<256;i++)
bb.put((byte)i);
bb.flip();
outc.write(bb);
bb.clear();
inc.read(bb);
bb.flip();
for(inti=0;i<bb.limit();i++){
System.out.println(bb.get());
}
}
}
注:经由过程挪用Buffer上的put()和get()办法,我们能够手工的往Buffer傍边添补数据。
1.5.Buffer的形态量。
Buffer次要利用三个形态量position,limit,capacity来标志底层的形态。个中capacity表征Buffer的最年夜容量,这个值在Buffer被分派时设定,一样平常不会跟着操纵改动。position表征Buffer确当前读写地位,不论是读操纵仍是写操纵,城市招致position的增添。limit表征Buffer的最年夜可读写地位,limit老是小于或即是capacity。
1.5.1.布局图:
1.5.2.flip()和clear()操纵
flip(){
limit=position;
postion=0;
}
clear(){
limit=capacity;
position=0;
}
1.5.3.例子:
/**
*@authorcenyongh@mails.gscas.ac.cn
*/
publicclassCopyFile{
publicstaticvoidmain(String[]args)throwsException{
Stringin=args;
Stringout=args;
FileInputStreamfis=newFileInputStream(in);
FileOutputStreamfos=newFileOutputStream(out);
FileChannelinc=fis.getChannel();
FileChanneloutc=fos.getChannel();
ByteBufferbb=ByteBuffer.allocate(1024);
inc.read(bb);
show(bb,"Afterread");
bb.flip();
show(bb,"Afterflip");
outc.write(bb);
show(bb,"Afterwrite");
bb.clear();
show(bb,"Afterclear");
}
publicstaticvoidshow(ByteBufferbb,Stringmsg){
System.out.println(msg+"p:"+bb.position()+"l:"+bb.limit()
+"c:"+bb.capacity());
}
}
输入:Afterreadp:1024l:1024c:1024
Afterflipp:0l:1024c:1024
Afterwritep:1024l:1024c:1024
Afterclearp:0l:1024c:1024
注:在举行read()操纵时,程序将只管的添补从position到limit之间的空间。在举行write()操纵时,
程序将读出从position到limit之间的空间。以是,在挪用完read()操纵今后,要举行其他操纵之前,
我们必需要挪用flip()操纵,使得position的地位回指到开首;而当挪用完write()操纵今后,应调
用clear()操纵,这一方面使得position回指到开首,同时使得limit抵达Buffer最年夜的容量处。
1.6.子Buffer
当在Buffer下面挪用slice()操纵时,将独自划出在[position,limit)之间的一段Buffer作为子Buffer,子Buffer与父Buffer利用不异的空间,但保护各自的形态量。
1.6.1.布局图:
1.6.2.例子:
ByteBufferoriginal=ByteBuffer.allocate(8);
original.position(2);
original.limit(6);
ByteBufferslice=original.slice();
1.7.其他范例的Buffer
我们能够把最基础的ByteBuffer包装成其他的CharBuffer,FloatBuffer等。
1.7.1.布局图:
1.7.2.例子:
ByteBufferbuffer=ByteBuffer.allocate(size);
FloatBufferfloatBuffer=buffer.asFloatBuffer();
1.8.在ByteBuffer上的多格局读取
在对ByteBuffer举行读取时,除能够依照流动距离的读取体例之外,我们也能够依照变长的体例读取。
1.8.1.例子:
fch.read(bb);
bb.flip();
byteb0=bb.get();
shorts0=bb.getShort();
byteb1=bb.get();
floatf0=bb.getFloat();
1.9.非堵塞I/O
在完成基于TCP/UDP的谈天服务器时,为了节俭资本我们可使用轮训手艺。而为了让服务器不永久堵塞在accept()办法上,我们能够设置一个守候超时价。而经由过程利用Selector类,我们可让以上办法更简单,更高效的失掉完成。
publicclassServerStubimplementsRunnable{
privateSelectorselector=null;
privateintport=0;
…
publicvoidrun(){
started=true;
try{
selector=Selector.open();
ServerSocketChannelschannel=ServerSocketChannel.open();
schannel.configureBlocking(false);
ServerSocketssocket=schannel.socket();
ssocket.bind(newInetSocketAddress("127.0.0.1",port));
schannel.register(selector,SelectionKey.OP_ACCEPT);
Set<SelectionKey>sks=null;
intkeys=0;
while(started){
keys=selector.select();
if(keys>0){
sks=selector.selectedKeys();
Iterator<SelectionKey>it=sks.iterator();
while(it.hasNext()){
SelectionKeykey=it.next();
it.remove();
if(key.isReadable()){
sender=(SocketChannel)key.channel();
Stringmsg=receive(sender);
}elseif(key.isAcceptable()){
SocketChannelsc=schannel.accept();
sc.configureBlocking(false);
sc.register(selector,SelectionKey.OP_READ);
}else{
emit("SomethingAbnormal");
}
}
}
}
}catch(Exceptione){
e.printStackTrace();
}
}
…
}
注:Selector的利用,使得服务器能以一种事务呼应的体例对客户真个毗连举行监听。经由过程
SelectionKey供应的常量,管道能够注册他说感乐趣的事务,关于ServerSocketChannel他
只能注册OP_ACCEPT事务。当用户挪用selector.select()办法时,线程将会被堵塞,直到某
些事务产生了。然后用户判别产生的事务范例并举行对应的操纵。这里有几点必要注重,第一
是必要利用Selector的Channel必要设置为非堵塞形式(configureBlocking(false)),第二
是用户必要手工的把已处置的SelectionKey,从汇合中移除。
publicclassClientStubimplementsRunnable{
privateSelectorselector=null;
privateSocketChannelchannel=null;
privatebooleanstarted=false;
…
publicvoidrun(){
started=true;
try{
selector=Selector.open();
Selectorsel=Selector.open();
channel=SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector,SelectionKey.OP_READ
|SelectionKey.OP_CONNECT);
channel.connect(addr);
Set<SelectionKey>sks=null;
intkeys=0;
while(started){
keys=selector.select();
if(keys>0){
sks=selector.selectedKeys();
Iterator<SelectionKey>it=sks.iterator();
while(it.hasNext()){
SelectionKeykey=it.next();
it.remove();
if(key.isReadable()){
Stringmsg=receive(channel);
}elseif(key.isConnectable()){
channel.finishConnect();
key.interestOps(SelectionKey.OP_READ);
}else{
emit("SomethingAbnormal");
}
}
}
}
}catch(Exceptione){
e.printStackTrace();
}
}
…
}
注:客户端程序的完成与服务器真个基础类似。独一的一点区分就是,客户端一入手下手注册了两个事务范例OP_READ和OP_CONNECT,而当客户端毗连上服务器今后,他将会收到一个isConnectable的SelectionKey。在这里我们必要先挪用finishConnect()办法,然后因为我们不再必要监听毗连事务,因而我们必要修正Channel在Selector上的监听事务范例,这必要挪用interestOps()操纵来完成,个中办法的参数就是我们所必要的新的事务范例,这一步骤十分主要。
1.10.编码与解码
J2SDK1.4供应了专门用于举行编/解码的类,CharsetEncoder和CharstDecoder。
publicCharBufferdecode(ByteBufferbb){
Charsetc=Charset.forName("gb2312");
CharsetDecodercd=c.newDecoder();
CharBuffercb=cd.decode(bb);
returncb;
}
注:编码(CharsetEncoder)的办法与解码的相似。
2.ImageI/O
J2SDK1.4供应了专门用于图片读写的类。ImageIO。假如我们只是想复杂的读取或输入图片的话,那末我们能够间接利用ImageIO供应的static办法。而假如我们想对图片的读/写举行更多的把持的话,我们可使用ImageReader和ImageWriter,和与图片读写相干的一系列Listener。
publicImagereadImage(Stringfilename){
BufferedImagebi=ImageIO.read(newFile(filename));
returnbi;
}
publicvoidwriteImage(){
BufferedImagebi=newBufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2Dg2=bi.createGraphics();
//画图操纵
ImageIO.write(bi,"jpeg",newFile("pic.jpg"));
}
3.Log
J2SDK1.4供应了专门用于誊写日记的类,Logger及其相干的Handler,Filter和Formatter。
3.1.布局图:
在Logger体系傍边,我们必要先猎取一个Logger实例,然后经由过程挪用Logger上的日记办法,我们将发生一个LogRecord实例,该实例将会被传送到在Logger上注册的一切Handler内,然后Handler利用他外部的Filter对象,以判别是不是要处置该LogRecord纪录,假如要处置的话,则把LogRecord传送给Formatter,让他对输入格局举行格局化。
publicclassTest{
publicstaticvoidmain(String[]args){
Loggerlog=Logger.getLogger("Test");
StreamHandlersh=newStreamHandler(System.out,newSimpleFormatter());
log.addHandler(sh);
log.info("HelloWorld");
}
}
输入:2005-3-121:06:25nick.log.Testmain
信息:HelloWorld
2005-3-121:06:25nick.log.Testmain
信息:HelloWorld
申明:因为Logger机制会递回的挪用父类的Logger,因而,这里输入了两份日记纪录。
3.2.自界说Handler,Filter,Formatter
publicclassTestFormatterextendsFormatter{
publicStringformat(LogRecordrecord){
return"INFOMESSAGE:"+record.getMessage();
}
}
publicclassTestFilterimplementsFilter{
publicbooleanisLoggable(LogRecordrecord){
if(record.getLevel()==Level.INFO)
returntrue;
else
returnfalse;
}
}
publicclassTestHandlerextendsHandler{
publicvoidpublish(LogRecordr){
if(!isLoggable(r))
return;
System.out.println(getFormatter().format(r));
}
publicvoidclose()throwsSecurityException{}
publicvoidflush(){}
}
publicclassTest{
publicstaticvoidmain(String[]args){
Loggerlog=Logger.getLogger("Test");
log.setLevel(Level.ALL);
log.setUseParentHandlers(false);
TestHandlerth=newTestHandler();
th.setFilter(newTestFilter());
th.setFormatter(newTestFormatter());
log.addHandler(th);
log.info("info");
log.fine("fine");
}
}
输入:INFOMESSAGE:info
申明:在主程序内里,我们挪用了setUseParentHandlers(false)办法,如许做是为了克制以后
的Logger挪用其父类Logger,默许情形下该值为true。
3.3.默许Handler及其设置
Log体系供应了五个默许Handler的完成:FileHandler,ConsoleHandler,MemoryHandler,SocketHandler,StreamHandler。经由过程设置文件,我们能够设定其默许属性。而经由过程在System.setProperty()办法内里设定“java.util.loggin.config.file”的值,能够指定设置文件的地位,默许情形下体系利用/jre/lib/logging.properties作为设置文件。
FileHandler
ConsoleHandler
MemoryHandler
SocketHandler
StreamHandler
level
y
y
y
Y
Y
filter
y
y
y
Y
Y
formatter
y
y
y
Y
encoding
y
y
y
Y
limit
y
count
y
pattern
y
append
y
size
y
push
y
target
y
host
Y
port
Y
logging.properties的内容:
nick.log.level=WARNING
publicclassTest{
publicstaticvoidmain(String[]args){
System.setProperty("java.util.logging.config.file",
"./logging.properties");
Loggerlog=Logger.getLogger("nick.log");
System.out.println(log.getLevel());
log.setUseParentHandlers(false);
StreamHandlersh=newStreamHandler(System.out,newSimpleFormatter());
log.addHandler(sh);
log.warning("warning");
log.info("info");
log.fine("fine");
}
}
输入:WARNING
2005-3-121:05:44nick.log.Testmain
告诫:warning
4.正则表达式
J2SDK1.4引进了对正则表达式的撑持。这次要包含Pattern和Matcher类。
publicclassTest{
publicstaticvoidmain(String[]args){
Patternp=Pattern.compile("+");
StringinputString="well,heytherefeller";
Matchermatcher=p.matcher(inputString);
while(matcher.find()){
intstart=matcher.start();
intend=matcher.end();
Stringmatched=inputString.substring(start,end);
System.out.println(matched);
}
System.out.println("=====UsingGroup:=====");
matcher.reset();
while(matcher.find()){
Stringmatched=matcher.group();
System.out.println(matched);
}
}
}
输入:well,
hey
there
=====UsingGroup:=====
well,
hey
there
申明:Pattern对必要举行辨认的形式举行编译,这能够进步以后的辨认速率。在利用Pattern
时有一点要出格注重,就是正则表达式单中,大批的利用以“”开首的标记,以是为了在Pattern
中暗示“”我们必要写成“”。而傍边的加号并非暗示毗连,而是暗示“1此或屡次”
上述程序演示了怎样利用一个形式往辨认一个字符串,并提取每个婚配的串。
4.1.捕捉组(CapturingGroup)
在Pattern傍边的正则表达傍边,经由过程利用括号,我们能够在本来的表达式傍边界说子表达式,大概称为CapturingGroup。经由过程Matcher,我们还能够间接提取某一个CapturingGroup的内容。
publicclassTest{
publicstaticvoidmain(String[]args){
Patternp=Pattern.compile("++(+)++");
StringinputString="heytherefeller";
Matchermatcher=p.matcher(inputString);
while(matcher.find()){
intstart=matcher.start(1);
intend=matcher.end(1);
Stringmatched=inputString.substring(start,end);
System.out.println(matched);
}
System.out.println("=====UsingGroup:=====");
matcher.reset();
while(matcher.find()){
Stringmatched=matcher.group(1);
System.out.println(matched);
}
}
}
输入:there
=====UsingGroup:=====
there
申明:CapturingGroup的编号是从1入手下手的。组号为0的组暗示全部串。
4.2.交换
Matcher供应用于交换的办法。一种是复杂举行查找交换,利用replaceAll()办法。第二种加倍天真的体例,在利用的时分能够分离CapturingGroup。
publicclassTest{
publicstaticvoidmain(String[]args){
Patternp=Pattern.compile("+");
StringinputString="heytherefeller";
Matchermatcher=p.matcher(inputString);
Stringns=matcher.replaceAll("Hello");
System.out.println(ns);
}
}
输入:HelloHellofeller
publicclassTest{
publicstaticvoidmain(String[]args){
Patternpattern=Pattern.compile("(((w|)*))");
StringinputString="Theseshouldbe(squarebrackets).(hello)";
StringBuffersb=newStringBuffer();
Matchermatcher=pattern.matcher(inputString);
while(matcher.find()){
matcher.appendReplacement(sb,"[$1]");
}
matcher.appendTail(sb);
StringnewString=sb.toString();
System.out.println(newString);
在1995年5月23日以“Java”的名称正式发布了。 我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。 学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。 关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。 是一种将安全性(Security)列为第一优先考虑的语言 是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能 在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。 Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。 Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。 你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。 其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。 Java是一种计算机编程语言,拥有跨平台、面向对java Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。 Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading) 其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。 应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展 至于JDBC,就不用我多说了,你如果用java编过存取数据库的程序,就应该很熟悉。还有,如果你要用Java编发送电子邮件的程序,你就得看看Javamail 了。 在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
页:
[1]