`
kobe学java
  • 浏览: 257912 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java nio 在探索

    博客分类:
  • MINA
 
阅读更多

 

nio之所以为为新,在于它并没在原来I/O的基础上进行开发,而是提供了全新的类和接口,除了原来的基本功能之外,它还提供了以下新的特征:
        ► 多路选择的非封锁式I/O设施
        ►支持文件锁和内存映射
        ►支持基于Perl风格正则表达式的模式匹配设施
        ►字符集编码器和译码器
        为了支持这些新的功能,nio使用了两个新的概念:

 1. 信道(channel)
                 信道是一个连接,可用于接收或发送数据,如文件和套接字。因为信道连接的是底层的物理设备,他可以直接支持设备的读/写,或提供文件锁。对于文件、管道、套接字都存在相应的信道类。可以把信道看成是数据流的替代品。信道没有包装类,提高了性能。  所有的信道类都位于java.nio.channels包中。

 2. 缓冲区(buffer)
       缓冲区是一个数据容器。可以把它看做内存中的一个大的数组,用来存储来自信道的同一类型的所有数据,因此,程序员可以使用字节、字符、整数等缓冲区。字节缓冲区提供必要的方法,可以提取或存入所有基本类型(boolean型除外)的数据。 
       buffer类的核心是一块内存区,便于核心代码和java代码同时访问,核心代码可以直接访问它,java代码可以通过API访问它。
       缓冲区基本上是一块内存区域,因而可以执行一些与内存有关的操作,如清除其中的内容,支持读写或只读操作等。所有的buffer类都位于java.nio包中。

 下面看如何使用它们:
1.      使用信道
在信道的使用中,文件的信道是最具有代表性的,API也是最多的,下面我们以文件信道为例介绍它。
●     获取文件信道
文件的信道的类为FileChannel,遗憾的是他并没有向我们提供打开文件的方法,我们可以通过调用FileInputStream、FileOutputStream和RandomAccessFile类实例的getChannel()方法来获取其实例。例如:

RandomAccessFile raf = new RandomAccessFile(“data.txt”, “rw”);
FileChannel fc 
= raf.getChannel();


●    从信道读取数据
读取的数据会默认放到字节缓冲区中。
FileChannel提供了四个API读取数据:

a.    read(ByteBuffer dst) 将字节序列从此通道读入给定的缓冲区
b.   read(ByteBuffer[] dsts) 将字节序列从此通道读入给定的缓冲区
c.    read(ByteBuffer[] dsts, 
int offset, int length) 
          将字节序列从此通道读入给定缓冲区的子序列中
d.    read(ByteBuffer dst, 
long position) 
          从给定的文件位置开始,从此通道读取字节序列,并写入给定的缓冲区


●    向信道写入数据
数据来源默认是字节缓冲区。
FileChannel提供了四个API写入数据:

a. write(ByteBuffer src) 
          将字节序列从给定的缓冲区写入此通道
b. write(ByteBuffer[] srcs) 
          将字节序列从给定的缓冲区写入此通道
c. write(ByteBuffer[] srcs, 
int offset, int length) 
          将字节序列从给定缓冲区的子序列写入此通道
d. write(ByteBuffer src, 
long position) 
          从给定的文件位置开始,将字节序列从给定缓冲区写入此通道


 ● 使用文件锁
      文件锁机制主要是在多线程同时读写某个文件资源时使用。
      FileChannel提供了两种加锁机制,lock和tryLock,两者的区别在于,lock是同步的,
      直至成功才返回,tryLock是异步的,无论成不成功都会立即返回。

 ● 使用内存映射
    FileChannel提供的的API为:
    MappedByteBuffer map(FileChannel.MapMode mode,  long position, long size);
    映射模式一个有三种:

 a.只读: 试图修改得到的缓冲区将导致抛出 ReadOnlyBufferException.(MapMode.READ_ONLY) 
          b.读
/写: 对得到的缓冲区的更改最终将传播到文件;该更改对映射到同一文件的其他程序不一定是可见的。 (MapMode.READ_WRITE) 
          c.专用: 对得到的缓冲区的更改不会传播到文件,并且该更改对映射到同一文件的其他程序也不是可见的;相反,会创建缓冲区已修改部分的专用副本。 (MapMode.PRIVATE) 


2.   使用缓冲区●     层次结构所有缓冲区的基类都是Buffer,除Boolean类型外,其它数据类型都有对应的缓冲区类,另有一个ByteOrder类,用来设置缓冲区的大小端顺序,即BigEndian或者是LittleEndian,默认情况下是BigEndian。其层次结构图如下:


●     获取缓冲区对象一共有两种类型的缓冲区,直接缓冲区和非直接缓冲区,两者区别在于直接缓冲区上的数据操作,虚拟机将尽量使用本机I/O,并尽量避免使用中间缓冲区。判断一个缓冲区是否是直接缓冲区,可以调用isDirect()方法。有三种方式来获取一个缓冲区的对象:
a.      调用allocate()或者allocateDirect()方法直接分配,其中allocateDirect()返回的是直接缓冲区。
b.      包装一个数组,如:byte[] b = new byte[1024];ByteBuffer bb = ByteBuffer.wrap(b);
c.       内存映射,即调用FileChannel的map()方法。

ByteBuffer buffer1 = ByteBuffer.allocate(1024);
ByteBuffer buffer2 
= ByteBuffer.allocateDirect(1024);
ByteBuffer buffer3 
= ByteBuffer.wrap(new String("hello").getBytes());



●     缓冲区基本属性这几个属性是每个缓冲区都有的并且是常用的操作。
a.     容量(capacity),缓冲区大小
b.      限制(limit),第一个不应被读取或写入的字节的索引,总是小于容量。
c.       位置(position),下一个被读取或写入的字节的索引,总是小于限制。
d.      clear()方法:设置limit为capacity,position为0。
e.      filp()方法:设置limit为当前position,然后设置position为0。
f.        rewind()方法:保持limit不变,设置position为0。


●     缓冲区数据操作操作包括了读取和写入数据两种。读取数据使用get()及其系列方法,除boolean外,每一种类型包括了对应的get()方法,如getInt(),getChar()等,get()方法用来读取字节,支持相对和绝对索引两种方式。写入数据使用put()及其系列方法,和get()方法是对应的。           下面这个例子演示了如何使用缓冲区和信道:

package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class BufferDemo {       
    
public static void main(String[] args) throws Exception{  
       
//分配一个非直接缓冲区       
        ByteBuffer bb = ByteBuffer.allocate(100);   
    
//向缓冲区写入0到100的字节制    
    for(int i = 0; i <100; i++){     
         
byte b = (byte) (Math.random() * 100);  
         bb.put(b);        }
     
        System.out.println(
"写入文件前的缓冲区数据"); 
    bb.flip();      
    
while(bb.hasRemaining())       
          System.out.print(bb.get() 
+ " ");   
    System.out.println();              
    
//获取一个关联到文件buffer.txt的信道    
    FileChannel fc = new FileOutputStream("buffer.txt").getChannel();   
    
//将缓冲区数据写到文件中      
    bb.flip();      
    fc.write(bb);    
    
//防止缓存       
    fc.force(true);      
    
//关闭信道       
    fc.close();       
    bb 
= null;       
    fc 
= null;                
    
//下面从文件中读取数据       
    fc = new FileInputStream("buffer.txt").getChannel();   
    ByteBuffer bb2 
= ByteBuffer.allocate((int) fc.size());   
    fc.read(bb2);      
    System.out.println(
"从文件读取的缓冲区数据");   
    bb2.flip();      
    
while(bb2.hasRemaining())      
         System.out.print(bb2.get() 
+ " ");     
    System.out.println();       
    fc.close();       
    bb2 
= null;       
    fc 
= null;            }
}


  3.视图缓冲区         
  上面我们的缓冲区都是基于字节的,像IntBuffer、LongBuffer等这些都可以调用ByteBuffer的         as***Buffer(***表示某个数据类型)得到,所以这种类型的缓冲区又被称为视图缓冲区(View Buffer),       视图缓冲区有以下特点:
      a.     视图缓冲区有自己独立的position和limit,但它不是一个新的创建,只是原来字节缓冲区的一个逻辑缓冲区,字节缓冲区的任何修改都会影响视图缓冲区,反之亦然。
      b.      视图缓冲区按照数据类型的大小进行索引,而不是字节顺序。
      c.       也提供了put()和get()及其系列方法,用于数据的整块传输。      
 下面这个例子演示了视图缓冲区:

package nio;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;

public class ViewBufferDemo {   
    
public static void main(String[] args) throws Exception{   
    
//将文件内容读到缓冲区中      
    FileChannel fc = new FileInputStream("buffer.txt").getChannel();    
    ByteBuffer bb 
= ByteBuffer.allocate((int) fc.size());    
    fc.read(bb);        
    fc.close();      
    fc 
= null;           
    System.out.println(
"从文件读取的字节缓冲区数据");      
    bb.flip();       
    
while(bb.hasRemaining())         
         System.out.print(bb.get() 
+ " ");  
    System.out.println();    
    
//获取视图缓冲区        
    bb.flip();        
    IntBuffer ib 
= bb.asIntBuffer();       
    System.out.println(
"将字节缓冲区作为整形缓冲区的数据");  
    
while(ib.hasRemaining())           
         System.out.print(ib.get() 
+ " ");  
    System.out.println();               
    bb 
= null;        
    ib 
= null;            
    }
}



  4.映射内存缓冲区         
  调用信道的map()方法后,即可将文件的某一部分或全部映射到内存中,映射内存缓冲区是一         个直接缓冲区,继承自ByteBuffer,但相对于ByteBuffer,它有更多的优点:
  a.     内存映射I/O是对信道/缓冲区技术的改进。 当传输大量的数据时,内存映射I/O速度相对较快,这是因为它使用虚拟内存把文件传输到进程的地址空间中。
  b.      映射内存也成为共享内存,因此可以用于相关进程(均映射同一文件)之间的整块数据传输,这些进程甚至可以不必位于同一系统上,只要每个都可以访问同一文件即可。
  c.       当对FileChannel执行映射操作,把文件映射到内存中时,得到的是一个连接到文件的映射的字节缓冲区,这种映射的结果是,当输出缓冲区的内容时,数据将出现在文件中,当读入缓冲区时,相当于得到文件中的数据。        下面这个例子演示了映射内存:

package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
    
public class CopyFile {  
        
public static void main(String[] args) throws Exception {  
    FileChannel fIChan, fOChan;      
    MappedByteBuffer mBuf;       
    fIChan 
= new FileInputStream("buffer.txt").getChannel();  
    fOChan 
= new FileOutputStream("bufferTemp.txt").getChannel();    
    mBuf 
= fIChan.map(FileChannel.MapMode.READ_ONLY, 0, fIChan.size());        fOChan.write(mBuf);        
    fIChan.close();       
    fOChan.close();               
    fIChan 
= null;       
    fOChan 
= null;        
    mBuf 
= null;    
}
}



NIO网络支持

●服务器端:接收请求的应用程序。
●客户端:向服务器端发出请求的应用程序。
●套接字通道:客户端与服务器端之间的通信通道。它能识别服务器端的IP地址和端口号。数据以Buffer中元素的形式通过套接字通道传送。
●选择器:所有非阻塞技术的主要对象。它监视着已注册的套接字通道,并序列化服务器需要应答的请求。
●关键字:选择器用来对对象的请求进行排序。每个关键字代表一个单独的客户端子请求并包含识别客户端和请求类型的信息。

图一:使用非阻塞套接字体系的结构图。


你可能注意到,客户端应用程序同时执行对服务器端的请求,接着选择器将其集中起来,创建关键字,然后将其发送至服务器端。这看起来像是阻塞(Blocking)体系,因为在一定时间内只处理一个请求,但事实并非如此。实际上,每个关键字不代表从客户端发至服务器端的整个信息流,仅仅只是一部分。我们不要忘了选择器能分割那些被关键字标识的子请求里的数据。因此,如果有更多连续地数据发送至服务器端,那么选择器就会创建更多的根据时间共享策略(Time-sharing policy)来进行处理的关键字。强调一下,在图一中关键字的颜色与客户端的颜色相对应。
服务器端非阻塞(Server Nonblocking)
我以前的部分介绍过的实体都有与其相当的Java实体。客户端和服务器端是两个Java应用程序。套接字通道是SocketChannel类的实例,这个类允许通过网络传送数据。它们能被Java程序员看作是一个新的套接字。SocketChannel类被定义在java.nio.channel包中。
选择器是一个Selector类的对象。该类的每个实例均能监视更多的套接字通道,进而建立更多的连接。当一些有意义的事发生在通道上(如客户端试图连接服务器端或进行读/写操作),选择器便会通知应用程序处理请求。选择器会创建一个关键字,这个关键字是SelectionKey类的一个实例。每个关键字都保存着应用程序的标识及请求的类型。其中,请求的类型可以是如下之一:
●尝试连接(客户端)
●尝试连接(服务器端)
●读取操作
●写入操作
一个通用的实现非阻塞服务器的算法如下:
基本上,服务器端的实现是由选择器等待事件和创建关键字的无限循环组成的。根据关键字的类型,及时的执行操作。关键字存在以下4种可能的类型。
Acceptable: 相应的客户端要求连接。
Connectable:服务器端接受连接。
Readable:服务器端可读。
Writeable:服务器端可写。
通常一个表示接受的关键字创建在服务器端。事实上,这种关键字仅仅通知一下服务器端客户端请求连接。在这种环境下,正如你通过算法得到的结论一样,服务器端个性化套接字通道和连接这个通道到选择器以便进行读/写操作。从这一刻起,当接受客户端读或写操作时,选择器将为客户端创建Readable或Writeable关键字。从而,服务器端将截取这些关键字并执行正确的动作。
现在,你可以用下面这个推荐算法和Java语言写服务器端了。用这种方法能成功的创建套接字通道,选择器,和套接字-选择器注册(socket-selector registration)。

// Create the server socket channel
ServerSocketChannel server = ServerSocketChannel.open();
// nonblocking I/O
server.configureBlocking(false);
// host-port 8000
server.socket().bind(new java.net.InetSocketAddress(host,8000));
System.out.println(
"Server attivo porta 8000");
// Create the selector
Selector selector = Selector.open();
// Recording server to selector (type OP_ACCEPT)
server.register(selector,SelectionKey.OP_ACCEPT);


我们使用OP_ACCEPT,意思是选择器仅能报告客户端尝试连接服务器端。其他可能的选项是:OP_CONNECT,在客户端下使用;OP_READ; 和OP_WRITE。

// Infinite server loop
for(;;) {
// Waiting for events 
selector.select(); 
// Get keys  
Set keys = selector.selectedKeys(); 
Iterator i 
= keys.iterator(); 
// For each keys 
while(i.hasNext()) {   
  SelectionKey key 
= (SelectionKey) i.next(); 
 
// Remove the current key  
  i.remove();   
// if isAccetable = true// then a client required a connection   
  if (key.isAcceptable()) {    
   
// get client socket channel     
    SocketChannel client = server.accept();  
    
// Non Blocking I/O     
    client.configureBlocking(false);    
    
// recording to the selector (reading)     
    client.register(selector, SelectionKey.OP_READ);    
    
continue;    }
   
    
// if isReadable = true    // then the server is ready to read  
  if (key.isReadable()) {    
     SocketChannel client 
= (SocketChannel) key.channel();  
     
// Read byte coming from the client    
     int BUFFER_SIZE = 32;      
     ByteBuffer buffer 
= ByteBuffer.allocate(BUFFER_SIZE);    
     
try {        
         client.read(buffer);    
     }
   catch (Exception e) {    
    
// client is no longer active     
    e.printStackTrace();       
    
continue;      
    }
      // Show bytes on the console    
    buffer.flip();      
    Charset charset
=Charset.forName("ISO-8859-1");    
    CharsetDecoder decoder 
= charset.newDecoder();   
    CharBuffer charBuffer 
= decoder.decode(buffer);   
    System.out.print(charBuffer.toString());    
    
continue;   
    }
  }
}


循环的第一行是调用select方法,它会阻塞进程执行并等待选择器上记录的事件。在这段代码中,套接字通道由服务器变量指代。实际上,服务器端不是一个SocketChannel对象,而是一个ServerSocketChannel对象。它象SocketChannel一样是SelectableChannel类的一般化,通常用于服务器端的应用程序。
选择器等待的事件是客户端尝试连接。当这样的操作出现时,服务器端的应用程序便获得一个由选择器创建的关键字和检查每个关键字的类型。你也许注意到,当一个关键字被处理时,它不得不调用remove方法从这组关键字中被移出。如果这个关键字的类型是可接受的(isAcceptable()=true),那么服务器端便通过调用accept方法来查找客户端套接字通道,设置它为非阻塞,并将OP_READ选项把它登记进选择器中。我们也可以使用OP_WRITE 或者是OP_READ|OP_WRITE选项,但为了简单,我实现的服务器端仅仅能从通道中读取,不能进行写入操作。

客户端套接字通道现在已经登记入选择器并可进行读取操作。从而,当客户端在套接字通道上写数据时,选择器将通知服务器端应用程序这里有一些数据读。随着可读关键字的创建,从而isReadable()=true。在这个例子中,应用程序从套接字通道上读取数据使用的是32个字节的ByteBuffer,字节译码使用的是ISO-8859-1编码规则,同时读取的数据也会显示在服务器端的控制台上。


客户端非阻塞(Client Nonblocking)
为了检验编制的服务器端能否以非阻塞的方法工作正常,我将实现一个客户端以期在套接字通道上连续地写字符串“Client XXX”,这里的“XXX”是命令行所传递的参数。例如,当客户端运行的命令行的参数是89时,服务器端的控制台上就会显示“Client 89 Client 89 Client 89 Client 89 ...”。如果其它的客户端开始的参数是92时会发生些什么呢?如果服务器端已阻塞,任何事情都不会发生,服务器端还是显示连续的字符串“Client 89”。自从我们的服务器使用了非阻塞套接字,那么控制台就会显示下面这样的字符串:"Client 89 Client 89 Client 92 Client 89 Client 92 Client 92 Client 89 Client 89 ...",这意味着在套接字通道上的读/写操作并不阻塞服务器应用程序的执行。
这里有一段客户端应用程序的代码:

// Create client SocketChannel
SocketChannel client = SocketChannel.open();
// nonblocking I/O
client.configureBlocking(false);
// Connection to host port 8000
client.connect(new java.net.InetSocketAddress(host,8000));
// Create selector
Selector selector = Selector.open();
// Record to selector (OP_CONNECT type)
SelectionKey clientKey = client.register(selector, SelectionKey.OP_CONNECT);
// Waiting for the connection
while (selector.select(500)> 0{  
    
// Get keys  
    Set keys = selector.selectedKeys();
    Iterator i 
= keys.iterator(); 
    
// For each key 
    while (i.hasNext()) 
          SelectionKey key 
= (SelectionKey)i.next(); 
      
// Remove the current key   
      i.remove();   
      
// Get the socket channel held by the key  
      SocketChannel channel = (SocketChannel)key.channel(); 
      
// Attempt a connection   
      if (key.isConnectable()) {    
          
// Connection OK     
          System.out.println("Server Found");  
          
// Close pendent connections    
          if (channel.isConnectionPending())       
              channel.finishConnect();     
    
// Write continuously on the buffer  
        
    ByteBuffer buffer 
= null;    
    
for (;;) {      
    buffer 
=  ByteBuffer.wrap(  new String(" Client " + id + " ").getBytes());        channel.write(buffer);     
    buffer.clear();    
    }
   
    }
 
    }
}

也许,客户端应用程序的结构让你回忆起服务器端应用程序的结构。然而,这里也有许多不同的地方。套接字通道使用OP_CONNECT选项连接到选择器上,意思是当服务器接受连接时选择器将不得不通知客户端,这个循环不是无穷的。While循环的条件是:
while (selector.select(500)> 0)
意思是客户端尝试连接,最大时长是500毫秒;如果服务器端没有应答,selete方法将返回0,因为在通道上的服务器没有激活。在循环里,服务器端检测关键字是否可连接。在这个例子中,如果有一些不确定的连接,客户端就关闭那些不确定的连接,然后写入字符串“Client”后面接着从命令行参数中带来的变量ID。

分享到:
评论

相关推荐

    Java NIO通信框架在电信领域的实践

    ### Java NIO通信框架在电信领域的实践 #### 华为电信软件技术架构演进 **1.1 电信软件概述** 电信软件是一个宽泛的概念,根据功能和应用场景的不同大致可以分为两大类:系统软件和业务应用软件。系统软件通常...

    Java NIO入门的源码

    在Java NIO中,主要有以下核心概念: 1. **通道(Channels)**:通道类似于流,但它们是双向的,可以读取和写入数据。常见的通道有FileChannel、SocketChannel、ServerSocketChannel等。 2. **缓冲区(Buffer)**:在...

    Java NIO pdf

    它提供了一种高效、面向块的数据处理方式,相较于传统的 Java IO 库,NIO 在数据读写性能上有了显著提升。 #### 二、Java NIO 的关键特性 ##### 1. 面向缓冲区的 I/O 操作 Java NIO 的一个核心特性是面向缓冲区...

    Pro Java 7 NIO.2.pdf

    在第四章中,作者将专注于探索第二种类型的操作。本章中介绍的概念将在书中其他部分非常有用。 ### 2. 介绍 Path 类 路径位于文件系统中,文件系统“在某种形式的介质上存储和组织文件,通常是硬盘,以便可以轻松...

    PRO JAVA 7 NIO2

    《深入理解Java 7 NIO2:Path类的探索与应用》 在Java 7的NIO2(JSR203:Java平台上的更多新I/O API)更新中,`java.nio.file.Path` 类成为了核心组件之一,为开发者提供了更高效、更直观的文件系统操作接口。本文...

    NIO与传统IO代码区别实例

    在Java编程领域,IO(Input/Output)和NIO(Non-blocking Input/Output)是两种不同的I/O模型,它们在处理数据输入和输出时有着显著的差异。本教程旨在帮助NIO初学者理解这两种模型的核心概念及其实际应用,通过具体...

    032002_【第20章:Java新IO】_通道(Channel)_java_hearing3oc_扣弄你澳大_stoppedh

    在Java NIO中,通道和缓冲区(Buffer)是两个核心概念。通道类似于传统IO中的流,但有以下几个显著区别: 1. **双向性**:通道可以进行读写操作,而流通常是单向的(读或写)。 2. **非阻塞**:通道可以设置为非...

    JAVA8 完整源码(包含Sun包源码)

    在 `java.util.function` 包中,你可以看到各种函数接口,如 `Function,R&gt;`、`Predicate&lt;T&gt;` 和 `Consumer&lt;T&gt;`,它们使得代码更加简洁,尤其是在处理集合时。 2. **Stream API**:Java 8 引入了 Stream API,位于 `...

    NIO+Netty5视频教程2018

    这个教程旨在帮助Java开发者深入理解和应用NIO(Non-blocking Input/Output)技术以及Netty网络框架,尤其在构建高效、高性能的网络应用中。 【描述】中的第一部分"深入浅出Netty源码剖析",意味着讲解者会带领学习...

    java面试笔试题库java学习笔记开发教程互联网公司面试资料大全合集.zip

    Java NIO通信框架在电信领域的实践.docx java.png javaconcurrencyinpractice.pdf JavaEE学习笔记.pdf java_Java_学习笔记.pdf Java_Performance.pdf java代码效率优化.docx Java内存模型的历史变迁.docx Java在游戏...

    【项目实战】Netty源码剖析&NIO;+Netty5各种RPC架构实战演练三部曲视频教程(未加密)

    Java NIO(New IO)是Java SE 1.4中的新特性,旨在提高Java在处理大量并发连接时的性能。相比于传统的阻塞I/O,NIO采用了基于缓冲区和通道的非阻塞模式,减少了线程的开销,并提高了系统的吞吐量。NIO主要由Buffer、...

    Java在高并发网络编程中的应用分析.pdf

    随着计算机网络技术的发展,高并发网络编程在信息共享与数据处理中扮演着越来越重要的角色。...随着计算机网络技术的不断进步,Java在这一领域的应用将更加广泛,其在网络编程中的潜力还有待开发者们进一步探索和挖掘。

    【博客 Java调用MATLAB,将文件转换为二进制流】java+matlab程序

    Java的`java.io`和`java.nio`包提供了丰富的工具来处理二进制流。 5. **错误处理与优化**:在实际应用中,需要考虑错误处理,如MATLAB代码执行失败、文件不存在等问题。此外,根据性能需求,可能还需要优化调用...

    java api_javaapi_

    7. **IO流的NIO(非阻塞IO)**:`java.nio`包引入了一种新的IO模型,允许进行非阻塞读写操作,提高了高并发场景下的性能。 8. **日期和时间API**:Java 8引入了`java.time`包,提供了更强大、易用的日期和时间处理...

    驾驭Java文件与IO:深入探索数据流的奥秘

    # 驾驭Java文件与I/O:深入探索数据流的奥秘 Java作为一种广泛应用的编程语言,在多种软件开发场景中扮演着重要角色。本文旨在深入解析Java在处理文件及I/O操作方面的能力,帮助读者更好地理解并掌握相关技术。 ##...

    java实验报告(本人亲手完成的一份JAVA试验报告册)

    Java提供了丰富的多线程支持,实验中可能会创建并运行多个线程,探索同步机制,如synchronized关键字、wait()、notify()和notifyAll()方法,以及Thread类和Runnable接口的区别。此外,线程池的使用也是实验的重点。 ...

    NIO学习笔记

    《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking ...本文仅作为NIO的入门介绍,更多高级特性和实践技巧,还需读者在实践中不断探索和积累。

    java高手真经:网络开发卷源码

    《Java高手真经:网络开发卷源码》是一份专为Java开发者提供的宝贵资源,它聚焦于Java在网络开发领域...源码分析和动手实践是掌握技术的最佳途径,期待你在学习过程中不断探索和进步,成为一名真正的Java网络开发高手。

Global site tag (gtag.js) - Google Analytics