一、通信概述
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模型:货到的时候送货上门,去拿货的路程虽然不长,但由别人替你承担