JavaSE之I/O流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_1018944104/article/details/82871279

目录

一、File类的使用

1.路径

2.Java的文件管理

3.Java的文件操作

4.Java的目录操作

二、I/O流

1.什么是流?

2.输入/输出

3.流的分类

4.流的继承关系

三、字节流

1.字节流介绍

2.文件字节流

3.缓冲字节流

4.对象字节流

5.打印输出字节流PrintStream

6.数据字节流

四、字符流

1.字符流介绍

2.文件字符流

3.缓冲字符流

4.转换字符流

5.打印输出字符流PrintWriter

五、补充知识

1.介绍Scanner类

2.I/O流异常处理模板

3.自动资源释放



一、File类的使用

1.路径

  • 绝对路径:从盘符到文件的完整路径表示形式,如d:\\data\\a.txt(这里涉及到转义字符)
  • 相对路径:相对于文件的位置,如\\data\\a.txt

2.Java的文件管理

  • Java中用File类来表示对操作系统文件或目录的封装。
  • File类主要用来获取文件(或目录)本身的一些信息,如文件的名字,不涉及文件的读写操作。

3.Java的文件操作

  • File类中操作文件的常用方法:
  • exists():判断文件或目录是否存在,存在返回true,否则返回false
  • createNewFile():新建文件
  • getName():获得文件名
  • getPath():获得路径
  • getAbsoutePath():获得绝对路径
  • getParent():获得父路径
  • canRead():文件是否可读
  • canWrite():文件是否可写
  • isFile():是否为文件
  • long lastModified():最后一次修改时间,返回毫秒值
  • long length():文件的长度 字节数(就是文件的大小),英文字母1字节,汉字2字节
  • boolean delete():删除文件

示例

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
public class TestFile1 {
	public static void main(String[] args) throws IOException {
		//File 操作文件
		File f = new File("D:/data/a.txt");
//		File f = new File("D:/","data/a.txt");
//		File f1 = new File("D:/data/");
//		File f = new File(f1,"a.txt");
//		File f = new File("a.txt");
		//判断文件或目录是否存在,存在返回true,否则返回false
		System.out.println(f.exists());
		//新建文件
		f.createNewFile();
		//获得文件名
		System.out.println(f.getName());
		//获得路径
		System.out.println(f.getPath());
		//获得绝对路径
		System.out.println(f.getAbsolutePath());
		//获得父路径
		System.out.println(f.getParentFile());
		//文件是否可读
		System.out.println(f.canRead());
		//文件是否可写
		System.out.println(f.canWrite());
		//是否为文件
		System.out.println(f.isFile());
		//最后一次修改时间,返回毫秒值
		long time = f.lastModified();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		System.out.println(sdf.format(time));
		//文件的长度 字节数(就是文件的大小),英文字母1字节,汉字2字节
		System.out.println(f.length());
	}
}

4.Java的目录操作

4.1.目录

  • 目录是一个包含其他文件或路径列表的File类。

4.2.方法

判断方法

  • boolean exists():判断是否存在
  • boolean isDirectory():判断是否为目录

获得方法

  • String[ ] list():获得的是目录下的子目录和文件的名称
  •  
  • File[ ] listFiles():获得目录下的子目录和文件的File形式

其他方法

  • mkdir():建立一个目录,若父目录不存在,则不会创建
  • mkdirs():建立一个目录,父目录不存在会创建

示例

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Arrays;
public class TestFile2 {
	public static void main(String[] args) {
		//File 目录 文件夹
		File f = new File("d:/data");
		System.out.println(f.exists());
		//是否是目录
		System.out.println(f.isDirectory());
		//list()获得的是目录下的子目录和文件的名称
		String[] fs = f.list();
		Arrays.stream(fs).forEach(System.out::println);
		//文件名过滤器
		fs = f.list(new FilenameFilter() {
			//参数分别是父路径和文件
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith("java");
			}
		});
		Arrays.stream(fs).forEach(System.out::println);
		fs = f.list((dir, name)->name.endsWith("class"));
		Arrays.stream(fs).forEach(System.out::println);
		//获得目录下的子目录和文件的File形式
		File[] fes = f.listFiles();
		for(File f1 : fes){
			if(f1.isDirectory()){
				System.out.println(f1.getAbsolutePath());
			}else {
				System.out.println(f1.getName());
			}
		}
		//过滤java文件
		fes = f.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.getName().endsWith("java");
			}
		});
		fes = f.listFiles(pathname->pathname.getName().endsWith("class"));
		for(File f1 : fes){
			if(f1.isDirectory()){
				System.out.println(f1.getAbsolutePath());
			}else {
				System.out.println(f1.getName());
			}
		}
//		File f = new File("d:/data1");
		File f = new File("d:/data2/data3");
		System.out.println(f.exists());
		//建立一个目录,若父目录不存在,则不会创建
		f.mkdir();
		//建立一个目录,父目录不存在会创建
		f.mkdirs();
	}
}

4.3.过滤器

  • FileNameFilter:函数式接口,文件名过滤器
  • FileFilter:函数式接口,文件过滤器

二、I/O流

1.什么是流?

  • Java中,文件的输入/输出功能通过流来实现。
  • 流(Stream):可以理解为一组有序的、有起点和终点的动态数据集合。

2.输入/输出

  • 以计算机内存作为参照,数据流入内存称为输入,数据流出内存称为输出。
  • Java在java.io包中定义了多个流类型实现输入和输出。

3.流的分类

按照流的数据类型分为:

  • 字节流:每次读写一个字节
  • 字符流:每次读写一个字符

按照方向分为:

  • 输入流(读):硬盘文件 -> 内存变量
  • 输出流(写):内存变量 -> 硬盘文件

按照功能分为:

  • 节点流:直接对数据源进行操作的流
  • 处理流:提供了更多的功能(过滤、包装)或提高了效率

4.流的继承关系

三、字节流

1.字节流介绍

1.1.特点

  • 以字节为单位对数据进行读写。
  • 字节流是万能的,可以处理任何文件,比如文本、图片、音视频等。一般用来处理非文本的文件。

1.2.字节流的两个抽象类

InputStream:所有字节输入流的父类。主要方法包括

  • int read():从输入流中读取一个字节,到达文件尾返回-1。
  • void close():关闭此输入流并释放与此流有关的所有系统资源。

OutputStream:所有字节输出流的父类。主要方法包括

  • void write(int b):将指定的字节写入此输出流。
  • void close():关闭此输入流并释放与此流有关的所有系统资源。

注:判断是字节流还是字符流,只需看后缀即可,比如xxxStream和xxxReader

2.文件字节流

FileInputStream 类和 FileOutputStream 类

示例

//读取文件
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**文件流*/
public class TestFileInputStream1 {
	public static void main(String[] args) throws IOException {
		//1.创建流对象
		//FileNotFoundException 文件找不到
//		FileInputStream fin = new FileInputStream("d:\\data\\a.txt");
		File f = new File("d:\\data\\a.txt");
		FileInputStream fin = new FileInputStream(f);
		//2.读
		//读一字节 IOException(读写时都需要处理异常)
		//文件末尾返回-1
		int temp;//abc你好
		while((temp = fin.read()) != -1){
			System.out.println((char)temp);
		}
		//3.关闭流
		fin.close();
	}
}
//写入文件
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileOutputSteam1 {
	public static void main(String[] args) throws IOException {
		//String s 存到文件b.txt
		//创建流对象
		//父目录不存在会引发异常,文件可以自动创建
//		FileOutputStream fout = new FileOutputStream("d:\\data\\b.txt");
		//第二个参数,如果是true,则是追加写入。默认是覆盖写入。
		FileOutputStream fout = new FileOutputStream("d:\\data\\b.txt",true);
		//写
		//(1)一次写一字节,比如97 就是写入字符a
//		fout.write(97);
		//(2)写入字节数组
		String s = "hello";
		byte[] b = s.getBytes();
//		fout.write(b);
		//参数分别是:字节数组,起始位置,几个字节
		fout.write(b, 2, 2);
		//关闭
		fout.close();
	}
}

3.缓冲字节流

BufferedInputStream 类和 BufferedOutputStream 类

示例:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestFileInOut {
	public static void main(String[] args) {
		//读a.txt 写入到b.txt
		//1.流对象
		FileInputStream fin = null;
		//缓冲流 8192字节
		BufferedInputStream bfin = null;
		FileOutputStream fout = null;
		BufferedOutputStream bfout = null;
		try {
			fin = new FileInputStream("d:\\data\\pic.jpg");
			bfin = new BufferedInputStream(fin);
			fout = new FileOutputStream("d:\\data2\\pic.jpg");
			bfout = new BufferedOutputStream(fout);
			//2.读写
			int temp;
			while((temp = bfin.read()) != -1){
				bfout.write(temp);
			}
			//强制刷新缓冲区,保证所有数据写入到目的地
			bfout.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//关闭流
			if (fin != null) {
				try {
					bfin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fout != null) {
				try {
					bfout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

4.对象字节流

ObjectInputStream 类和 ObjectOutputStream 类

示例:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Student implements Serializable{
	/**
	 * 版本号,手动指定后,系统则不会自动生成。
	 * 若升级类的版本,则需手动指定版本号才能正常反序列化,否则序列号不一致,导致失败。
	 */
	private static final long serialVersionUID = 1L;
	private int no;
	private String name;
	public Student(int no, String name) {
		super();
		this.no = no;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Student [no=" + no + ", name=" + name + "]";
	}
}
public class TestObjectOutputSteam {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//序列化:把对象转换成字节序列(对象存到文件中)
		Student guojing = new Student(20,"guojing");
		FileOutputStream fout = new FileOutputStream("d:\\data\\obj.txt");
		ObjectOutputStream objOut = new ObjectOutputStream(fout);
		objOut.writeObject(guojing);
		objOut.close();
		//反序列化:把文件中的对象还原(把字节序列还原成对象)
		FileInputStream fin = new FileInputStream("d:\\data\\obj.txt");
		ObjectInputStream objIn = new ObjectInputStream(fin);
		Student stu = (Student)objIn.readObject();
		System.out.println(stu);
		objIn.close();
	}
}

5.打印输出字节流PrintStream

示例:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
public class TestPrintStream {
	public static void main(String[] args) throws IOException {
		//从文件中读内容,把内容展现在控制台
		FileInputStream fin = new FileInputStream("d:\\data\\a.txt");
		byte[] b = new byte[fin.available()];
		fin.read(b);
		String s = new String(b);
		fin.close();
		PrintStream p = new PrintStream(System.out);
		p.println(s);
		p.close();
	}
}

6.数据字节流

DataInputStream 类和 DataOutputStream 类

示例:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestDataInputStream {
	public static void main(String[] args) throws IOException {
		//写,输出
		//1.
		File f = new File("d:\\data\\data.txt");
		FileOutputStream fout = new FileOutputStream(f);
		DataOutputStream dout = new DataOutputStream(fout);
		//2.写
		int[] no = {11,22,33};
		String[] name = {"aa","bb","cc"};
		for (int i = 0; i < name.length; i++) {
			dout.write(no[i]);
			dout.writeUTF(name[i]);
		}
		//3.
		dout.close();
		//1.写入和读取的格式要一样,顺序也要一样。
		FileInputStream fin = new FileInputStream(f);
		DataInputStream din = new DataInputStream(fin);
		for (int i = 0; i < name.length; i++) {
			System.out.println(din.readInt());
			System.out.println(din.readUTF());
		}
		din.close();
	}
}

四、字符流

1.字符流介绍

1.1.特点

  • 以字符为单位对数据进行读写。
  • 只能处理文本文件。
  • 最底层是文件字符流:FileReader 类和 FileWriter 类

1.2.字符流的两个抽象类

Reader:所有字符输入流的父类。主要方法包括

  • int read():从输入流中读取一个字符,到达文件尾返回-1。
  • void close():关闭此输入流并释放与此流有关的所有系统资源。

Writer:所有字符输出流的父类。主要方法包括

  • void write(int b):将指定的字符写入此输出流。
  • void close():关闭此输入流并释放与此流有关的所有系统资源。

2.文件字符流

FileReader 类和 FileWriter 类

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestReader {
	public static void main(String[] args) throws IOException {
		//读a.txt
		FileReader fr = new FileReader("d:\\data\\a.txt");
		int temp;
		while((temp = fr.read()) != -1){
			System.out.println((char)temp);
		}
		fr.close();
		File f = new File("d:\\data\\w.txt");
		FileWriter fw = new FileWriter(f);
		String s = "hello";
		fw.write(s);
		fw.close();
	}
}

3.缓冲字符流

BufferedReader 类和 BufferedWriter类

示例:练习题

1)格式模板保存在文本文件temp.txt中,内容如下:

您好!

我的名字是{name},我是一只{type}。

我的主人是{master}。

2)其中{name}、{type}、{master}是需要替换的内容,现在要求按照模板格式保存宠物数据到文本文件,即把{name}、{type}、{master}替换为具体的宠物信息。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestBufferedRW {
	public static void main(String[] args) {
		File f = null;
		FileReader fr = null;
		FileWriter fw = null;
		BufferedReader bfr = null;
		BufferedWriter bfw = null;
		try {
			f = new File("d:\\data\\temp.txt");
			//输入流
			fr = new FileReader(f);
			bfr = new BufferedReader(fr);
			//输出流
			fw = new FileWriter(f);
			bfw = new BufferedWriter(fw);
			
			String temp;
			StringBuffer sb = new StringBuffer();
			//读取
			while((temp = bfr.readLine()) != null){
				sb.append(temp);
				sb.append("\r\n");
			}
			//替换
			temp = sb.toString();
			temp = temp.replace("{name}", "Kitty");
			temp = temp.replace("{type}", "加菲猫");
			temp = temp.replace("{master}", "Tom");
			//写入缓冲流
			bfw.write(temp);
			//刷新缓冲流
			bfw.flush();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (bfr != null) {
				try {
					bfr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (bfw != null) {
				try {
					bfw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

4.转换字符流

InputStreamReader 类和 OutputStreamWriter 类

示例:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestFileInputStream2 {
	public static void main(String[] args) throws IOException {
		//1.创建流对象
		//FileNotFoundException 文件找不到
//		FileInputStream fin = new FileInputStream("d:\\data\\a.txt");
		File f = new File("d:\\data\\a.txt");
		FileInputStream fin = new FileInputStream(f);
		//把字节流转换成字符流
		InputStreamReader fr = new InputStreamReader(fin);
		//2.读
		//读一字节 IOException(读写时都需要处理异常)
		//文件末尾返回-1
		int temp;//abc你好
		while((temp = fr.read()) != -1){
			System.out.println((char)temp);
		}
		//3.关闭流
		fin.close();
	}
}

5.打印输出字符流PrintWriter

示例:循环输入学员的姓名,输入"q"结束,把输入的内容存在name.txt文件中。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class TestStuName {
	public static void main(String[] args) {
		File file = new File("d:\\data\\name.txt");
		PrintWriter pw = null;
		try {
			pw = new PrintWriter(file);
			for (int i = 0; i < 4; i++) {
				pw.println("请输入:" + i);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (pw != null) {
				pw.close();
			}
		}
	}
}	

五、补充知识

1.介绍Scanner类

import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestScanner {
	public static void main(String[] args) throws FileNotFoundException {
//		//System.in 代表键盘输入
//		Scanner sc = new Scanner(System.in);
//		String s = sc.next();
//		//System.out 代表控制台输出
//		System.out.println(s);
		
//		FileInputStream fin = new FileInputStream("d:\\data\\a.txt");
//		Scanner sc1 = new Scanner(fin);
//		String s1 = sc1.next();
//		System.out.println(s1);
		
//		Scanner sc1 = new Scanner("aa bb cc dd");
//		String s1 = sc1.nextLine();
//		System.out.println(s1);
		
		Scanner sc1 = new Scanner(System.in);
		System.out.println("输入一个数字:");
		if (sc1.hasNextInt()) {
			int num = sc1.nextInt();
			System.out.println(num + 23);
		} else {
			System.out.println("不是数字的操作");
		}
	}
}

2.I/O流异常处理模板

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileInOut {
	public static void main(String[] args) {
		//读a.txt 写入到b.txt
		//1.流对象
		FileInputStream fin = null;
		FileOutputStream fout = null;
		try {
			fin = new FileInputStream("d:\\data\\a.txt");
			fout = new FileOutputStream("d:\\data\\a.txt");
			//2.读写
			int temp;
			while((temp = fin.read()) != -1){
				fout.write(temp);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//关闭流
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fout != null) {
				try {
					fout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

3.自动资源释放

原理:只有实现AotoClosable接口才能自动释放资源。只要在try-catch块执行完了,try括号里面资源就会自动释放。

语法:

try(/*声明需要释放的资源*/){
    //可能产生异常的语句
}catch(/*异常*/){
}

示例:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class TestStuName {
	public static void main(String[] args) {
		File file = new File("d:\\data\\name.txt");
		//自动释放资源的语法
		try(PrintWriter pw = new PrintWriter(file);) {
			
			for (int i = 0; i < 4; i++) {
				pw.println("请输入:" + i);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_1018944104/article/details/82871279