I/O框架

什么是流?

  • 概念:内存与存储设备之间的传输数据的通道。
  • 水借助管道传输;数据借助流传递
    例如:内存中的数据一旦保存后便会存入电脑的某个盘中

流的分类:
按方向:

  • 输入流:将存储设备中的内容读入到内存中
  • 输出流:将内存中的内容写入到存储设备中
    如:将内存中的内容作为中心,输出到存储设备中则为输出流。

按单位:

  • 字节流:以字节为单位,可以读写所有数据
  • 字符流: 以字符为单位,只能读写文本数据
    如:将程序中的字节输出到存储设备中,字节输出流。

按功能:

  • 节点流:具有实际传输数据的读写功能。
  • 过滤流:在字节流的基础之上增强功能。
    如:在字节输出流在表述,具体的传输为节点流,则称为字节输出节点流。

字节流

  • 字节流的父类(抽象类):

     InputStream:字节输入流
     	public int read(){}
     	public int read(byte[] b){}
     	public int read(byte[] b ,int off,int len){}
     OutputStream:字节输出流
     	public int write(){}
     	public int write(byte[] b){}
     	public int write(byte[] b ,int off,int len){}
    

字节节点流

  • FileOutputStream:
    public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流。
  • FileInputStream:
    public int read(byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestFileOutPutStream {
	public static void main(String[] args) throws IOException {
		//1.输出字节流 OutputStream
		//2.输出字节节点流,具有实际传输数据的功能(文件路径.boolean append)
	//FileOutputStream fos = new FileOutputStream("F:\\java_files\\day31\\target.txt",false);//默认为false重复运行不追加
		//此时路径为绝对路径
		//路径正确:当文件不存在时,则会自动新建一个文件
		//路径错误时,没有盘符
		//相对路径: 与上一种形式等价,但此方式为相对于当前项目下寻找路径和文件。
		FileOutputStream fos = new FileOutputStream("target.txt",false);
//		fos.write(65);//输出单个字节
//		fos.write(66);
//		fos.write('D');
		byte[] bytes = new byte[] {65,66,67,68,'D'};
//		fos.write(bytes);//一次输入一组字节   //ABCDD
		
		fos.write(bytes,1,3);//字节数组 起始下标  长度 //BCD
		//fos.write('你');//占两个字节,无法直接输出
		String s = "你";
		byte[] bs = s.getBytes();
		System.out.println(bs[0]+"\t"+bs[1]);
		fos.write(bs);	
	}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestFileIO {
	public static void main(String[] args) throws IOException {
		//将指定图片,上传一份到项目里面来
		
		//文件在存储设备中,读到程序中,再从程序中写到存储设备
		//输入流
		FileInputStream fis = new FileInputStream("D:\\1.png");
		
		//输出流
		FileOutputStream fos = new FileOutputStream("2.png");
		//byte[] cache = new byte[1024*1024];
		//缓冲空间过大过小都不合适
		int len = 0;//代表每次读到的字节
		while((len = fis.read())!=-1) {
			fos.write(len);//读多少写多少
		}
		
		//fis.read(cache);

		//释放资源;
		fis.close();
		fos.close();
		
	}
}

字节过滤流

  • 缓冲流:BufferedOutputStream/BufferedInputStream
    提高IO效率,减少访问磁盘的次数;
    数据存储在缓冲区中。flush是将缓存区的内容写入文件中,也可以直接close。
  • 对象流:ObjectOutputStream/ObjectInputStream
    增强了缓冲区功能
    增强了读写8种基本数据类型和字符串功能
    增强了读写对象的功能:readObject()、writeObject(Object obj)
    使用流传输对象的过程称为序列化、反序列化
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestBufferedOutput {
	public static void main(String[] args) throws IOException {
		//有参构造需要一个字节输出节点流
		//先创建字节输出字节流
		FileOutputStream fos = new FileOutputStream("buffer.txt");
		//增强字节流
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		//过滤流的write方法,实现写入到缓冲区数组。
		bos.write('A');
		bos.write('B');
		bos.write('C');
		bos.write('D');
		bos.flush();//刷新缓冲区(将缓冲区的数据一次性写入到文件中,并清空当前缓冲区)
		
		bos.write('E');
		bos.write('F');
		//bos.flush();
		bos.close();//级联的执行了flush方法,释放资源的同时将数据一次性写入到文件里。
		
		
		FileInputStream fis = new FileInputStream("buffer.txt");
		BufferedInputStream bis = new BufferedInputStream(fis);
		byte[] bytes = new byte[100];
		//bis.read(bytes);
		fis.read(bytes);
		
		for(int i = 0 ;i<bytes.length;i++) {
			System.out.println((char)bytes[i]);
		}
	}
}

对象序列化

  • 对象序列化的细节:
    必须实现Serializable接口
    必须保持其所有属性均可序列化
    transient修饰为临时属性,不参与序列化
    读取到文件尾部的标志:java.io.EOFException
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
//static依旧属于类的,会影响序列化
//非包装类数据也可以写

public class TestObjectStream {
	public static void main(String[] args) throws IOException, ClassNotFoundException{
		OutputStream os = new FileOutputStream("obj.txt");
		ObjectOutputStream oos = new ObjectOutputStream(os);
		
		Student stu = new Student("kunyan",12,"female",110D,new Address("wuhan","10000"));
		Student stu1 = new Student("haha",13,"male",100D,new Address("wuhan","10000"));
		oos.writeObject(stu);
		oos.writeObject(stu1);
		
		oos.writeInt(30);
		
		
		InputStream is = new FileInputStream("obj.txt");
		ObjectInputStream ois = new ObjectInputStream(is);
		//int result = ois.readInt();
		//System.out.println(result);
		
//		Object obj = ois.readObject();
		//Student s = (Student)obj;
//		System.out.println(obj);
		//System.out.println(s.name);
		
		while(true) {
			try {
				Object obj = ois.readObject();
				System.out.println(obj.toString());
			}catch(Exception e){
				break;//到达文件末尾哦。获得EOFException,就停止循环---
			}
		
		}
		
		oos.flush();
	}
}
//对象自身要支持序列化
//属性也要支持序列化
//transient修饰为临时属性,不参与序列化
class Student implements Serializable{
	String name;
	Integer age;
	String sex;
	Double score;
	transient Address add;
	public Student(String name, Integer age, String sex, Double score,Address add) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.score = score;
		this.add = add;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score + ", add=" + add + "]";
	}

}
class Address implements Serializable{
	String postion;
	String zipCode;
	
	public Address(String postion, String zipCode) {
		super();
		this.postion = postion;
		this.zipCode = zipCode;
	}

	@Override
	public String toString() {
		return "Address [postion=" + postion + ", zipCode=" + zipCode + "]";
	}
}

File类

  • 概念:代表物理盘符中的一个文件或者文件夹
  • 方法:
    createNewFile()//创建一个新文件
    Mkdir()//创建一个新目录
    Detele()//删除文件或空目录
    Exists()//判断File对象所代表的对象是否存在
    getAbsolutePath()//获取文件的绝对路径
    getName()//取得名字
    getParent()//获取文件/目录所在的目录
    isDirectory()//是否是目录
    isFile()//是否是文件
    length()//获取文件的长度
    listFiles()//列出目录中的所有内容
    renameTo()//修改文件名为
import java.io.File;
import java.io.IOException;

public class TestFiles {
	public static void main(String[] args) throws Exception {
		File file = new File("F:\\test\\testfiles.txt");
		
//		System.out.println(file.canExecute());//文件是否存在
//		System.out.println(file.canWrite());//能不能修改文件
//		System.out.println(file.canRead());//能不能执行文件
		
//		System.out.println(file.createNewFile());//文件已存在则返回false,文件不存在则true并新建
//		System.out.println(file.delete());
//		Thread.sleep(3000);
//		file.deleteOnExit();//jvm终止时,则执行删除文件
//		System.out.println(file.exists());
//		System.out.println(file.getAbsolutePath());//绝对路径
//		System.out.println(file.getPath());//相对路径
//		System.out.println(file.getName());//名字加后缀
//		System.out.println(file.getFreeSpace()/1024/1024/1024);//获取硬盘的空闲空间
//		System.out.println(file.getTotalSpace()/1024/1024/1024);//总空间
//		System.out.println(file.getParent());//指定文件的父级目录
		
//		System.out.println(file.isDirectory());//判断是否为文件夹
//		System.out.println(file.isFile());//判断是否是文件
//		System.out.println(file.isHidden());//判断是否隐藏
		
//		System.out.println((System.currentTimeMillis()-file.lastModified())/1000/60);//获取文件最后一次获取时间
//		System.out.println(file.length());//文件内容的字节
		
//		System.out.println(file.mkdirs());
		System.out.println(file.createNewFile());
	}
}
import java.io.File;

public class TestFileList {
	public static void main(String[] args) {
		File file = new File("F:\\java_files");
		
//		String[] fileName = file.list();//获取文件夹中的所有文件(包含文件夹)的名字 String类型
//		for(String fname:fileName) {
//			System.out.println(fname);
//		}
		
		File[] files = file.listFiles();
		for(File f:files) {
			if(f.isFile()) {
				if(f.getName().endsWith(".docx")) {
					System.out.println(f.getName());
				}
			}
		}
	}
}

FileFilter接口

  • public interface FileFilter
    boolean accept(File pathname)

  • 当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。

import java.io.File;
import java.io.FileFilter;
import java.io.ObjectOutputStream;

public class TestFileList {
	public static void main(String[] args) {
		File file = new File("F:\\java_files");
		
//		String[] fileName = file.list();//获取文件夹中的所有文件(包含文件夹)的名字 String类型
//		for(String fname:fileName) {
//			System.out.println(fname);
//		}
		
		File[] files = file.listFiles(new MyFilter());
		for(File f:files) {
//			if(f.isFile()) {
//				if(f.getName().endsWith(".docx")) {
					System.out.println(f.getName());
//				}
//			}
		}
		
	}
}
class MyFilter implements FileFilter{
	@Override
	public boolean accept(File pathname) {
		if(pathname.isFile()) {
			if(pathname.getName().endsWith(".docx")) {
				return true;
			}
		}
		return false;
	}
	
}
import java.io.File;
import java.io.FileFilter;

public class TestShowAllFiles {
	static int count = 0;
	public static void main(String[] args) {
		//1.遍历F盘下,所有是.class为结尾的文件
		File file = new File("F:\\");
		showall(file);
		System.out.println("一共"+count+"个文件");
	}
	public static void showall(File dir) {
		File[] file = dir.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				if(pathname.isDirectory()) {//文件夹保存
					return true;
				}
				if(pathname.isFile()) {//符合要求的文件
					if(pathname.getName().endsWith(".class")) {
						return true;
					}
				}
				return false;
			}		
		});
		if(file!=null) {
			for(File f:file) {
				if(f.isFile()) {
					count++;
					System.out.println(f.getName());
				}else {
					showall(f);
				}
			}
		}
	}	
}

字符编码

  • ISO-8859-1 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语 希伯来语对应的文字符号
  • UTF-8 针对Unicode的可变长度字符编码
  • GB2312 简体中文
  • GBK 简体中文、扩充
  • BIG5 台湾,繁体中文
    当编码方式和解码方式不一致时,会出现乱码
import java.io.UnsupportedEncodingException;

public class TestEncoding {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "你好世界123abc陶喆";//文本内容
		//byte[] bs = str.getBytes();//获得字符的二进制表现形式
		byte[] bs = str.getBytes("GBK");
		for(int i = 0 ; i<bs.length;i++) {
			System.out.println(bs[i]);
		}
		//解码二进制
		String str2 = new String(bs,"BIG5");
		System.out.println(str2);
		
		byte[] bs2 = str2.getBytes("BIG5");
	
		String str3 = new String(bs2,"GBK");
		System.out.println(str3);
	}
}

字符流

  • 字符流的父类(抽象类):

Reader:字符输入流

	public int read(){}
	public int read(char[] c){}
	public int read(char[] b ,int off,int len){}

Writer:字符输出流:

	public int write(int n){}
	public int write(String str){}
	public int write(char[] c){}

字符节点流

  • FileWriter:
    public void write(String str)//一次写多个字符,将b数组中所有字符,写入输出流。
  • FileReader:
    public int read(char[] c)//从流中读取多个字符,将读到内容存入到c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1.
import java.io.FileReader;
import java.io.FileWriter;
//但记事本中没有换行
public class TestWriter {
	public static void main(String[] args) throws Exception {
		FileWriter fw = new FileWriter("chars.txt");
		char[] chars = new char[] {'举','头','望','明','月'};
		
		fw.write("床前明月光");
		fw.write("疑是地上霜");
		fw.write(chars);
		fw.flush();
		
		FileReader fr = new  FileReader("chars.txt");
		char[] cache = new char[5];
		while(true) {
			int n = fr.read(cache);
			if(n==-1) {
				break;
			}
			for(int i = 0;i<n;i++) {
				System.out.print(cache[i]);
			}
			System.out.println();
		}
	}
}

字符过滤流

  • 缓冲流:BufferedWrite/BufferedReader
    支持输入换行符
    可一次写一行、读一行

  • PrintWriter:
    封装了print()/println()方法,支持写入后换行。

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class TestBuffer {
	public static void main(String[] args) throws Exception {
		FileWriter fw = new FileWriter("buf.txt");
		BufferedWriter bw =  new BufferedWriter(fw);
		bw.write("床前明月光");
		bw.newLine();//根据平台提供换行符
		bw.write("疑是地上霜");
		bw.flush();
	}
}
//过滤流比BufferedWriter更为方便,提供println打印后换行的方法
//字符流读到末尾返回null
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;

public class TestPrinter {
	public static void main(String[] args) throws Exception {
		FileWriter fw = new FileWriter("prints.txt");
		PrintWriter pw = new PrintWriter(fw);
		pw.println("床前明月光");
		pw.println("疑似地上霜");
		pw.println("举头望明月");
		pw.println("低头思故乡");
		pw.flush();
		
		FileReader fr = new FileReader("prints.txt");
		BufferedReader br = new BufferedReader(fr);
		while(true) {
			String str = br.readLine();
			if(str == null) {
				break;
			}
			System.out.println(str);
		}
	}
}

字符节点流

  • 桥转换流:InputStreamReader/OutputStreamWriter
    可将字节流转换为字符流
    可设置字符的编码方式
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class TestConvertStream {
	public static void main(String[] args) throws Exception {
		//OutputStream os = new FileOutputStream("convert.txt");//字节输出流
		//编码
		//OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");//指定输出的数据编码格式
		
		//PrintWriter pw = new PrintWriter(osw);
		PrintWriter pw = new  PrintWriter(new OutputStreamWriter(new FileOutputStream("convert.txt"),"UTF-8") );
		pw.println("床前明月光");
		pw.println("疑似地上霜");
		pw.println("举头望明月");
		pw.println("低头思故乡");
		pw.flush();
		
		
		InputStream is = new FileInputStream("convert.txt");
		//解码
		InputStreamReader isr = new InputStreamReader(is,"UTF-8");
		BufferedReader br = new BufferedReader(isr);
		while(true) {
			String str = br.readLine();
			if(str == null) {
				break;
			}
			System.out.println(str);
		}
//		char[] chars = new char[5];
//		isr.read(chars);
//		for(int i = 0 ;i<chars.length;i++) {
//			System.out.print(chars);
//		}
//		System.out.println();	
	}
}

使用步骤

  • 创建节点流
  • [创建过滤流 设置字符编码集]
  • 封装过滤流
  • 读写数据
  • 关闭流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值