IO和NIO

IO

一、java io 概述

什么是IO

IO包括输入流和输出流,输入流指的是将数据以字符或者字节形式读取到内存 分为字符输入流和字符输入流

输入流指的是从内存读取到外界 ,分为字符输入流和字节输出流

Java IO即Java 输入输出系统。不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO(文件、控制台、网络),我们还要考虑具体和它们的通信方式(顺序、随机、二进制、按字符、按字、按行等等)。Java类库的设计者通过设计大量的类来攻克这些难题,这些类就位于java.io包中。

什么是

Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)

二、Java IO类库的框架

2.1 Java IO的类型

虽然java IO类库庞大,但总体来说其框架还是很清楚的。从是读媒介还是写媒介的维度看,Java IO可以分为:

1. 输入流:InputStream和Reader

2. 输出流:OutputStream和Writer

而从其处理流的类型的维度上看,Java IO又可以分为:

1. 字节流:InputStream和OutputStream

2. 字符流:Reader和Writer

01File

   创建文件   删除文件 修改文件 删除文件信息

02:字节流    InputStream            OutputStream     基类(父类)

03:字符流    Reader                Writer

04:缓冲流    BufferReader           BufferWriter  依赖于 Reader  Writer  

05:二进制流  DataInputStream        DataOutputStream 依赖于InputStream OutputStream

06:序例化    objectInputStream      ObjectOutputStream 依赖于InputStream OutputStream

我们的程序需要通过InputStream或Reader从数据源读取数据,然后用OutputStream或者Writer将数据写入到目标媒介中。其中,InputStream和Reader与数据源相关联,OutputStream和writer与目标媒介相关联。 以下的图说明了这一点:

三、Java IO的基本用法

3.1 Java IO :字节流字节流对应的类应该是InputStreamOutputStream

1,用字节流写文件

 1 package com.dzq;
 2 import java.io.*;
 3 /**
 4  * 字节流    InputStream            OutputStream
 5  */
 6 public class ByteDemo {
 7     public static void main(String[] args) {
 8         //创建输入流和输出流对象
 9         InputStream inputStream=null;
10         OutputStream outputStream=null;
11         try {
12             inputStream=new FileInputStream("e:/aaa.txt");
13             //true代表是否向文件拼接,不能删除之前的内容
14             outputStream=new FileOutputStream("e:/aaa.txt",true);
15            //向文件写入内容
16             outputStream.write("54321".getBytes());
17             //read方法0-255,如果流读到了最后,将返回-1
18             int num=0;//int -1   字符串 null
19             while ((num=inputStream.read())!=-1){
20                 System.out.println((char)num);
21             }
22         } catch (Exception e) {
23             e.printStackTrace();
24         }
25         try {
26             inputStream.close();
27             outputStream.close();
28         } catch (IOException e) {
29             e.printStackTrace();
30         }
31     }
32 }
用字节流写文件

3.2 Java IO :字符流字符流对应的类应该是ReaderWriter

2,用字符流文件

 1 package com.dzq;
 2 import java.io.*;
 3 /*
 4  * 字符流    Reader                Writer
 5  */
 6 public class CharDemo{
 7     public static void main(String[] args) {
 8         //创建字符流输出和输入
 9         Reader reader=null;
10         Writer writer=null;
11         try {
12             reader=new FileReader("e:/aaa.txt");
13             writer=new FileWriter("e:/aaa.txt",true);
14             writer.write("我爱我家!");
15             writer.write("我爱我家?");
16             writer.write("我爱我家!!");
17             writer.write("我爱我家??");
18             writer.flush();
19             writer.write("我爱我家!!!!");
20             writer.close();
21             //读取
22             //创建一次性读取多个字符
23             char[] bytes =new char[1024];
24             int num=0;
25             StringBuffer stringBuffer=new StringBuffer();
26             while((num=reader.read(bytes))!=-1){
27                 stringBuffer.append(bytes);
28             }
29             System.out.println(bytes);
30         } catch (Exception e) {
31             e.printStackTrace();
32         }finally {
33             try {
34                 writer.close();
35                 reader.close();
36             } catch (IOException e) {
37                 e.printStackTrace();
38             }
39         }
40         }
41 }
用字符流写文件

3.3 Java IO  :二进制流( DataInputStream DataOutputStream 依赖于 InputStream    OutputStream

 3,二进制流

 1 package com.dzq;
 2 import java.io.*;
 3 /*
 4  *二进制流  DataInputStream        DataOutputStream
 5  */
 6 public class DataDemo {
 7    public static void main(String[] args) {
 8        //创建输入流和输出流对象
 9         InputStream inputStream=null;
10         OutputStream outputStream=null;
11         DataInputStream dataInputStream=null;
12         DataOutputStream dataOutputStream=null;
13         try {
14             //获取输入流
15             inputStream=new FileInputStream("e:/aaa.txt");
16             dataInputStream=new DataInputStream(inputStream);//封装
17             //获取输出流
18             outputStream=new FileOutputStream("e:/aaa.txt");
19             dataOutputStream=new DataOutputStream(outputStream);
20             //读取
21             int num=0;
22             while ((num=dataInputStream.read())!=-1){
23                 dataOutputStream.write(num);//复制
24             }
25         } catch (Exception e) {
26             e.printStackTrace();
27         }finally {
28             try {
29                 dataOutputStream.close();
30                 dataInputStream.close();
31                 outputStream.close();
32                 inputStream.close();
33             } catch (IOException e) {
34                 e.printStackTrace();
35             }
36         }
37     }
38 }
二进制流

3.4 Java IO(缓冲流BufferReader  BufferWriter 依赖于Reader Writer)

例四:缓冲流

 1 package com.dzq;
 2 import java.io.*;
 3 /**
 4  *缓冲流    BufferReader           BufferWriter
 5  */
 6 public class BufferDemo {
 7     public static void main(String[] args) {
 8         //创建字符流输出和输入
 9         Reader reader = null;
10         Writer writer = null;
11         BufferedReader bufferReader=null;
12         BufferedWriter bufferedWriter=null;
13         try {
14             //写入
15             writer=new FileWriter("e:/aaa.txt") ;
16            bufferedWriter=new BufferedWriter(writer);//封装
17             bufferedWriter.write("我爱我家1");
18             bufferedWriter.write("我爱我家2");
19             bufferedWriter.write("我爱我家3");
20             bufferedWriter.newLine();//换行
21             bufferedWriter.write("我爱我家4");
22             reader.close();
23             bufferedWriter.close();//如果不关闭后两行出不来
24             //读取
25             reader=new FileReader("e:/aaa.txt") ;
26             bufferReader=new BufferedReader(reader);//封装
27             //拼接
28             String line=null;
29             StringBuffer stringBuffer=new StringBuffer();
30             while((line=bufferReader.readLine())!=null){
31                 stringBuffer.append(line);
32             }
33             System.out.println(stringBuffer.toString());
34         } catch (Exception e) {
35             e.printStackTrace();
36         }finally {
37             try {
38                 bufferReader.close();
39                 reader.close();
40             } catch (IOException e) {
41                 e.printStackTrace();
42             }
43         }
44     }
45     }
缓冲流

3.5 Java IO序列化和非序列化

User类:

 1 package com.cd;
 2 import java.io.Serializable;
 3 public class User implements Serializable{
 4     public String username;
 5     public String password;
 6     public String getUsername() {
 7         return username;
 8     }
 9     public void setUsername(String username) {
10         this.username = username;
11     }
12     public String getPassword() {
13         return password;
14     }
15     public void setPassword(String password) {
16         this.password = password;
17     }
18     public User(String username, String password) {
19         this.username = username;
20         this.password = password;
21     }
22     public User(){
23     }
24 }
User

写代码的固定区域:

 1 package com.cd;
 2 /**
 3  * 序列化和非序列化
 4  */
 5 import java.io.*;
 6 import java.util.Scanner;
 7 public  class ObjectDemo {
 8    static Scanner input=new Scanner(System.in);
 9     //创建输出流和输入流
10     static  InputStream inputStream=null;
11     static  OutputStream outputStream=null;
12     static ObjectInputStream objectInputStream=null;
13     static ObjectOutputStream objectOutputStream=null;
14     public static void main(String[] args) {
15            //登录
16           Login();
17           //注册
18           register();
19     }
20     //注册
21     private static void register() {
22         User user =new User();
23         System.out.println("请输入你的用户名");
24         user.setUsername(input.next());
25         System.out.println("请输入你的密码");
26         user.setPassword(input.next());
27         try {
28          outputStream=new FileOutputStream("e:/aaa.txt");
29            objectOutputStream=new ObjectOutputStream(outputStream);
30             //把对象输出到文件中
31             objectOutputStream.writeObject(user);
32         } catch (Exception e) {
33             e.printStackTrace();
34         }finally {
35             try {
36                 objectOutputStream.close();
37                 outputStream.close();
38             } catch (IOException e) {
39                 e.printStackTrace();
40             }
41         }
42     }
43     //登录
44     private static void Login() {
45         try {
46             inputStream=new FileInputStream("e:/user.txt");
47             objectInputStream=new ObjectInputStream(inputStream);
48             //读取对象
49             User user= (User) objectInputStream.readObject();
50             System.out.println(user);
51         } catch (Exception e) {
52             e.printStackTrace();
53         }finally {
54             try {
55                 objectInputStream.close();
56                 inputStream.close();
57             } catch (IOException e) {
58                 e.printStackTrace();
59             }
60         }
61     }
62 }
写代码的固定区域类

3.6 Java IO :字节流转换为字符流InputStreamReader

 1 public static void convertByteToChar() throws IOException{
 2  File file= new File( "d:/test.txt"); 
 3 //获得一个字节流 InputStream is= new FileInputStream( file);
 4  //把字节流转换为字符流,其实就是把字符流和字节流组合的结果。
 5  Reader reader= new InputStreamReader( is);
 6  char [] byteArray= new char[( int) file.length()]; 
 7 int size= reader.read( byteArray); 
 8 System. out.println( "大小:"+size +";内容:" +new String(byteArray));
 9  is.close(); 
10 reader.close();
11  }
字节流换为字符流

四:使用IO写一个实例:

功能简介: 

创建文件

删除文件 

修改文件 

创建文件夹

删除文件夹 

查询文件下所有的列表信息

框架

通用代码环节(首次)

通用代码环节(首次)

通用代码环节(首次)

 1 public class FileDemo
 2 {
 3     static  Scanner input =new Scanner(System.in);
 4     public static void main( String[] args )
 5     {
 6         System.out.println( "***********欢迎进入文件操作系统*******************" );
 7         System.out.println(" *******************1:创建文件*******************" );
 8         System.out.println( "*******************2:删除文件*******************" );
 9         System.out.println( "*******************3:修改文件*******************" );
10         System.out.println( "*******************4:创建文件夹*******************" );
11         System.out.println( "*******************5:删除文件夹*******************" );
12         System.out.println( "*******************6:查询文件夹下所有的列表*******************" );
13         int choose =input.nextInt();
14         switch(choose){
15             case 1://创建文件
16                 createNewFile();
17                 break;
18             case 2://删除文件
19                 deleteNewFile();
20                 break;
21             case 3://修改文件
22                 updateNewFile();
23                 break;
24             case 4://创建文件夹
25                 mkdirs();
26                 break;
27             case 5://删除文件夹
28                 deletemkdirs();
29                 break;
30             case 6://查询文件夹下所有的列表
31                 findFileList();
32                 break;
33         }
34     }
首次

创建文件

 1 private static void createNewFile()
 2 {
 3     System.out.println("请输入文件的名称:(默认为E:/)");
 4     String fileName=input.next();
 5     //创建文件
 6     File file=new File("E:/"+fileName);//默认的路径
 7     if(file.exists()){
 8         System.out.println("该文件已存在!");
 9     }else{
10         try {
11             boolean flag =file.createNewFile();
12             if(flag){
13                 System.out.println("文件夹创建成功");
14             }else{
15                 System.out.println("文件夹创建失败");
16             }
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20     }
21 }
创建文件

删除文件

 1 private static void deleteNewFile()
 2 {
 3     System.out.println("请输入你要删除的文件名称:(默认为E:/)");
 4     String fileName=input.next();
 5     //创建File对象
 6     File file =new File("E:/"+fileName);
 7     if (file.exists()){
 8         boolean flag =file.delete();
 9         if(flag)
10         {
11             System.out.println("删除成功");
12         }else{
13             System.out.println("删除失败");
14         }
15     }else{
16         System.out.println("该文件不存在");
17     }
18 }
删除文件

修改文件

 1 private static void updateNewFile()
 2 {
 3     System.out.println("请你输入需要修改的文件的名称:(默认为E:/)");
 4     String oldFileName=input.next();
 5     System.out.println("请你输入文件的新名称:(默认为E:/)");
 6     String newFileName=input.next();
 7     //创建File对象
 8     File oldFile=new File("E:/"+oldFileName);
 9     File NewFile=new File("E:/"+newFileName);
10     if(oldFile.renameTo(NewFile)){
11         System.out.println("修改成功");
12     }else{
13         System.out.println("修改失败");
14     }
15 }
修改文件

创建文件夹

 1 private static void mkdirs() {
 2     System.out.println("请输入你要创建的文件名称:(默认为E:/)");
 3     String fileName=input.next();
 4     //创建File对象
 5     File file =new File("E:/"+fileName);
 6     if (file.mkdirs()){
 7             System.out.println("创建成功");
 8         }else{
 9             System.out.println("创建失败");
10         }
11 }
创建文件夹

删除文件夹

一:删除文件夹的方法先删除文件夹里面的东西在删除文件

 1 public static void delFolder(String folderPath) {
 2     try {
 3         delAllFile(folderPath); //删除完里面所有内容
 4         String filePath = folderPath;
 5         filePath = filePath.toString();
 6         java.io.File myFilePath = new java.io.File(filePath);
 7         myFilePath.delete(); //删除空文件夹
 8     } catch (Exception e) {
 9         e.printStackTrace();
10     }
11 }
删除文件夹内部

二:删除文件夹的方法

 1 public static boolean delAllFile(String path) {
 2     boolean flag = false;
 3     File file = new File(path);
 4     if (!file.exists()) {
 5         return flag;
 6     }
 7     if (!file.isDirectory()) {
 8         return flag;
 9     }
10     String[] tempList = file.list();
11     File temp = null;
12     for (int i = 0; i < tempList.length; i++) {
13         if (path.endsWith(File.separator)) {
14             temp = new File(path + tempList[i]);
15         } else {
16             temp = new File(path + File.separator + tempList[i]);
17         }
18         if (temp.isFile()) {
19             temp.delete();
20         }
21         if (temp.isDirectory()) {
22             delAllFile(path  + tempList[i]);//先删除文件夹里面的文件
23             delFolder(path  + tempList[i]);//再删除空文件夹
24             flag = true;
25         }
26     }
27     return flag;
28 }
删除文件夹内部和外部

三:删除文件夹的终极方法

 1 private static void deletemkdirs() {
 2     System.out.println("请输入你要删除的文件夹名称:(默认为E:/)");
 3     String fileName=input.next();
 4     //创建File对象
 5     File file =new File("E:/"+fileName);
 6     if (file.exists()){
 7         boolean flag = delAllFile("E:/qqq");
 8         if(flag)
 9         {
10             System.out.println("删除失败");
11         }else{
12             file.delete();
13             System.out.println(" 删除成功");
14         }
15     }else{
16         System.out.println("该文件不存在");
17     }
18 }
删除文件终极方法

NIO

一:java nio 概述

什么是NIO

NIONew IO,这个库是在JDK1.4中才引入的。NIOIO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO

java.nio 的核心的内容有:

BufferChannel(SelectableChannel)Selector

核心内容图示:

注意点:

:
buffer
    缓冲区
   存储的是相同数据类型的数据集!
   本质是一个可以写入数据,并且从中读取数据的内存!
01. position:
      写入或者读取的数据的当前指针
      最大值是: capacity-1
02. limit:
     有多少数据可以写或者可以读
     write模式下,我们的limit和capacity的值一致!
     read模式下,我们的limit和write模 式下的position的值一致!
     position变成了0!
03. capacity:缓冲区的最大容量

1.1 Buffer的本质

一个容器(数组实现)。一个初始化之后,大小就固定了的,底层用数组实现的,存储原始类型的容器(bytecharshortintlongfloatdouble)。每一个原始类型(boolean除外)对应一个子类,但是我们一般使用的都是 ByteBuffer,因为OS网络层最终传输的是字节byte:

也就是说用java.nio编写非阻塞网络程序,在通过 Channel 发送和接受网络字节,一般都是使用 ByteBuffer,作为容器(数组)来暂时存储的。

1.2 Buffer 的核心属性:mark 属性,mark() 函数,reset() 函数,它们是一组的,配合使用

private int mark = -1;

private int position = 0;

private int limit;

private int capacity;

Buffer鉴别buffer limit position的值

在默认的状态:

1 package com.DX;
2 import java.nio.IntBuffer;
3 public class BufferDemo {
4     public static void main(String[] args) {
5         //创建一个容量为10 为int类型的缓冲区
6         IntBuffer  buffer=IntBuffer.allocate(10);       System.out.println("capactity======>>"+buffer.capacity());       System.out.println("position======>>"+buffer.position());        System.out.println("limit======>>"+buffer.limit());
在默认的状态:

在写的状态:

1 buffer.put(13);//转换成写的形式
2 buffer.put(56);
3 buffer.put(1343);
4 buffer.put(13242);
5 System.out.println("capactity======>>"+buffer.capacity());
6 System.out.println("position======>>"+buffer.position());
7 System.out.println("limit======>>"+buffer.limit());
写的状态

1 buffer.flip();//转换成读的形式   System.out.println("capactity======>>"+buffer.capacity());
2 System.out.println("position======>>"+buffer.position());    System.out.println("limit======>>"+buffer.limit());
3     //读取数据
4     while(buffer.hasRemaining()){
5         System.out.println(buffer.get());
6     }
7 }
在读的状态:

IONIO的区别

图示:

文字解释

1、面向流与面向缓冲

     Java IONIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

2、阻塞与非阻塞IO

     Java IO的各种流是阻塞的。这意味着,当一个线程调用read() write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

3、选择器(Selectors

     Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来选择通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

 

原文地址:https://www.cnblogs.com/3020815dzq/p/9261744.html