IO流

IO流

三大分类
1. 流向:输入流,输出流
2. 单位:字节流(适用范围广),字符流(只适用于读取文字,效率高,范围窄)
3. 功能:节点流(直接接触数据源的流),处理流(过滤流)(连接其他流的流,提高效率,使操作更加灵活)

// 创建文件
  File  file = new File("C:\\Users\\huangjinjin\\Desktop\\a");

file 只是表示路径,文件不一定存在

//exists 判断文件是否真的存在
	if(!file.exists()){
    	// 不存在则想要创建一个文件
        boolean b = file.createNewFile();
        System.out.println(b);
    }
// 创建文件夹
	file3.mkdirs();// mkdirs 创建多级目录

file的一些方法

	System.out.println("得到文件的名字"+file.getName());
	System.out.println("相对路径:"+file.getPath());
	System.out.println("绝对路径:"+file.getAbsolutePath());
	System.out.println("得到父级目录String"+file.getParent());
	System.out.println("得到父级目录File"+file.getParentFile());

	System.out.println("文件是否可读"+file.canRead());
	System.out.println("文件是否可写"+file.canWrite());
	System.out.println("文件是否是隐藏文件"+file.isHidden());
	
	System.out.println("判断是否是文件夹"+file.isDirectory());
	System.out.println("判断是否是文件"+file.isFile());
// 此方法不能对文件夹起作用
	System.out.println("文件内容长度"+file.length());
//文件名字重命名
	File file2 = new File("b.txt");
	boolean b2 = file.renameTo(file2);
	System.out.println(b2);
// 删除操作和重命名操作  操作的文件如果被使用着则操作失败
	file2.delete();

递归:隐式循环

递归: 自己方法调用自己 形成了隐式循环
思想: 将复杂的问题简单化, 直到简单到直接可以得到结果为止
递归比较耗费内存, 所以适当使用,在特定的场景使用

递归存在的风险:
可能会出现StackOverflowError 栈内存溢出
设置出口 合理的控制 则不会出现StackOverflowError

// 方法执行是在栈中执行
    static int num = 0;
    public static void a(){
        System.out.println(" this is a a()");
        num++;
        if(num==5){
            return;
        }
        a();// 自己调用自己

举例

递归: 遍历整个文件夹中所有的文件

 	public static void findAllFile(File file){
		if(file!=null){
			//判断是不是文件夹
			if(file.isDirectory()){
				// 查找文件夹下一层级所有内容
				File[] files = file.listFiles();
				for (File file2 : files) {
					findAllFile(file2);// 调用findAllFile 帮判断是文件还是文件夹
				}
			}else{
				System.out.println("是文件:"+file);
			}
		}else {
			System.out.println("没有办法找");
		}
	}

用递归求斐波那契数列

//  1 1 2 3 5 8 13  21  34 
// 第三个等于前两个相加、第四个等于前两个相加,以此类推
	public static void main(String[] args) {
		int num = rabbit(10);
		System.out.println(num);
	}
	public static int rabbit(int month){
		if(month==1 || month==2){
			return 1;
		}
		return rabbit(month-1)+rabbit(month-2);
	}

文件过滤器

	public static void main(String[] args) {
		File file = new File("C:\\Users\\huangjinjin\\Desktop\\StudentCourses");
		String[] list = file.list(new MyFileNameFilter());
		for (String string : list) {
			System.out.println(string);
		}
	}
}
// 过滤器
	class MyFileNameFilter implements FilenameFilter{
	@Override
	public boolean accept(File dir, String name) {
	//System.out.println("====dir===="+dir);//file 对象路径
	//System.out.println("====name===="+name);// 文件夹下面的所有文件的名字
		
	// 只保留 文件, 过滤掉文件夹
	// new File(parent, child)  父路径与子路径连接
	// C:\Users\huangjinjin\Desktop\StudentCourses\.idea   
		File file = new File(dir,name);
		if(file.isDirectory()){
			return true;
		}
	//保留后缀名为txt的
		if(name.endsWith(".txt")){
			return true;
		}
		return false;// return false 被过滤掉
					//         true 保留 不被过滤掉
		}	
	}

文件流

文件字节流 InputStream/OutputStream

创建对象

// 创建文件字节输入流
	File file = new File("a.txt");
	
	// 创建对象  两种方法
	FileInputStream fis = new FileInputStream(file);
	FileInputStream fis = new FileInputStream("a.txt");

FileInputStream的一些方法

// 跳过两个字节
	fis2.skip(2);
// 剩余可用字节个数
	int num = fis2.available();
	System.out.println("可用字节个数"+num);
	
// read方法的作用, 读取字节,并且指针向后移动
// 第一种
	int i = fis2.read();
	System.out.println(i);
	int i2 = fis2.read();
	System.out.println(i2);
	
	byte[] bs = new byte[4];
	// read的方法的返回值代表的是本次读取有效元素的个数
	int num2 = fis2.read(bs);
	// 将数据读取到数组中
	System.out.println(Arrays.toString(bs));
	System.out.println(num2); //2 
	
// 第二种最常用	
//当读取到文件结尾以后,再次读取读取到的是-1 , -1是文件结尾的标志
	int num3 = fis2.read(bs);
	System.out.println(num3);
	System.out.println(Arrays.toString(bs));
	
	String str = new String(bs, 0, num3);
	System.out.println(str);
	
// 第三种
	byte[] bs2 = new byte[4];
	//off偏移量 偏移的数组的下标,读取的位置不会有变化      len 长度
	// fis2.read(b, off, len)
	int num4 = fis2.read(bs2, 2, 2);
	//  offset+len<=数组.lenth
	System.out.println(Arrays.toString(bs2));
	System.out.println(num4);

FileInputStream

	FileInputStream fis =null;
	try {
		fis = new FileInputStream("a.txt");
		byte[] bs = new byte[10];
		int len = 0;
		
		while((len = fis.read(bs))!=-1){
			String str = new String(bs,0,len);
			System.out.println(str);
		}
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	// 关流
	}finally {
		if(fis!=null){
			try {
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

FileOutputStream

	FileOutputStream fos = null;
	try {
		// 输出流 连接的文件不存在的情况下可以自动创建
		//fos = new FileOutputStream("b.txt");
		// 以追加方式写入内容   true表示每次执行都会在原来的基础上进行
		fos  = new FileOutputStream("b.txt", true);
// write方法
	// 第一种
		// 一次只能写一个
		fos.write(99);
		fos.write(100);
	// 第二种
		// 一次会写一个数组的数据
		byte[] bs = {97,98,99,100};
		fos.write(bs);
	// 第三种	写的时候 第三个比较常用
		// 写入数组中指定位置的部分进入文件
		// fos.write(b, off, len);
		fos.write(bs, 1, 2);
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally { // 关流
		if(fos!=null){
			try {
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

举例:字节流InputStream文件复制

	public static void main(String[] args) {
		//1.源文件
		File src=new File("a.txt");
		//2.目标文件
		File dest= new File("c.txt");
		//3.创建输入输出流对象
		FileInputStream fis =null;
		FileOutputStream fos =null;
		try {
			 fis = new FileInputStream(src);
			 fos = new FileOutputStream(dest);
			//4.读		
				byte[] bs = new byte[10];
				int len = 0;
				while((len = fis.read(bs))!=-1){
					// 5.写到c.txt
					fos.write(bs, 0, len);
				}
				System.out.println("复制完成");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//6.关流 
			if(fos!=null){
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(fis!=null){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

文件字符流 Reader/Writer

FileReader

	FileReader reader = new FileReader("a.txt");
// read的方法
	// 第一种
	int num = reader.read();
	System.out.println(num); // 返回ASCII码值
	// 第二种
	char[] cs = new char[10];
	int num2 = reader.read(cs); // 返回读取的字符个数
	System.out.println(cs);
	System.out.println(num2);
	// 第三种
	int num3 = reader.read(cs); // 返回一个数组 [a, s, d, f, g, h, j, k, l,  ]
	System.out.println(Arrays.toString(cs)); 
	// 数据取完 就会显示 -1
	System.out.println(num3);  // -1
	
// 输出文件
	char[] cs = new char[10];
	int len = 0;
	while((len=reader.read(cs))!=-1){
		// 将字符数组中的内容转成字符串
		String str = new String(cs,0,len);
		System.out.println(str);
	}	
	if(reader!=null){
		reader.close();
	}

FileWriter

FileWriter writer = new FileWriter("c.txt");
		char[] cs = {'a','b','c','d'};
		writer.write(cs);
		writer.flush(); // 刷新	
		writer.write(cs, 2, 2);
		
		writer.write("fdsfdsfds");
		writer.write("abc", 0, 2);
	// 追加
		writer.append('d');
		writer.append("aggfgf");

		writer.close();

缓冲流Buffer

提高执行效率,让操作更加灵活

字节缓冲流

BufferedInputStream

	BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.txt"));
		
	byte[] bs  = new byte[30];
	int num =0;
	while((num = bis.read(bs))!=-1){
		String str = new String(bs, 0, num);
		System.out.println(str);
	}	
		
	if(bis!=null){
		bis.close();
	}

BufferedOutputStream

	BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
	byte[] bs = {97,98,99,100,101,102};
	bos.write(bs, 0, bs.length);
	bos.flush();
	
	if(bos!=null){
		bos.close();
	}

字符缓冲流

BufferedReader

	BufferedReader reader = new BufferedReader(new FileReader("source.txt"));
// 正常读取方式	
	char[] cs = new char[30];
	int num = 0;
	while((num = reader.read(cs))!=-1) {
		String str = new String(cs,0,num);
		System.out.println(str);
	}
	
// 按行读 readLine()方法  读取一行
	String str = null;
	while((str = reader.readLine())!=null) {
		System.out.println(str);
	}

	if(reader!=null) {
		reader.close();
	}

BufferedWriter

	BufferedWriter writer = new BufferedWriter(new FileWriter("a.txt"));
// writer()第一种
	writer.write("abc");
// writer()第二种
	char[] cs = {'a','b','c'};
	writer.write(cs,0,cs.length);
	writer.flush(); // 因为是缓冲流,如果写入的内容没有达到它的限度,就需要手动缓冲
// writer()第三种
	writer.newLine();  // 换行
	
	if(writer!=null) {
		writer.close();
	}

对象流

所有流 直接操作的都是 字节或者字符
对象流 -->对象—>文件中
ObjectInputStrea
ObjectOutputStream

中转站:
序列化 Serializable
对象–>字节 序列化
字节–>对象 反序列化

序列化版本号
保持版本一致,在修改前序列化的对象, 在修改后可以进行照常反序列化

private static final long serialVersionUID = 1L;

transient 暂态

new出来的对象是可以使用此属性值,但是不能序列化到文件
transient int age;

对象流存、取对象(不推荐)

	Student stu = new Student("张三", 18);
	Student stu2 = new Student("李四", 19);
// 存入文件 将对象---> 字节   序列化
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("w.txt"));
		oos.writeObject(stu);
		oos.writeObject(stu2);
		oos.flush();
// 读取出来  将字节--->对象   反序列化
	ObjectInputStream ois = new ObjectInputStream(new FileInputStream("w.txt"));
	Object stu3 = ois.readObject();
	Object stu4 = ois.readObject();// 存的时候 按照顺序存, 读的时候 是按照存入的顺序读
	Object stu5 = ois.readObject();// 存的时候 按照顺序存, 读的时候 是按照存入的顺序读
	System.out.println(stu3);
	System.out.println(stu4);
	System.out.println(stu5);
存储多个对象 ,读取的时候 用抛异常(EOFException)的方法结束
//EOFException 对象流 没有-1 null这种标志的, 当读到文件结尾,再继续去读取的时候,会以抛异常的方式提示你文件到结尾了
	try{
		while(true){
			Object obj = ois.readObject();
			System.out.println(obj);
		}
	}catch (EOFException e) {
		System.out.println("文件已达结尾");
	}
更加推荐的写法是 一个文件中只写一个对象
所以一般用集合

对象流存、取对象

	List<Student> list = new ArrayList<Student>();
	list.add(new Student("张三", 4));
	list.add(new Student("李四", 4));
	list.add(new Student("王五", 4));
	list.add(new Student("赵柳", 4));
		
// 将一个集合 通过对象流存入到了 文件  序列化
	ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream("z.txt"));
	oos2.writeObject(list);
	oos2.flush();
	
// 将集合通过对象流从文件中读取出来 反序列化
	ObjectInputStream ois2 = new ObjectInputStream(new FileInputStream("z.txt"));
	List<Student> list2 = (List<Student>)ois2.readObject();
	for (Student student : list2) {
		System.out.println(student);
	}

Properties

属性集 键值对都是String类型
存入的顺序随机

父类是Hashtable  实现Map
Properties 拥有了map中所有的功能
以键值对的方法存入,key和value都是String类型
	Properties properties = new Properties();
	properties.setProperty("1", "aaa");
	properties.setProperty("2", "bbb");
	properties.setProperty("3", "ccc");
	
	String value1 = properties.getProperty("1");
	String value2 = properties.getProperty("2");
	String value3 = properties.getProperty("3");
	
	// getProperty 键不存在的时候, 可以设定默认的value值
	String value4 = properties.getProperty("5", "zzz");
	
	// 遍历properties的一种方式
	Set<Entry<Object,Object>> set = properties.entrySet();
	for (Entry<Object, Object> entry : set) {
		System.out.println(entry.getKey()+"="+entry.getValue());
	}
	
	// 遍历properties的第二种方式
	Set<Object> set2 = properties.keySet();
	for (Object key : set2) {
		Object value = properties.get(key);
		System.out.println(key+" = "+value);
	}
经常用到的方法
	Properties properties = new Properties();
// 将db.properties中的信息读取到 properties
	properties.load(new FileInputStream("db.properties"));
// 获取键值对
	String driver = properties.getProperty("driver");
	String url = properties.getProperty("url");
	String username = properties.getProperty("username");
	String password = properties.getProperty("password");
	
	// 下一步就是注册jdbc
	
	Properties properties2 = new Properties();
// 设置键值对
	properties2.setProperty("money", "1000000000000");
	properties2.setProperty("girlfriend", "java");
	properties2.setProperty("girlfriend2", "riyu");
	properties2.setProperty("girlfriend3", "go");
	properties2.setProperty("girlfriend4", "clenrabush");
// 存入文件
	properties2.store(new FileOutputStream("do-dream.txt"), "注释 you are dream");

结果如下:
存入文件的结果

转换流

实质上是字符流  父类是Reader  Writer

InputStreamReader   字节 --> 字符
OutputStreamWriter  字符 --> 字节     二进制  对应适当的规则,进行转换成不同的编码格式
字节流和字符流之间进行转换
也可以解决因为编码格式不同造成的乱码问题

ascii unicode编码表

编码格式
				编码
高级语言   ---> 机器语言   再给计算机执行 
 				解码
 机器语言  ---> 高级语言   再给人去看
 UTF-8 编码格式  规则     汉字   100
 GBK  编码格式  规则        sa	100

想要保证读写过程中 文字不是乱码,则要保证, 流和接触到的文件的编码格式一致

//  zz.txt  的编码格式是GBK     这个Test类是utf-8  
	InputStreamReader isr = new InputStreamReader(new FileInputStream("zz.txt"),"GBK");
	char[] cs = new char[20];
	int num = isr.read(cs);
	String str = new String(cs,0,num);
	System.out.println(str);

打印流

字节打印流

PrintStream 帮助实现打印输出效果

	PrintStream ps = System.out;// System.out 标准输出    就是输出到控制台
	ps.println("aaa");

	System.out.println("bbb");

用PrintStream存到txt文件里

	PrintStream ps2 = new PrintStream("c.txt");
	ps2.println("bb"); // 换行
	ps2.print("333"); // 不换行
	ps2.write(new byte[]{97,98,99,100}); // 存的是ASCII码值
	ps2.flush();

err

err 也是printStream流类型

System.err.println("aaa");

结果:
在这里插入图片描述

字符打印流

PrintWriter 存到txt文件中

	// 字符打印流
	PrintWriter writer = new PrintWriter("e.txt");
	writer.write(new char[]{'a','b','c'});
	writer.println("aaaa"); // 换行
	writer.print("aaaa"); // 不换行
	writer.flush();

输入流

数据类型是InputStream
InputStream is = System.in;// 标注输入
	InputStream is = System.in;
	int num = is.read(); // 读取操作
		int num2 = is.read(); // 读取操作
		int num3 = is.read(); // 读取操作
		int num4 = is.read(); // 读取操作
		int num5 = is.read(); // 读取操作
		int num6 = is.read(); // 读取操作
		System.out.println(num);
		System.out.println(num2);
		System.out.println(num3);
		System.out.println(num4);
		System.out.println(num5);
		System.out.println(num6);

// 过滤掉回车和换行 13、10
	for (int i = 0; i < 5; i++) {
		int num = is.read();
		if(num==13 || num==10){
			i--;
		}else{
			System.out.println((char)num);
		}
	}

结果:

每读三次返回一次,13和10是回车和换行

在这里插入图片描述
汉字:

先把字节流转成 字符流
转换流 InputStreamReader    将字节转成字符
			OutputStreamWriter  将字符转字节
// 								InputStream 就是一个字符流  上面的is
	InputStreamReader reader = new InputStreamReader(is);
	char[] cs = new char[14];
	int num = reader.read(cs);
	System.out.println(Arrays.toString(cs));

结果:
在这里插入图片描述
用缓冲流按行读

//                           				上面的reader
	BufferedReader reader2 = new BufferedReader(reader);
	String str = reader2.readLine();
	System.out.println(str);

结果:
在这里插入图片描述
仿Scanner的nextLine方法的实现

	InputStream is2 = System.in;
	// 字节流--->字符流
	InputStreamReader reader3 = new InputStreamReader(is2);
	// 一次读取一行
	BufferedReader reader4 = new BufferedReader(reader3);
	String str3 = reader4.readLine();
	System.out.println(str3);

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值