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
01:File
创建文件 删除文件 修改文件 删除文件信息
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 :字节流(字节流对应的类应该是InputStream和OutputStream)
例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 :字符流(字符流对应的类应该是Reader和Writer)
例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 }
写代码的固定区域:
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?
NIO即New IO,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
java.nio 的核心的内容有:
Buffer、Channel(SelectableChannel)、Selector。
核心内容图示:
注意点:
一:
buffer
缓冲区
存储的是相同数据类型的数据集!
本质是一个可以写入数据,并且从中读取数据的内存!
01. position:
写入或者读取的数据的当前指针
最大值是: capacity-1
02. limit:
有多少数据可以写或者可以读
在write模式下,我们的limit和capacity的值一致!
在read模式下,我们的limit和write模 式下的position的值一致!
position变成了0!
03. capacity:缓冲区的最大容量
1.1 Buffer的本质
一个容器(数组实现)。一个初始化之后,大小就固定了的,底层用数组实现的,存储原始类型的容器(byte、char、short、int、long、float、double)。每一个原始类型(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 }
IO和NIO的区别
图示:
文字解释
1、面向流与面向缓冲
Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
2、阻塞与非阻塞IO
Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
3、选择器(Selectors)
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。