目录
4.1 字符流FileReader加BufferedReader实现读取
4.2 字符流FileWriter加BufferedWriter实现写出
1.File简介
1.1 File
1.1.1 什么是文件
生活中,我们以前经常使用纸质类的文件用来保存数据,使文件上的内容可以永久化储存,便于查阅和使用,现在我们可以将许多数据存储在硬盘,U盘等能够存储文件的数据存储器中。
因此,实际上文件就是永久化的一堆数据的集合,其作用就是将数据持久化存储。
1.1.2 Java中的文件File
(1)File是Java中java.io包中的一个类
(2)使用File需要创建其实例,即new File();构造器要求输入字符串形式的文件的路径
1.2 File的增删查
1.2.1 File的创建
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void addFile(File file) throws IOException {
//createFile()方法,如果不存在同名文件,则创建文件并返回true
//如果存在同名文件,不操作,并返回false
//该方法需要抛出异常,如果找不到路径,会抛出异常
boolean flag = file.createNewFile();
if(flag){
System.out.println("新建文件成功!");
}else{
System.out.println("新建文件失败!");
}
}
public static void main(String[] args) throws IOException {
File file = new File("D:\\A\\ddd.txt");
Demo1.addFile(file);
}
}
第一次运行:
第二次运行:
1.2.2 File的查询
import java.io.File;
public class Demo2 {
public static void main(String[] args) {
File file = new File("D:/A/ddd.txt");
//exists()方法可以校验是否存在该文件,防止抛出异常
if(file.exists()){
System.out.println(file.getName());//返回文件名
System.out.println(file.getAbsolutePath());//返回文件绝对路径
}else{
System.out.println("文件不存在!");
}
}
}
1.2.3 File的删除
import java.io.File;
public class Demo3 {
public static void main(String[] args) {
File file = new File("D:/A/ddd.txt");
boolean flag = file.delete();
if(flag){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
}
运行前:
运行后:
1.3 流
1.3.1 计算机中的流
流的机制:先进先出
流的方向:从源数据源到目标数据源
1.3.2 流的指向
读入:从文件到程序
写出:从程序到文件
1.3.3 流的分类
按流向区分:输出流和输入流
按照处理数据单元划分:字节流和字符流
2.字节流
2.1 字节输入流 FileInputStream
2.1.1 读入下一个字节码 read()方法
import java.io.FileInputStream;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:/A/ddd.txt");
int read1 = fis.read();//该方法只能返回一个字节值(ASCII码值)
System.out.println(read1);
int read2 = fis.read();//每次调用,数据字节的指向都会向下走一位
System.out.println(read2);
}
}
文件内容:
控制台结果:
使用循环输出整个文件内容:
import java.io.FileInputStream;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:/A/ddd.txt");
int data = 0;//用于暂时存储数据的字节值
while((data = fis.read())!= -1){
//read()方法到达末尾后返回-1
System.out.print((char)data);//使用char强制转换可以直接显示字符
}
}
}
2.1.2 读入字符数组 read(byte[] b)方法
import java.io.FileInputStream;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:/A/ddd.txt");
int data = 0;
byte b[] = new byte[1024];//定义一个存放值的字节数组
while((data = fis.read(b))!= -1){
//将所有数据读取到数组中,并返回数组的长度
for (int i = 0; i < data; i++) {
System.out.print((char)b[i]);//遍历读取该数组
}
}
}
}
这种方法大大提高了上面单个读取的效率
2.2 字节输出流 FileOutputStream
2.2.1 结合FileInputStream实现复制文件
此方法是覆盖式写入,如果文件不存在会自动创建新文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:/A/ddd.txt");
FileOutputStream fos = new FileOutputStream("D:/A/kkk.txt");
int data = 0;
byte[] b = new byte[1024];
while((data = fis.read(b)) != -1){
fos.write(b,0,data);//0为起始位置,data为源文件数据长度
}
}
}
运行前:
运行后:
2.3 拓展和完善
2.3.1 关闭流
在使用完流的功能时,需要添加close()方法将对象关闭释放内存,并且遵循先开后关的原则。
2.3.2 使用try/catch结构处理异常
一般需要对所有可能出现异常的地方都进行try/catch异常处理,而不是简单的声明抛出异常。
2.3.3 以上一节示例为例完善代码
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo3 {
public static void main(String[] args){
//先定义两个临时变量,使最后关闭时可以获取变量名
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:/A/ddd.txt");
fos = new FileOutputStream("D:/A/kkk.txt");
int data = 0;
byte[] b = new byte[1024];
while ((data = fis.read(b)) != -1) {
fos.write(b, 0, data);//0为起始位置,data为源文件数据长度
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos != null){
fos.close();//先关闭fos
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fis != null){
fis.close();//再关闭fis
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.字符流
3.1 字符流与字节流的区别
字符流实际上使字节流与字符集的结合,很容易发现,字节流只能读取返回ASCII码值,只能识别该字符集中的字符,当文件数据中的字符是中文或者其他非英文语言时则会出现乱码。这时候我们就必须要使用字符流来读取文件。
3.2 读取 FileReader字符流
FileReader的使用方式与字节流类似,可以解决文字乱码的问题
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("D:/A/ddd.txt");
int data = 0;
char[] c = new char[1024];//直接使用char数组
while( (data = fr.read(c)) != -1){
for (int i = 0; i < data; i++) {
System.out.print(c[i]);
}
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}finally {
try{
if(fr != null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.3 写出 FileWriter字符流
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("D:/A/ddd.txt",true);
//append参数默认为false,true表示添加内容而不是覆写
fw.write("字符流写出!");
//也可以用来复制,但单纯复制的话使用字节流即可
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}finally {
try{
if(fw != null){
fw.close();
//写出 字符流必须关闭,否则无法得到结果
//也可以使用flush()但正常情况一般不用
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4. 缓冲流
4.1 字符流FileReader加BufferedReader实现读取
import java.io.*;
public class Demo1 {
public static void main(String[] args) {
Reader fr = null;
BufferedReader br = null;
try{
fr = new FileReader("D:/A/ddd.txt");
br = new BufferedReader(fr);//构造方法需要一个FileReader对象
String data = null;
while ((data = br.readLine()) != null){
//readLine()方法可以一行一行地读取
System.out.println(data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(br != null){
try{
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr != null){
try{
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2 字符流FileWriter加BufferedWriter实现写出
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) {
FileWriter fw = null;
BufferedWriter bw = null;
try{
fw = new FileWriter("D:/A/kkk.txt");
bw = new BufferedWriter(fw);
bw.write("缓冲流写出!");
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bw != null){
try{
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw != null){
try{
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.复制
5.1 字符流实现复制
import java.io.*;
public class Demo1 {
public static void main(String[] args) {
FileReader fr = null;
BufferedReader br = null;
FileWriter fw = null;
BufferedWriter bw = null;
try{
fr = new FileReader("D:/A/ddd.txt");
br = new BufferedReader(fr);
fw = new FileWriter("D:/A/sss.txt");
bw = new BufferedWriter(fw);
StringBuffer sb = new StringBuffer();
String line = null;
while( (line = br.readLine()) != null){
sb.append(line + "\n");//注意每行后面加入换行符
}
bw.write(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//先开后关,后开先关
bw.close();
fw.close();
br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.2 复制二进制文件(图片,视频)
import java.io.*;
public class Demo2 {
public static void main(String[] args) {
//复制二进制文件时,一般要用Data的缓冲流
FileInputStream fis = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try{
fis = new FileInputStream("D:/A/img.png");
dis = new DataInputStream(fis);
fos = new FileOutputStream("D:/A/img_copy.png");
dos = new DataOutputStream(fos);
byte[] b = new byte[1024];
int len = 0;
while((len = dis.read(b)) != -1){
dos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
dos.close();
fos.close();
dis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行前:
运行后: