Java IO 学习笔记

1. IO_File_API 使用

1.1 路径名称分隔符

  • 名称分隔符 \ separator
package sdu.io;
import java.io.File;
public class PathDemo01 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String Path ="E:\\赵鹏\\eclipse-workspace\\IO_study01\\src\\1.PNG";
		System.out.println(Path);
		// 建议 
		// 1./
		Path="E:/赵鹏/eclipse-workspace/IO_study01/src/1.PNG";
		System.out.println(Path);
		// 2.常量拼接
		Path = "E:"+File.separator+"赵鹏"+File.separator+"eclipse-workspace"+File.separator+"IO_study01"+File.separator+"src"+File.separator+"1.PNG";
		System.out.println(Path);
	}
}

1.2 建立File

  • 三种创建File对象的方法
package sdu.io;
import java.io.File;
public class FileDemo01 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String Path = "E:/赵鹏/eclipse-workspace/IO_study01/src/1.PNG";
		//1.构建File对象
		File src = new File(Path);
		System.out.println(src.length());//图片大小
		//2.构建File对象
		src = new File("E:/赵鹏/eclipse-workspace/IO_study01/src","1.PNG");
		System.out.println(src.length());
		//3.构建File对象
		src = new File(new File("E:/赵鹏/eclipse-workspace/IO_study01/src"),"1.PNG");
		System.out.println(src.length());
	}
}

1.3 相对路径和绝对路径

  • 创建 Flie类
    1)、 有盘符:绝对路径
    2)、无盘符:相对路径 ,相对于当前工程
package sdu.io;
import java.io.File;
public class FileDemo02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//绝对路径
		String Path = "E:/赵鹏/eclipse-workspace/IO_study01/1.PNG";
		File src = new File(Path);
		System.out.println(src.getAbsolutePath());
		
		//相对路径
		src = new File("1.PNG");
		System.out.println(src.getAbsolutePath());//返回绝对路径
		
		//构建不存在的文件 (可以)
		src = new File("aa/1.PNG");
		System.out.println(src.getAbsolutePath());//返回绝对路径

	}
}

1.4 File类的使用

  • 名称或路径
    getName();
    getPath();
    getParent(); 父路径,上路径
    getAbsolutePath()
  • 文件状态
    1)不存在 exists()
    2)存在
    文件:isFile()
    文件夹:isDirectory()
  • 其他信息
    length(); //返回文件的字节数,如果是文件夹或者不存在, 返回0,
    createNewFile() //创建文件,不存在才会创建成功,否则返回空
    delete() //删除已经存在的文件
  • 4.创建目录
    mkdir();//确保上级目录存在,不存在创建失败
    mkdirs();//上级目录可以不存在,不存在一同来创建
  • 5.列出下目录一级
    list();//列出下一级名称
    listFiles();//列出下一级File对象
package sdu.io;
import java.io.File;
import java.io.IOException;
public class FileDemo03 {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		String Path = "E:/赵鹏/eclipse-workspace/IO_study01/1.PNG";
		File src = new File(Path);
		//基本信息:文件名 路径名
		System.out.println("名称:"+src.getName());
		System.out.println("路径:"+src.getPath());//相对 绝对
		System.out.println("绝对路径:"+src.getAbsolutePath());//绝对
		System.out.println("父路径:"+src.getParent());
		
		//文件状态
		System.out.println("是否存在:"+src.exists());
		System.out.println("是否文件:"+src.isFile());
		System.out.println("是否文件夹:"+src.isDirectory());
		
		//文件状态
		src = new File("xxx");
		if(null==src||!src.exists()){
			System.out.println("文件不存在");
		}else if(src.isFile()){
			System.out.println("文件操作");
		}else {
			System.out.println("文件夹操作");
		}
		//创建文件	
		src = new File("E:/赵鹏/eclipse-workspace/IO_study01/1.txt");
		boolean flag = src.createNewFile();
		System.out.println(flag);
		
		//不是创建文件夹
		src = new File("E:/赵鹏/eclipse-workspace/IO_study01/oo");
		flag = src.createNewFile();
		System.out.println(flag);
		
		//删除文件
		flag = src.delete();
		System.out.println(flag);
		
		//创建目录
		File dir = new File("E:/赵鹏/eclipse-workspace/IO_study01/dir/test");
		flag = dir.mkdir();
		System.out.println("mkdir创建文件夹:"+flag);//失败
		flag = dir.mkdirs();//推荐使用
		System.out.println("mkdirs创建文件夹:"+flag);//成功 
		
		dir = new File("E:/赵鹏/eclipse-workspace/IO_study01");
		//列出目录下一级
		String[] subNames = dir.list();
		for(String s:subNames){
			System.out.println(s);
		}
		//列出目录下一级
		File[] subFiles = dir.listFiles();
		for(File f:subFiles){
			System.out.println(f.getAbsolutePath());
		}
		
		//列出所有盘符
		File[] roots = dir.listRoots();
		for(File r:roots){
			System.out.println(r.getAbsolutePath());
		}
		
	}

}

1.5 递归统计子孙级目录和文件名称
递归:自己调用自己
递归头:何时递归结束
递归体:重复调用

package sdu.io;
import java.io.File;
public class DirDemo01 {
	public static void main(String[] args) {
		File src = new File("E:/赵鹏/eclipse-workspace/IO_study01");
		printName(src,0);
	}

	//打印子孙级目录和文件的名称
	public static void printName(File src,int deep) {
		//控制层次
		for(int i=0;i<deep;i++){
			System.out.print("-");
		}		
		System.out.println(src.getName());//打印名称
		if(null==src||!src.exists()) {//递归头
			return;
		}else if(src.isDirectory()){//目录
			for(File s:src.listFiles()){
				printName(s,deep+1);//递归体
			}
		}
	}
}

1.6 递归统计文件夹大小、文件个数和文件夹个数(面向对象)

package sdu.io;
import java.io.File;
public class DirCount {	
	//大小
	private long len;
	//文件夹路径
	private String path;
	//文件的个数
	private int fileSize;
	//文件夹的个数
	private int dirSize;
	//源
	private File src;
	//构造函数
	public DirCount(String path) {
		this.path = path;
		this.src = new File(this.path);
		Count(this.src);
	}
	//方法
	private void Count(File src) {
		//获取大小
		if(src!=null&&src.exists()){//递归头
			if(src.isFile()){
				len+= src.length();//计算文件大小
				this.fileSize++;
			}else {
				this.dirSize++;
				for(File s:src.listFiles()){
					Count(s);//递归体
				}
			}
		}
	}
	public long getLen() {
		return len;
	}
	public int getFileSize() {
		return fileSize;
	}
	public int getDirSize() {
		return dirSize;
	}

	public static void main(String[] args) {
		DirCount dir = new DirCount("E:/赵鹏/eclipse-workspace/IO_study01");
		System.out.println(dir.getLen()+"--->"+dir.getFileSize()+"-->"+dir.getDirSize());
		dir = new DirCount("E:/赵鹏/eclipse-workspace/IO_study01/src");
		System.out.println(dir.getLen()+"--->"+dir.getFileSize()+"-->"+dir.getDirSize());
	}	
}

2. 文件编码

字节===>字符 编码
字符===>字节 解码
2.1 字符集
Java字符集使用16位的双字节存储,但是在实际文件中,存储的数据有各种字符集,需要正确操作,否则就有乱码的现象。

字符集说明
US-ASCII英文的ASCII
ISO-8859Latin-1 拉丁字符,包括中文,日文
UTF-8变长的 Unicode 字符(1-3字节),国际通用
UTF-16BE定长 Unicode 字符(2字节),大端表示(Big-endian)
UTF-16LE定长 Unicode 字符(2字节),小端表示(Little-endian)
UTF-16文件中开头指定大端还是小端方式,即BOM(Byte-Order-Mark):FE FF(表示大端) FF FE(表示小端)

2.2 编解码

  • 编码
    getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
public class ContentDecode {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String msg = "姓名生命使命a";
		//编码:字节数组
		byte[] datas = msg.getBytes();//默认使用工程的字符集
		System.out.println(datas.length);
		
		//编码其他字符集
		datas = msg.getBytes("UTF-16LE");
		System.out.println(datas.length);
		
		datas = msg.getBytes("GBK");//默认使用工程的字符集
		System.out.println(datas.length);
	}
}
  • 解码
    new String():
public class ContentEncode {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String msg = "姓名生命使命a";
		//编码:字节数组
		byte[] datas = msg.getBytes();//默认使用工程的字符集
		System.out.println(datas.length);
		
		//解码:字符串
		msg = new String(datas,0,datas.length,"UTF-8");
		System.out.println(msg);
		
		//乱码
		//1)字节数不够
		msg = new String(datas,0,datas.length-2,"UTF-8");
		System.out.println(msg);
		//2)字符集不统一
		msg = new String(datas,0,datas.length,"GBK");
		System.out.println(msg);		
	}
}

3. IO流

3.1 分类

  • 处理数据:字节流 字符流
    字节流只能处理纯文本,字节流可以处理一切
  • 功能分类:结点流 处理流
  • 流向:输入流 输出流 (以程序为中心)

3.2 四个抽象类

抽象类说明常用方法
InputStream字节输入流的父类,数据单位为字节int read(); void close();
OutputStream字节输出流的父类,数据单位为字节voud write(int); void flush();void close();
Reader字符输入流的父类,数据单位为字符int read();int close();
Writer字符输出流的父类,数据单位为字符voud write(String); void flush();void close();

输入输出流
3.3 IO操作基本步骤

  • 创建源
  • 选择流
  • 操作:读 写
  • 释放
public class IO_test01 {
	public static void main(String[] args) {
		//1.创建源
		File src = new File("abc.txt");
		//2.选择流  字节输入流
		InputStream is = null;
		try {
			is = new FileInputStream(src);
			//3.读操作
			int temp;
			while((temp=is.read())!=-1) { //文件结束符 -1
				System.out.println((char)temp);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=is) {
					is.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

3.4 文件字节流

  • 文件字节输入流 FileInputStream :通过字节的方式读取文件,适合读取所有类型的文件(图像、视频等),全字符文件请考虑FileReadr。
public class IO_test03 {
	public static void main(String[] args) {
		//1.创建源
		File src = new File("abc.txt");
		//2.选择流
		InputStream is = null;
		try {
			is = new FileInputStream(src);
			//3.读操作(分段读取)
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//字节数组->字符串(解码)
				String str = new String(flush,0,len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=is) {
					is.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
  • 文件字节输出流 FileOutputStream :通过字节方式,写出或者追加数据到文件,适合读取所有类型的文件(图像、视频等),全字符文件请考虑FileWriter。
public class IO_test04 {
	public static void main(String[] args) {
		//1.创建源
		File dest = new File("dest.txt");
		//2.选择流
		OutputStream os = null;
		try {
			os = new FileOutputStream(dest,true);//true 追加写入
			//3.写操作
			String msg = "IO is so easy!";
			byte[] datas = msg.getBytes();//字符串->字节数组(编码)
			os.write(datas, 0, datas.length);
			os.flush();//刷新一下,避免数据驻留在内存中
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=os) {
					os.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
  • 文件字节流的应用——文件的拷贝
public class IO_test05_Copy {
	public static void main(String[] args) {
		copy("1.png","2copy.png");
	}
	
	public static void copy(String srcPath,String destPath)
	{
		//1.创建源
		File src = new File(srcPath);//源
		File dest = new File(destPath);//目的地
		//2.选择流
		InputStream is = null;
		OutputStream os = null;
		try {
			is = new FileInputStream(src);
			os = new FileOutputStream(dest);
			//3.读操作
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//写操作
				os.write(flush, 0, len);
			}
			os.flush();//刷新一下
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源 分别关闭 先打开的后关闭
			try {
				if(null!=os) {
					os.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(null!=is) {
					is.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

3.5 文件字符流

public class IO_test06 {
	public static void main(String[] args) {
		//1.创建源
		File src = new File("abc.txt");
		//2.选择流
		Reader reader = null;
		try {
			reader = new FileReader(src);
			//3.读操作(分段读取) char字符类型   byte字节类型
			char[] flush = new char[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=reader.read(flush))!=-1) {
				//字符数组->字符串
				String str = new String(flush,0,len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=reader) {
					reader.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
  • FileWriter:通过字符的方式写出或者追加数据到文件,仅适合字符文件
public class IO_test07 {
	public static void main(String[] args) {
		//1.创建源
		File dest = new File("dest.txt");
		//2.选择流
		Writer writer = null;
		try {
			writer = new FileWriter(dest,true);//true 追加
			//3.写操作
			//写法一
			String msg = "写法一:欢迎来到新世界!\r\n";
			char[] datas = msg.toCharArray();//字符串->字符数组
			writer.write(datas, 0, datas.length);
			writer.flush();//刷新一下
			//写法二
			msg = "写法二:欢迎来到新世界!\r\n";
			writer.write(msg);
			writer.flush();
			//写法三:
			writer.append("写法二").append("欢迎来到新世界!\r\n");
			writer.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=writer) {
					writer.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

3.6 字节数组流
文件字节流和文件字符流,他们的源均是操作系统的中的文件(硬盘),所以需要操作系统释放源,字节数组流的源则是虚拟机中的内存,所以需要垃圾回收机制释放源,不需要关闭。
所有的东西都可以转成字节数组,可以方便数据传输。另外字节数组不要太大,否则太占内存。

  • 字节数组输入流
public class IO_test08 {
	public static void main(String[] args) {
		//1.创建源 字节数组
		byte[] src = "Talk is cheap, show me the code!".getBytes();//字符串->字节数组(编码)
		//2.选择流
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(src);
			//3.读操作(分段读取)
			byte[] flush = new byte[5];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//字节数组->字符串(解码)
				String str = new String(flush,0,len);
				System.out.println(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

  • 字节数组输出流
    将数组写入字节数组的输出流,当数据写入缓冲区时,缓冲区会自动增长。可以使用toByteArray()和toString()检索数据。
    关闭ByteArrayOutputStream没有任何效果。 在关闭流之后,可以调用此类中的方法,而不生成IOException 。
    总之
    1.创建源:内部维护
    2.选择流:不关联源
    3.操作:没有变化
    4.释放资源:可以不用
    需要获取数据,使用toByteArray()方法
public class IO_test09 {
	public static void main(String[] args) {
		//1.创建源(实际没有源)
		byte[] dest = null;
		//2.选择流(使用新增方法,所以一定要使用ByteArrayOutputStream)
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();// 没有源,没有参数
			//3.写操作
			String msg = "IO is so easy!";
			byte[] datas = msg.getBytes();//字符串->字节数组(编码)
			baos.write(datas, 0, datas.length);
			baos.flush();//刷新一下
			// 获取数据
				dest = baos.toByteArray();//新增方法
				System.out.println(dest.length+"-->"+new String(dest,0,baos.size()));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源 (实际不用释放,gc释放)
			try {
				if(null!=baos) {
					baos.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

3.7 综合 _对接流

  • 1.图片读到字节数组
    1)图片到程序
    2)程序到字节数组
  • 2.字节数组写到文件
    1)字节数组写入到程序
    2)程序写出到文件
    注:某某东西转成字节数组,除了字符串,都需要流来对接
public class IO_test10 {
	public static void main(String[] args) {
		byte[] data = fileToByteArray("1.png");
		System.out.println(data.length);
		byteArrayToFile(data,"1file.png");
	}	
	//文件->程序->字节数组
	public static byte[] fileToByteArray(String srcPath) {
		//1.创建源 和 目的地
		File src = new File(srcPath);
		byte[] dest = null;
		//2.选择流
		InputStream is = null;
		ByteArrayOutputStream baos = null;
		try {
			is = new FileInputStream(src);
			baos = new ByteArrayOutputStream();// 没有源,没有参数
			//3.读操作
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				baos.write(flush, 0, len);		
			}
			baos.flush();//刷新一下
			return baos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=is) {
					is.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}
		return null;
	}	
	//字节数组-->程序-->文件
	public static void byteArrayToFile(byte[] src,String destPath) {
		//1.创建源 字节数组
		File dest = new File(destPath);
		//2.选择流
		InputStream is = null;
		OutputStream os = null;
		try {
			is = new ByteArrayInputStream(src);
			os = new FileOutputStream(dest);
			//3.操作
			//读操作
			byte[] flush = new byte[1024];//程序缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//写操作
				os.write(flush, 0, len);		
			}
			os.flush();//刷新一下
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.释放资源
			try {
				if(null!=os) {
					os.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}	
	}
}

3.8 IO工具类

  • 1.封装拷贝
  • 2.封装释放
public class IO_test11_FileUtils {
	public static void main(String[] args) {
		//文件到文件
		try {
			InputStream is = new FileInputStream("abc.txt");
			OutputStream os = new FileOutputStream("abc_copy.txt");
			copy(is,os);
		} catch (IOException e) {
			e.printStackTrace();
		}
		//文件到字节数组
		byte[] data = null;
		try {
			InputStream is = new FileInputStream("1.png");
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			copy(is,os);
			data = os.toByteArray();
		} catch (IOException e) {			
			e.printStackTrace();
		}
		//字节数组文件
		try {
			InputStream os = new ByteArrayInputStream(data);
			OutputStream is = new FileOutputStream("1copy.png");			
			copy(os,is);
		} catch (IOException e) {			
			e.printStackTrace();
		}
		
		
	}
	//对接输入输出流
	public static void copy(InputStream is, OutputStream os)
	{
		try {
			//3.读操作
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//写操作
				os.write(flush, 0, len);
			}
			os.flush();//刷新一下
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源 分别关闭 先打开的后关闭
			//close1(is,os);
			close(is,os);
		}
	}
	
	//释放资源 封装1 :关闭输入输出流
	public static void close1(InputStream is,OutputStream os) {
		try {
			if(null!=os) {
				os.close();
			}				
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			if(null!=is) {
				is.close();
			}				
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//释放资源 封装2:关闭所有的流
	public static void close(Closeable... ios) {		
		for(Closeable io:ios) {
			try {
				if(null!=io) {
					io.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	//try...with..resource
	public static void copy2(InputStream is, OutputStream os)
	{
		try(is;os) {
			//3.读操作
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//写操作
				os.write(flush, 0, len);
			}
			os.flush();//刷新一下
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
}

3.9 IO 装饰器

  • 1.装饰器4大组成部分
    1) 抽象组件:需要装饰的抽象对象(接口或者抽象父类)
    2) 具体组件:需要装饰的对象
    3) 抽象装饰类:包含了对抽象组件的引用以及装饰着共有的方法
    4) 具体装饰类:被装饰的对象
public class Decorate_test02 {
	public static void main(String[] args) {
		Drink coffee = new Coffee();//具体对象
		System.out.println(coffee.info()+"-->"+coffee.cost());
		Drink milk = new Milk(coffee);//装饰对象
		System.out.println(milk.info()+"-->"+milk.cost());
		Drink suger = new Suger(milk);//装饰对象
		System.out.println(suger.info()+"-->"+suger.cost());
	}
}
//抽象组件
interface Drink{
	double cost();//费用
	String info();//说明	
}
//具体组件
class Coffee implements Drink{
	private String name = "原味咖啡";	
	@Override
	public double cost() {		
		return 10;
	}
	@Override
	public String info() {		
		return name;
	}	
}
//抽象装饰类
class Decorate implements Drink{
	//对抽象组件的引用
	private Drink drink;
	public Decorate(Drink drink) {
		this.drink = drink;
	}
	@Override
	public double cost() {		
		return this.drink.cost();
	}
	@Override
	public String info() {		
		return this.drink.info();
	}
}

//具体装饰类
class Milk extends Decorate{
	public Milk(Drink drink) {
		super(drink);
	}
	@Override
	public double cost() {		
		return super.cost()*4;
	}
	@Override
	public String info() {		
		return super.info()+"加入了牛奶 ";
	}
}
class Suger extends Decorate{
	public Suger(Drink drink) {
		super(drink);
	}
	@Override
	public double cost() {		
		return super.cost()*2;
	}
	@Override
	public String info() {
		return super.info()+"加入了蔗糖 ";
	}
}
  • 2.字节缓冲流(装饰流)
    1) 提升性能,建议都加上缓冲流
    2) 最底层为节点流(FileInputStream FileOutputStream)
    3) 只需释放最外层的结点流
    字节输入缓冲流:A BufferedInputStream为另一个输入流添加了功能,即缓冲输入并支持mark和reset方法的功能。 创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。 mark操作会记住输入流中的一个点,并且reset操作会导致从最近的mark操作读取的所有字节在从包含的输入流中取出新字节之前重新读取。
public class BufferedTest01 {
	public static void main(String[] args) {
		//1.创建
		File src = new File("abc.txt");
		//2.选择
		InputStream is = null;
		
		try {
			is = new BufferedInputStream(new FileInputStream(src));//直接套上BufferedInputStream
			//3.读操作
			byte[] flush = new byte[1024];//缓冲容器
			int len=-1;//读取的字节的长度
			while((len=is.read(flush))!=-1) {
				//字节数组->字符串
				String str = new String(flush,0,len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=is) {
					is.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

字节输出缓存流:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。

public class BufferedTest02 {
	public static void main(String[] args) {
		//1.创建源
		File dest = new File("dest.txt");
		//2.选择流
		OutputStream os = null;
		try {
			os = new BufferedOutputStream(new FileOutputStream(dest));//直接套上,so easy!
			//3.写操
			String msg = "IO is so easy!";
			byte[] datas = msg.getBytes();//字符编码
			os.write(datas, 0, datas.length);
			os.flush();//刷新
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源
			try {
				if(null!=os) {
					os.close();
				}				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

  • 3.字符缓存流(装饰流)

字符缓存输入流和字符缓存输出流,实现文本文件的拷贝

public class BufferedTest05_Copy {
	public static void main(String[] args) {
		copy("dest.txt","destcopy.txt");
	}
	
	public static void copy(String srcPath,String destPath)
	{
		//1.创建源
		File src = new File(srcPath);//源
		File dest = new File(destPath);//目的地
		//2.选择流
		try(BufferedReader br = new BufferedReader( new FileReader(src));
			BufferedWriter bw = new BufferedWriter( new FileWriter(dest));) {
			//3.读操作
			String line = null;
			while((line = br.readLine())!=null) {
				//写操作
				bw.write(line);
				bw.newLine();
			}
			bw.flush();//刷新一下
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
}

3.转换流

  • 功能:
    将字节流转换为字符流
    处理过程中可以指定字符集
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值