学习IO前我们先来看看"文件"的相关内容
一 .File
1.理解文件
什么是文件?
- 站在课本角度
文件是相关记录或者放在一起的数据的集合- 站在日常实用角度
你在windows操作中,经常在硬盘上创建的各种.txt, .doc, .exe, .java, .lib, .mp3等等,都可以称之为文件- 文件简单的可以理解成,在外设硬盘上面保存数据的一种方式
文件一共可以由两部分构成:属性(文件大小,文件名,文件类型等)+内容(就是文件里面放的是什么)
java给我提供了以下api让我们来操作文文件(java.io.File)
2.File中的相关方法
2.1 构造方法
方法 | 解释 |
---|---|
public File(File parent, String child) | 可指明父路径和子路径 |
public File(URI uri) | 通过将给定的file: URI转换为抽象路径名来创建新的File 实例。 |
2.2 File类的常用方法
方法 | 解释 |
---|---|
public boolean exists() | 测试指定路径中文件或者目录是否存在 |
public boolean isDirectory() | 判定一个文件是目录 |
public boolean isFile() | 判定是否是文件 |
public boolean delete() | 删除文件 |
public boolean createNewFile() | 创建一个新文件 |
public boolean mkdir() | 创建一个空目录 |
public boolean mkdirs() | 创建目录(无论有多少级父目录,都会创建) |
public String getParent() | 取得父路径 |
public File getParentFile() | 取得父File对象 |
public long length() | 取得文件大小(字节) |
public long lastModified() | 最后一次修改日期 |
public File[] listFiles() | 列出一个目录指定的全部组成 |
综合案例:递归打印文件内容列表
思路:如果是目录就列出目录中的所有文件(包括目录)依次递归,如果是文件就直接打印
public class IoDemo {
public static void listAllFiles(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
if (files !=null){
for(File file1 : files){
listAllFiles(file1);
}
}
}else{
System.out.println(file);
}
}
public static void main(String[] args) {
File file =new File("C:\\Users\\OS\\Desktop\\学习学习学习");
listAllFiles(file);
}
}
运行截图
2.IO
2.1 流的概念
什么是流呢?
流:在 Java中所有数据都是使用流读写的。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
1.按照流向分:输入流;输出流
2.按照处理数据的单位分:字节流(8位的字节);字符流(16位的字节)
2.2 什么是输出流,输入流
输入就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中。
输出则正好相反,是将数据写入到各种输出设备(比如文件、显示器、磁盘等)。
例如键盘就是一个标准的输入设备,而显示器就是一个标准的输出设备,但是文件既可以作为输入设备,又可以作为输出设备。
2.3 什么是字节流,字符流
File类不支持文件内容处理,如果要处理文件内容,必须要通过流的操作模式来完成。
在java.io包中,流分为两种:字节流与字符流
字节流:数据流中最小的数据单元是字节 。类名以stream结尾
字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节.类名都以Reader、Writer结尾
IO流的体系结构
JAVA IO的类图
我们只需学会用红框框住的类即可(仗剑走天下Hhhhhhhhhhh)
2.5 字节流
FileInputStream 和 FileOutputStream
FileInputStream 从文件系统中的某个文件中获得输入字节。
FileInputStream 用于读取诸如图像数据之类的原始字节流。
构造方法
FileInputStream(File file)
FileInputStream(String name)
FileOutputStream(File file)
FileOutputStream(String name)
示例使用 FileInputStream 和 FileOutputStream 复制图片:
package com.code.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("E:\\壁纸\\preview.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\fuzhi.jpg");
byte[] buffer = new byte[1024];//将内容读入一个byte中
int count = 0;//每次读到的字节数
try {
//当read()返回-1时说明没有内容可读了
while((count = fileInputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,count);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
try {
fileInputStream.close();
fileOutputStream.close();
System.out.println("复制成功.....");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
该写法需要最后关闭流,否则会造成内存泄漏
第二种写法 ,不需要显示的关闭流对象
public static void main(String[] args) throws FileNotFoundException {
byte[] buffer = new byte[1024];//将内容读入一个byte中
int count = 0;//每次读到的字节数
try(FileInputStream fileInputStream = new FileInputStream("E:\\壁纸\\preview.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\fuzhi.jpg")) {
//当read()返回-1时说明没有内容可读了
while((count = fileInputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,count);
}
} catch (IOException e) {
e.printStackTrace();
}
}
2.6 字符流
字符流 FileReader 和 FileWriter
构造方法
FileReader(File file)
FileReader(String fileName)
FileWriter(File file)
FileWriter(String fileName)
示例使用 FileReader 和 FileWriter 复制文件:
package com.code.io;
import java.io.FileReader;
import java.io.FileWriter;
public class ReaderAndWriterDemo {
public static void main(String[] args) {
try(FileReader fr =new FileReader("E:\\测试.txt");
FileWriter fw =new FileWriter("D:\\ceshi.txt")){
char[] buffer = new char[1024];
int readCount = -1;
while((readCount=fr.read(buffer))!=-1){
fw.write(buffer,0,readCount);
fw.flush();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
字符缓冲流 BufferedReader 和 BufferedWriter
为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。
BufferedReader 用于加快读取字符的速度, BufferedWriter 用于加快写入的速度。
BufferedReader 和 BufferedWriter 类各拥有 8192个 字符的缓冲区。当 BufferedReader在 读取文本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用 BufferedWriter 时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
构造方法
BufferedReader(Reader in)
BufferedReader(Reader in, int size)
BufferedWriter(Writer out)
BufferedWriter(Writer out, int size)
示例使用 BufferedReader 和 BufferedWriter 进行文件拷贝
public class BufferedDemo {
public static void main(String[] args) throws IOException {
BufferedReader bf =new BufferedReader(new FileReader("E:\\测试.txt"));
BufferedWriter bw =new BufferedWriter(new FileWriter("D:\\ceshi.txt"));
String read = null;
while((read=bf.readLine())!=null){
bw.write(read);
bw.newLine();//写完一行后,写入一个回车(换行)
bw.flush();
}
bf.close();
bw.close();
}
}
b不需要关闭FileReader和FileWriter,在调用bf.close();bw.close();
时会自动关闭,源码如下:
2.6 字节流对比字符流
1、字节流操作的基本单元是字节;字符流操作的基本单元为Unicode码元。
2、字节流在操作的时候本身不会用到缓冲区的,是与文件本身直接操作的;而字符流在操作的时候使用到缓冲区的。
3、所有文件的存储都是字节(byte)的存储,在磁盘上保留的是字节。