Java通信各种输入流输出流、java的io与内存及常见的通信方式NIO AIO等介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zanpengfei/article/details/86308943

一、通信概述

1、常用流的介绍:

1)SocketInPutStream:继承于FileInputStream,本身的缓冲区是爱内核中

2)DataInputStream :可以处理流中的不同的数据类型

3)ZipInputStream、GZinputStream、JarInputStream:可以对数据做压缩和解压缩

4)ByteArrayInputStream:通过内存的某些数据得到一个输入流

5)ObjectInputStream:对自定义的对象做输入、输出

6)FileReader、FileWriter:是通过StreamDecoder、StreamEncoder来对字符集进行处理,最终还是通过字节来完成发送和接受

7)BufferedInputStream:可以对输入或输出做Buffer

8)PipedInputStream:对输入流与输出流进行对接时

9)PushbackInputStream:一般流是向前读操作,但该流有回退功能

2、java I/O与内存介绍

1)I/O:输入输出流,是以内存为参考点而言,所有由内存到磁盘或者是文件是输出流,由磁盘到内存是输入流

2)InputStream、OutputStream都是通过字节与终端进行输入输出的

3)切套是为了修饰方法为新的功能,让功能组合起来,让自己所使用流的功能拥有多个流的功能

4)读取一个文件,获取BufferedReader方式:

Files.newBufferedReader(Path.get(“/tmp/xxx.txt”),Charset.forName(“GBK”));

5)文件拷贝实例:文件拷贝一般情况下会开启一个输入流将文件读取到内存,然后开启一个输出流将内存中的数据输出到另一个文件中。在输出数据时会先进入Kenel区域,再拷贝到JVM,输出时先由JVM拷贝到Kenel区域,再输出到终端。

public static void copyFile(String srcFileName,String dstFileName){

   File srcFile = new File(srcFileName);

   File dstFile = new File(dstFileName);

   if(!srcFile){

       throw new RuntimeException(“”);
}

   if(dstFile){

       throw new RuntimeException(“”);
}

   DataInputStream inputStream = null;

   FileOutputStream outputStream = null;

   try{

   inputStream = new DataInputStream(new FileInputStream(srcFile));

   outputStream = new FileOutputStream(“dstFile”);

   int fileAvailable = inputStream.available();

   if(fileAvailable <= COPY_FILE_SIZE){
 
   byte []bytes = new byte[fileAvailable]

   inputStream.readFUlly(bytes);

   outputStream.write(bytes);

}else{

   byte[]bytes = new byte[COPY_FILE_SIZE];

   int len = inputStream.read(bytes);

   while(len > 0){

      outputStream.write(bytes,0,len);

      len = inputStream.read(bytes);
    }

 }

}finally{
  closeStream(inputStream,outputStream); 
  }
}

6)文件copy另一种方式:直接内存映射,省去了中间copy的过程,利用FIleChannel.map()

public static void copyFileByMappedByteBuffer(String srcFileName,String dstFileName){

   FileChannel iniFileChannel = new RandomAxcessFile(srcFileName,”r”).getChannel();

   FIleChannel outFIleChannel = new 
   RandomAccessFIle(dstFileName,”rw”).getChannel();

   try{

       long fileSize = inFileChannel.size();

       long position = 0;

       while(position < fileSize){

          long copyFIleSize = Math.min((fileSize-position),COPY_FILE_SIZE);

          MappedByteBuffer mappedByteBuffer=

           outFileChannel.map(MapMode.READ_QRITE,position,copyFileSize);

          inFileChannel.read(mappedByteBuffer);

          position += mappedByteBuffer.position();

}

}catch(){

}finally{

      closeStream(outFIleChannel);

}

}

7)经过测试第7点比6点要快很多,还有一种方式用DirectByteBuffer方式,拷贝文件小时,比第6点要快点,但是随着文件的变大,2者的差距在逐渐减小

8)Buffer与Cache的区别:

  a)Cache是将一些数据放到就近的地方,最方便拿到。

  b)Buffer通常与I/O有关,它是与I/O交互的一个缓冲区,该缓冲区反复被清空合写入

9)ByteBuffer的某些方法

  a)flip():将limit放在数据有效位置的末尾,以便读取所有的有效数据

  b)clear():放在了总容量最后的位置,以便重新写入数据

10)关于FileChannel加锁区别:

  a)channel.lock():在并发情况下,如果没有获取到锁将阻塞,直到获取到锁

  b)channel.tryLock():若未获取到锁返回null,若获取到返回FileLock对象,关闭锁调用其release方法。

3、通信调用方式

1)Linux OS的IO模型:select、poll、epoll模型

 a)select:由一个数组来管理,有长度限制,每注册一个事件,相当于占用数组一个位置,系统请求时将遍历整个数组查看是否有可处理的事件,若没有则睡眠

b)poll:与select类似,区别是poll用链表来实现,所以没有长度限制

c)epoll:基于事件回调机制,即回调时直接通知进程,通过mmap映射内存来实现

2)使用FileChanel来读取文件:

public class DownloadFileProcessor implements Closeable {

    private final static String FILE_PATH = "/jabaA/upload/Hadoop.PDF";

    private FileChannel fileChannel;

    protected ByteBuffer fileByteBuffer = ByteBuffer.allocate(8192);

   
     public DownloadFileProcessor() throws IOException {

        FileInputStream fileInputStream = null;

        try {

            fileInputStream = new FileInputStream(FILE_PATH);

            fileChannel = fileInputStream.getChannel();

        } catch (Exception e) {


        } finally {

            if (null != fileInputStream) {

                fileInputStream.close();
            }
        }
    }

 
    /*

     * @Description: 读取文件

     * @return int 字节大小

     */

    public int read() throws IOException {

        fileByteBuffer.clear();

        int cout = fileChannel.read(fileByteBuffer);

        fileByteBuffer.flip();

        return cout;

    }

    @Override

    public void close() throws IOException {

        if (null != fileChannel)

            fileChannel.close();

    }

    /*

     * @Description: 获取buffer

     * @return java.nio.ByteBuffer

     */

    public ByteBuffer getFileByteBuffer(){

        return fileByteBuffer;

    } 

}

3)java NIO包括:

a、FileChannel:文件读取的通道,但不支持非阻塞模式

b、SocketChannel:网络通信中TCP的通道

c、ServerSocketChannel:监听网络中新建的TCP连接,通过她调用accept()可创建SocketChannel与客户端正式连接

d、DatagramChannel:从UDP中读取网络包数据

4)Java AIO

a、形象对比BIO、NIO、AIO之间的区别:

i>BIO模型:需要去物流的中转站去等候且不能离开中转站,若货没到,其他事情别想做

ii>NIO模型:每天去检查一下货物是否到了,这个动作很简单,一个小区可以让一个人去看看是否有该小区的货,有就带回来或者是通知你去中转站拿货

iii>AIO模型:货到的时候送货上门,去拿货的路程虽然不长,但由别人替你承担

猜你喜欢

转载自blog.csdn.net/zanpengfei/article/details/86308943