1.IO概述
输入流就是把数据(文件、键盘输入、其他输入设备)读到你的程序中;
输出流是把你程序中的数据输出到外设或文件中
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
因此我们把这种输入和输出动作称为IO操作。
2.File类
java.io.File
将操作系统中的文件,目录(文件夹)路径,封装成File对象,提供方法,操作系统中的内容
File的静态成员变量
File.pathSeparator //与系统有关的路径分隔符,Windows中是一个;而Linux中是一个:
File.separator //与系统有关的默认名称分隔符,是一个右斜线 \,而在Linux中是一个左斜线 /
File类的构造方法
File(String pathname) //参数是一个路径 例:File file=new File("d:\\workspace"); windows中不区分大小写,但linux中区分大小写
File(String parent,String child) //父路径和子路径 例:File file1 =new File("d:","workspace"); 好处:可以单独操作父路径和子路径
File(File parent,String child) //File型的父路径,字符串类型的子路径 例:File parent=new File("d:");File file1 =new File(parent,"workspace"); 好处:父路径是File类型,可以直接调用File类方法
File的创建和删除功能
创建一个文件
注:createNewFile方法只能创建文件,不能创建文件夹
若文件已经存在则创建不成功
创建一个文件夹
如果想创建多级文件夹用mkdirs方法
注:推荐使用mkdirs,单个和多级都可以
若文件夹已经存在则创建不成功
删除一个文件或者文件夹
注意:如果文件或者文件夹已经打开,则删除失败
删除的方法,不走回收站,直接从硬盘中删除,删除有风险,运行需谨慎
File类的获取功能
getName()
返回的是路径中的文件或者文件夹的名字
获取的是路径中的最后部分的名字
File类中常见的方法:
getAbsolutePath和getAbsoluteFile获取的都是绝对路径,但getAbsoluteFile获取的是File对象,推荐使用getAbsoluteFile。
eclipse环境中,写的是相对路径,绝对位置就是工程根目录
File的遍历封装路径中的文件和文件夹名
注意:在获取指定目录下的文件或者文件夹时必须满足下面两个条件
指定的目录必须是存在的,
指定的必须是目录。否则容易引发返回数组为null,出现NullPointerException
文件过滤器
只想要一个目录下的指定扩展名的文件,或者包含某些关键字的文件夹
Filter类实现FileFilter接口
做遍历过滤
递归遍历全目录:
package com.sh.IODemo;
import java.io.File;
public class GetAllDirTest {
public static void main(String[] args) {
//遍历出D:\tomcat8.5下的所有文件
File f=new File("d:\\tomcat8.5");
getAllDir(f);
}
private static void getAllDir(File f) {
//遍历出d:\\tomcat8.5所有文件和文件夹
File[] list = f.listFiles();
for (File file : list) {
//System.out.println(file);
//判断如果遍历的是文件下,再将这个文件夹遍历出来
if (file.isDirectory()) {
getAllDir(file);
//直到遍历的不是文件夹,打印出文件的路径
}else{
System.out.println(file);
}
}
}
}
File类的判断功能:
exists()判断封装的路径是否存在
isDirectory()判断封装的路径是否是文件夹
递归
递归,指在当前方法内调用自己的这种现象
直接递归称为方法自身调用自己。间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
递归打印所有子目录中的文件路径
package com.sh.IODemo;
import java.io.File;
public class GetAllDirTest {
public static void main(String[] args) {
//遍历出D:\tomcat8.5下的所有文件
File f=new File("d:\\tomcat8.5");
getAllDir(f);
}
private static void getAllDir(File f) {
//遍历出d:\\tomcat8.5所有文件和文件夹
File[] list = f.listFiles();
for (File file : list) {
//System.out.println(file);
//判断如果遍历的是文件下,再将这个文件夹遍历出来
if (file.isDirectory()) {
getAllDir(file);
//直到遍历的不是文件夹,打印出文件的路径
}else{
System.out.println(file);
}
}
}
}
3.IO流
给文件中写数据,或者读取文件中的数据
字节输出流OutputStream
OutputStream此抽象类,是表示输出字节流的所有类的超类。操作的数据都是字节,定义了输出字节流的基本共性功能方法
输出流中定义都是写write方法
OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件
FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流
demo
给文件中续写和换行:在原有的文件中续写内容
4.IO的异常处理
public class FileOutputStreamDemo3 {
public static void main(String[] args) {
File file = new File("c:\\file.txt");
//定义FileOutputStream的引用
FileOutputStream fos = null;
try {
//创建FileOutputStream对象
fos = new FileOutputStream(file);
//写出数据
fos.write("abcde".getBytes());
} catch (IOException e) {
System.out.println(e.toString() + "----");
} finally {
//一定要判断fos是否为null,只有不为null时,才可以关闭资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("");
}
}
}
}
}
5.字节输入流InputStream
内存中的数据读到内存中,我们通过InputStream可以实现。InputStream此抽象类,是表示字节输入流的所有类的超类。,定义了字节输入流的基本共性功能方法。
方法:
int read():读取1个字节并返回,没有字节返回-1.
int read(byte[]): 读取一定量的字节数,并存储到字节数组中,返回读取到的字节数
FileInputStream类
demo
package com.sh.inputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
public class FileInputStreamDemo {
@Test
//使用read()读取字节
public void fileInputStreamTest() throws IOException{
File file=new File("c:\\a.txt");
FileInputStream in=new FileInputStream(file);
//int i = in.read();//每次只读取一个字节,读取到结尾的时候,返回一个-1
int len=0;
while ((len=in.read())!=-1) {
System.out.println((char)len);
}
//关闭资源
in.close();
}
@Test
//使用 read(byte[])读取字节
public void fileInputStreamTest1() throws IOException{
File file=new File("c:\\a.txt");
FileInputStream in=new FileInputStream(file);
//数组的作用:缓冲的作用,提高效率
byte[] b=new byte[1024];//数组长度写1024,或者1024的整数倍
int len=0;
while ((len=in.read(b))!=-1) {
System.out.println(new String(b, 0, len));
}
in.close();
}
}
6.文件的复制
原理:读取一个已有的数据,并将这些读到的数据写入到另一个文件中。
package com.sh.copyFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;
public class CopyFile {
// 复制文件,原理:就是将一个文件读取进来,然后再写入到磁盘中
@Test
public void TestCopyFile() {
FileInputStream fin = null;
FileOutputStream fot = null;
try {
File inFile = new File("c:\\XML的转义字符.png");// 读取的文件位置
File outFile = new File("c:\\copy\\copy.png");// 写出的文件位置
fin = new FileInputStream(inFile);// 输入流和要读取的位置关联
fot = new FileOutputStream(outFile);// 输出流和要写入的位置关联
byte[] b = new byte[1024*10];
int len = 0;
while ((len = fin.read(b)) != -1) {
fot.write(b, 0, len);
}
} catch (IOException ox) {
System.out.println(ox);
throw new RuntimeException("文件复制失败");
} finally {
try {
if (fot != null) {
fot.close();
}
} catch (IOException e) {
throw new RuntimeException("文件复制失败");
} finally {
try {
if (fin != null) {
fin.close();
}
} catch (IOException e) {
throw new RuntimeException("文件复制失败");
}
}
}
}
}
7.字符编码
常见的编码 GBK UTF-8 ISO-8859-1
GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0
UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)
iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
文字--->(数字) :编码。 “abc”.getBytes() byte[]
(数字)--->文字 : 解码。 byte[] b={97,98,99} new String(b)
8.FileWriter类
字符输出流,FileWriter只能输出文本
写入字符文件的便捷类
9.FileReader类(读取文本文件中的中文不会乱码)
字符输入流,FileReader只能读取文本
IO流的分类
|- 字节流
|- 字节输入流 InputStream 抽象类
|- FileInputStream 操作文件的字节输入流
|- 字节输出流 OuputStream抽象类
|- FileOutputStream 操作文件的字节输出流
|- 字符流(只针对文本文件的操作)
|- 字符输入流 Reader抽象类
|- InputStreamReader 输入操作的转换流
|- FileReader 用来操作文件的字符输入流(简便的流)
|- 字符输出流 Writer抽象类
|- OutputStreamWriter 输出操作的转换流
|- FileWriter 用来操作文件的字符输出流(简便的流)