Java IO流入门宝典

IO流入门

文件

什么是文件?

Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。

File对象代表磁盘中实际存在的文件和目录。

通俗来讲,文件对象(File)是文件夹和文件的统称

注意:File 类只能操作文件的属性,文件的内容是不能操作的。

文件的创建

说明:文件路径不存在,也是可以创建文件对象的。

1、通过给定的路径创建

格式:

File(String pathname) 
//通过文件路径进行创建(绝对路径)

		String pathname = "E:\\java\\TRstudy\\testStudy\\IOStudy\\testIO";
		File file = new File(pathname);

//不使用 Java 提供的分隔符字段,注意:这样写只能在 Windows 平台有效
        File f1 = new File("D:\\IO\\a.txt");
        //使用 Java 提供的分隔符
        File f2 = new File("D:"+File.separator+"IO"+File.separator+"a.txt");
2、通过父路径(字符串)和子路径创建

父路径: 文件夹路径

子路径:文件路径

格式:

File(String parent, String child) 
	// 通过父路径和子路径创建file对象(相对路径)

		String parentName = ".\test";
		String childName = "Demo1.txt";
		File file3 = new File(parentName,childName);
3、通过父路径(文件)和子路径创建2

格式:

File(File parent, String child);
// 通过父路径(文件对象)和子路径创建file对象

		File parentFile = new File(".\test"); 
		String cName = "Demo1.txt";
		File file4 = new File(parentFile,childName);
4、通过URL创建
File(URI uri) 
常用方法

创建文件或文件夹

方法描述
boolean createNewFile()创建一个新文件
boolean mkdirs()创建子文件夹,可以同时创建多级

查看文件或文件夹信息

方法描述
boolean exists()判断文件是否存在
String getName()获得文件或文件夹的名称
String getParentName()获取文件所在的父文件夹
String getPath()获得带路径的文件或文件夹的名称
boolean isDirectory()判断是否为文件夹
boolean isFile()判断是否为文件
long length()获得文件长度
long lastModified()获得文件的最后修改时间

查找定义目录下的文件或子文件夹

File[] listFiles()遍历文件夹中的所有子文件夹和文件 (只能一层)
boolean delete()删除文件或文件夹
最好先判断一下文件或文件夹是否存在
文件过滤器
		// 获取文件夹下的所有文件或文件夹对象
		
		// 普通
		File file = new File("C:\\testIO");
		for (File f : file.listFiles()) {
			System.out.println(f.getName());
		}
		
		// 过滤
		for (File f : file.listFiles(new FileFilter() {

			@Override
			public boolean accept(File pathname) {
				String name = pathname.getName();
				// 定义过滤规则 假如只要.txt后缀的文件
				if (name.endsWith(".txt") || pathname.isDirectory()) {
					return true;
				}
				return false;
			}

		})) {
			// 输出过滤后的文件
			System.out.println(f.getName());
		}

获取某文件下的所有子文件,及文件夹?

练习:

删除某文件下的所有txt文件?(递归)

package com.xhb.CharStream;

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

public class IOStream2_Zy2 {

	public static void main(String[] args) {
		
		File file = new File("c:testIO\\testDelete");
		deleteFile(file);
	}

	private static void deleteFile(File file) {
		// 判断文件夹是否存在
		if (file.exists()) {
			
			// 列出所有文件(文件和文件夹)
			File[] list = file.listFiles();
			for (File file2 : list) {
				
				// 如果是文件夹,递归
				if(file2.isDirectory()) {
					deleteFile(file2);
				}else {
					// 是文件?判断是否是txt文件
					if (file2.getName().endsWith(".txt")) {
						boolean isDelete = file2.delete();  // 删除文件
						System.out.println(file2.getPath()+":"+(isDelete==true?"删除成功":"删除失败"));
					}
				}
				
			}
		
		}else {
			System.out.println("文件夹不存在");
		}
	}
}

I/O流

  • I -> Input
  • O-> Output

是指在计算机的输入输出操作中各部件之间的数据流动。

流向是针对程序而言

  • 从磁盘读入到程序内存中(输入 Input)
  • 从程序中写到文件中(输出 Output)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3GIdvcb-1622628810206)(D:\install\typora\images\image-20210601160936313.png)]

规律:

字符流:

  • Reader(抽象)

  • Writer(抽象)

凡是带Reader 或 Writer 结尾的,都是他的实现类,也就是字符输入流

字节流:

  • InputStream(抽象)

  • OutputStream(抽象)

凡是带 InputStream 或 OutputStream 结尾的,都是他的实现类,也就是字节输入流

Buffered开头的都是带缓存区的

字节流

OutputStream(抽象) 下面都是实现的子类

  • FileOutputStream (字节输出流)

InputStream(抽象)下面都是实现的子类

  • FileInputStream(字节输入流)
FileInputStream 读数据(三种)

int read() 读取一个字节,效率低,用得少

		// InputStream  读一个字节
		String pathname = "C:\\testIO\\name.txt";
		InputStream is = new FileInputStream(pathname);
		int len = 0;
		System.out.println((char)is.read());

int read(byte[] b) 读取多个字节,字节数组越大,读到的字节就越多
返回实际读取到的字节数

String pathname = "C:\\testIO\\name.txt";
		InputStream is = new FileInputStream(pathname);
		int len = 0;
		byte [] b = new byte[1024];
		StringBuffer sb = new StringBuffer();
		while((len = is.read(b))!=-1) {
			sb.append(new String(b,0,len));
		}
		System.out.println(sb);

int read(byte[] b,int off,int len) 读取多个字节,字节数组越大,读到的字节就越多
返回实际读取到的字节数

String pathname = "C:\\testIO\\name.txt";
		InputStream is = new FileInputStream(pathname);
		byte[] b = new byte[1024];
		int len=2,offset = 0;
		StringBuffer sb = new StringBuffer();
		while((len = is.read(b, offset, len))!=-1) {
			offset+=len;
		}
		sb.append(new String(b,0,offset));
		System.out.println(sb);
FileOutputStream 写数据

默认覆盖写入

// 常规写法	  
		String parentName = "c:\\testIO";
		String childName = "a.txt";
		File file = new File(parentName,childName);
		OutputStream os = new FileOutputStream(file);
		String content = "你是谁,爱上谁";
		os.write(content.getBytes());

注意:

  1. 文件不存在,则会自己创建,文件存在,则会覆盖(文件会自己创建,文件夹不会)

  2. 若需追加数据,在new Outputstream 时,添加参数true

	OutputStream os = new FileOutputStream(file,true);
关流

必须关流

写在finally 里

is.close();
os.close();
拷贝案例
package com.xhb.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOStream_Zy3 {

	public static void main(String[] args) {

		// 源文件路径
		File file = new File("C:\\Users\\13500\\Desktop\\money.png");

		// 源文件存在 才能被复制
		if (file.exists()) {
			// 图片的目的地址
			File toParentFile = new File("c:\\testIO");
			File toChildFile = new File("c:\\testIO\\copyimg.png");

			// 目的地址父路径不存在就创建
			if (!toParentFile.exists()) {
				toParentFile.mkdirs();
			}

			// 目的地址子路径不存在就创建
			if (!toChildFile.exists()) {
				try {
					toChildFile.createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			// 复制图片
			copyPhoto(file, toChildFile);

		} else {
			System.out.println("源文件不存在");
		}

	}

	// 复制图片
	public static void copyPhoto(File file, File toFile) {

		InputStream is;
		try {

			is = new FileInputStream(file);
			OutputStream os = new FileOutputStream(toFile);

			byte[] b = new byte[1024];
			int len ;
			while ((len = is.read(b)) != -1) {
				os.write(b);
			}

			if (is != null) {
				is.close();
			}
			if (os != null) {
				os.close();
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}

字符流

只列出了常用的。

Reader(抽象)

  • FileReader (实现类)
  • BufferedReader (实现类)

Writer(抽象)

  • FileWriter(实现类)
  • BufferedWrite(实现类)

字符流是由字符组成的 ,包括字符、字符串和字符数组等 字符流处理由2个字节构成的Unicode编码

​ 一般的文本文件(.txt)就使用使用字符流来处理

字符流与字节流的区别?

字符流由字符组成,只能包含文本

字节流由字节组成,可以包含任意类型的数据,比如图片、视频、文本等

因为文本涉及到编码的问题,所以用字节流的话,还需要解码,所以如果是纯文本的话,就用字符流

FileWriter

写数据

		File file = new File("c:testIO\\a.txt");
		Writer w = new FileWriter(file,true);  // 表示追加
		System.out.println("请输入一段文字:");
		Scanner scanner = new Scanner(System.in);
		String content = scanner.next();
		w.write('\n');
		w.write(content);
		w.close();
		scanner.close();
BufferedWrite

带缓冲区的写数据

	  System.out.println("请输入一段文字:");
		Scanner scanner = new Scanner(System.in);
		String content = scanner.next();
		
		Writer fw = new FileWriter(file,true);// 追加
		BufferedWriter bW = new BufferedWriter(fw);
		
		bW.write(content);
		bw.flush();
		bW.close();
PrintWriter
		PrintWriter pw = new PrintWriter(new FileOutputStream(file,true),true);
		pw.write("the quick brown fox");
		pw.close();
FileReader

读数据

如果定义的字符数组不够,则会出现问题。怎么解决?没想好

		Reader reader = new FileReader(file);
		int len = 0,size = 0;
		StringBuffer sb = new StringBuffer();
		char[] b = new char[1024];
		
		while((len = reader.read(b,size,5))!=-1) {
			size += len;
		}
		sb.append(new String(b,0,size));
		System.out.println(sb);
		reader.close();
BufferedReader

带缓冲区的读

	Reader in = new FileReader(file);
		BufferedReader br = new BufferedReader(in);
		String line ;
		while((line = br.readLine())!=null) {
			System.out.println(line);
		}

readLine(): 读一行数据,BufferedReader 中特有的

转换流

字节流 --> 字符流

  • InputStreamReader: 将字节输入流装换成字符输入流
  • OutputStreamWriter: 将字节输出流转换成字符输出流
InputStreamReader
		//文件
		File file = new File("c:\\testIO\\name.txt");
		//字节流
		InputStream is = new FileInputStream(file);
		//转换流
		InputStreamReader isr = new InputStreamReader(is);
		//字符流
		BufferedReader br = new BufferedReader(isr);
    // 这里就是操作字符流了  详情见上
		String str;
		while((str = br.readLine())!=null) {
			System.out.println(str);
		}
OutputStreamWriter
		// 文件
		File file = new File("c:\\testIO\\name.txt");
		//字节流 输出
		OutputStream os = new FileOutputStream(file,true);
		//转换流
		OutputStreamWriter osw = new OutputStreamWriter(os);
		//字符输出流
		BufferedWriter bw = new BufferedWriter(osw); 
		
		bw.write("嘻嘻哈哈");
		bw.close();

总结:

四大基类:都是抽象类

  • InputStream
  • OutputStream
  • Writer
  • Reader

前两个是字节流,后两个是字符流

按功能分:

  • 节点流

    例如:FileOutputStream,这些直接操作的就是节点流

  • 处理流(包装流)

    例如:BufferedReader 处理流的构造方法总是要带一个其他的流对象做参数,一个流对象经过其他流的多次包装,称为流的链接

规律:

  • 带Buffered 开头的 都是带缓存区 的流 (速度快,效率高)
  • 以OutPutStream/ InputStream 结尾的,都是字节流
  • 以Writer / Reader 结尾的,都是字符流
  • 构造方法里,要传入一个流对象的,都是包装流(缓存流,转换流,内存流,合并流 这些都是包装流)
  • 关闭包装流时,只要关闭包装流即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值