IO流
一,操作文件 Files
1.创建文件对象
Path path = Paths.get("D:/1.txt")
2.创建文件
Path file = Files.createFile(path),如何磁盘中包含已经存在的,则会抛出异常FileAleradyExistsExcepton
3.删除文件
Files.delete(path)
4.复制文件
Files.copy(source,path)
二,流:是一组有序的数据序列,根据liu流向类型可分为输入流与输出流,根据处理的数据类型可以分为字节流与字符流,I/O流提供了一条通道程序,可以使用这条通道传输数据
节点流:直接从数据源写入数据
包装流(装饰模式):对其他流进行封装,提升性能
字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。
结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
Java IO流对象
1. 输入字节流InputStream
InputStream 是所有的输入字节流的父类,它是一个抽象类。
常用方法:
- abstract int read(); 从输入流中读取单个字节(相当于从图15.5所示的水管中取出一滴水),返回所读取的字节数据(字节数据可直接转换为int类型)。
- int read(byte[] b)从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
- int read(byte[] b,int off,int len); 从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
常见的实现类:
FileInputStream 文件输入流
File file = new File("D:/1.txt");//
只是在内存中创建File文件映射对象,而并不会在硬盘中创建文件
FileInputStream fileInputStream = new FileInputStream(file); }
BufferedInputStream 带缓存的输入流
常用的两个构造方法:BufferedInputStream(InputStream in)创建一个带32字节缓存流
BufferedInputStream(InputStream in,int size)按指定的大小创建缓存区
2.OutputStream输出字节流
ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据
常用方法
- void write(int c); 将指定的字节/字符输出到输出流中,其中c即可以代表字节,也可以代表字符。
- void write(byte[]/char[] buf); 将字节数组/字符数组中的数据输出到指定输出流中。
- void write(byte[]/char[] buf, int off,int len ); 将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到输出流中。
- void flush()刷新当前输出流,并强制写入所有缓冲的字节数据,只对使用缓存的去的OutputStream子类有效,当调用close()方法时,系统关闭流之前,也会将缓存区中的信息刷新到磁盘中
- void close() 关闭当前输出流,并释放所有与当前输出流有关的资源,通知操作系统进行释放,java无权干涉
常见的实现类:
FileOutputStream 文件输出流
常用构造方法:FileOutputStream(String name)与FileIutputStream使用相同的参数的构造方法,创建一个类输出流对象时,可以指定不存在的文件名,但是必须不能是被其他程序打开的文件
FileOutputStream(File file)
BufferedOutputStream 带缓存的输出流
常用的两个构造方法:BufferedOutputStream(InputStream in)创建一个带32字节缓存流
BufferedOutputStream(InputStream in,int size)按指定的大小创建缓存区
3.字符输入流Reader(底层还是对字节进行操作,自动搜寻码表)
编码:字符串—>字节
文件编码:
getBytes()
getBytes(Charset charset)
getBytes(String charsetname)
解码:new string 乱码原因:1.字节数不够 2.字符集不同
常用方法:int read() 读入一个字符,若结尾,返回-1
int read(char[]) 读取一些字符到数组内,并返回所读入的字符的数量,若已到达流结尾,则返回-1
常用实现类:
FileReader
FilerWriter
文件字符流(处理字符文件):
1.创建源 new file(),任何类型的都可以
2.选择流 Reader reader= new FileReader () 操作字符数组
3.操作流 read
4.释放资源
4.DataInputStream与DataOutputStream(装饰流)
public class DataTest { public static void main(String[] args) throws IOException { //写出 ByteArrayOutputStream baos = new ByteArrayOutputStream();//创建字节数组输入流 //创建数据输出流,并将数据写入指定的基础输出流 DataOutputStream dos = new DataOutputStream(baos); //操作数据类型+数据 dos.writeUTF("编码辛酸泪"); dos.writeInt(18); dos.writeBoolean(true); dos.flush();//把数据都刷新到baos中 byte[] datas = baos.toByteArray(); //读取 DataInputStream dis = new DataInputStream(new ByteArrayInputStream(datas)); //顺序与写出一致 String msg = dis.readUTF(); int age = dis.readInt(); boolean flag = dis.readBoolean(); System.out.println(flag); } }
数据走向
//数据——>DataOutputStream-->ByteArrayOutputStream-->ByteArrayInputStream-->DataInputStream
5.管道流
** * 消息发送类 */ class Send implements Runnable{ private PipedOutputStream out = null; public Send(){ out = new PipedOutputStream(); } public PipedOutputStream getOut(){ return this.out; } @Override public void run() { String msg = "hello java"; try { out.write(msg.getBytes()); } catch (IOException e) { e.printStackTrace(); } try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 接受消息类 */ class Recive implements Runnable{ private PipedInputStream input=null; public Recive(){ this.input=new PipedInputStream(); } public PipedInputStream getInput(){ return this.input; } public void run(){ byte[] b=new byte[1000]; int len=0; try{ len=this.input.read(b); }catch (Exception e) { e.printStackTrace(); }try{ input.close(); }catch (Exception e) { e.printStackTrace(); } System.out.println("接受的内容为 "+(new String(b,0,len))); } } /** * 测试类 * */ class hello{ public static void main(String[] args) throws IOException { Send send=new Send(); Recive recive=new Recive(); try{ //管道连接 send.getOut().connect(recive.getInput()); }catch (Exception e) { e.printStackTrace(); } new Thread(send).start(); new Thread(recive).start(); } }