03File类与IO流
1. File类
1.0 什么是字节和字符
byte即字节的意思,是java中的基本数据类型(整数),用来申明字节型的变量,一个字节包含8个位,所以,byte类型的取值范围是-128~127
,字节为计算机文件大小的基本计算单位
bit是Binary digit(二进制数位)的缩写,意为"位"或者"比特",是计算机运算的基础 和字节(byte)的关系是 1byte = 8bit
为什么要有字符,原因机器只知道字节,而字符确实语意上的单位,他是有编码的,一个字节可能编程成1个2个甚至3个4个字节.这根字符集编码有关系,英文字母和数字是单字节的,但汉字这些自然语言中的字符是多字节的.一个字节只能表示255个字符,不可能用于全球那么多种自然语言的处理,因此肯定就需要多字节的存储方式.如汉字按UNICODE标准所有字符都占2个字节.
1.1 File类描述目录文件和路径的对象
public class FileTest1 {
/*
* File类
* 文件夹 Directory:存储文件的容器,放置文件重名而设置,文件归类,文件夹本身不存储任何数据,计算机专业术语称为:目录
* 文件 File:存储数据的,同一个目录中的文件名不能相同
* 路径 Path:一个目录或者文件在磁盘中的位置 例如: E:\java\day3 是目录的路径 E:\java\day3\day3.iml 是文件的位置
* File类 :描述目录文件和路径的对象
* 和平台无关性 */
public static void main(String[] args) {
fileMethod3();
}
// 直接传入最终的路径
public static void fileMethod() {
// 字符串的路径,变成File对象 => 把day3下所有的文件和文件夹都读取出来了
File file = new File("E:\\java\\day3");
System.out.println(file);
}
// 拼接字符串路径,会自动加上分割符
public static void fileMethod2() {
String path1 = "E:\\java";
String path2 = "day3";
File file = new File(path1, path2);
System.out.println("第二个方法");
System.out.println(file);
}
// file实例拼接字符串
public static void fileMethod3() {
File file = new File("E:\\java");
String path = "day3";
File f2 = new File(file, path);
System.out.println(f2);
}
}
1.2 File类的创建方法
public class FileTest2 {
/*
* File类的创建方法
* 1. Boolean createNewFile() => 创建一个文件,文件路径写在File的构造方法中
* 2. Boolean mkdirs()创建目录,目录的位置和名字写在File的构造方法中 */
public static void main(String[] args) {
createFn2();
}
// 创建文件夹
public static void createFn1() {
File file = new File("E:\\java\\day3\\1.txt"); // 文件夹是可以加"."这个符号的
boolean b = file.mkdirs(); // 创建成功的返回true,失败false
System.out.println(b + "b");
}
// 创建文件
public static void createFn2() {
File file = new File("E:\\java\\day3\\1"); // 文件是可以不加"."的,后缀名是用来解析的
boolean b = false; // 创建成功的返回true,失败false
try {
b = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(b + "b");
}
}
1.3 File类的删除方法
public class FileTest3 {
// File类删除文件和文件夹的操作
public static void main(String[] args) {
// 注意:删除的方法不会进入回收站,直接从磁盘中删除,有误删的风险
File file = new File("E:\\java\\day3\\1");
Boolean b = file.delete();
System.out.println(b);
}
}
1.4 File类的判断方法
public class FileTest {
/*
* File类判断方法
* 1. Boolean exists() 判断构造方法中的路径是否存在
* 2. Boolean isDirectory() 判断构造方法中的路径是不是文件夹
* 3. Boolean isFile() 判断构造方法中的路径是不是文件
* 4. Boolean isAbsolute() 判断构造方法中的路径是不是绝对路径*/
public static void main(String[] args) {
fileFn1();
fileFn2();
fileFn3();
fileFn4();
}
// 1. Boolean exists() 判断构造方法中的路径是否存在
public static void fileFn1() {
File file = new File("E:\\java\\day3\\day4");
boolean b = file.exists();
System.out.println("路径是否存在" + b);
}
// 2. Boolean isDirectory() 判断构造方法中的路径是不是文件夹
public static void fileFn2() {
File file = new File("E:\\java\\day3\\day3.iml");
boolean b = file.isDirectory();
System.out.println("是不是文件夹" + b);
}
// 3. Boolean isFile() 判断构造方法中的路径是不是文件
public static void fileFn3() {
File file = new File("E:\\java\\day3");
boolean b = file.isFile();
System.out.println("是不是文件" + b);
}
// Boolean isAbsolute() 判断构造方法中的路径是不是绝对路径*/
public static void fileFn4() {
File file = new File("E:\\java\\day3");
boolean b = file.isAbsolute();
System.out.println("是不是绝对路径" + b);
}
}
1.5 File类的获取方法
public class Filetest1 {
/*
* File类获取的方法
* 1.File getAbsoluteFile(),返回值是file类型
* 2.File getParentFile() 获取父路径,返回值是File类型
* 3.String getName() 获取名字,File构造方法中的路径名字
* 4.String getPath() 获取File构造方法中的路径,完整的路径转为String返回
* 5.long length()获取文件的字节数
* 6.File[] listFile() 返回值是File[] 数组 , 存储了多个File对象, 方法的作用是遍历当前的文件夹*/
public static void main(String[] args) {
fn2();
}
public static void fn() {
File file = new File("E:\\java\\day3");
File f1 = file.getAbsoluteFile(); // 获取绝对路径
System.out.println(f1);
File f2 = file.getParentFile(); // 获取父路径
System.out.println(f2);
String f3 = file.getName(); // 获取名字
System.out.println(f3);
String f4 = file.getPath(); // 获取路径,但是是String类型的
System.out.println(f4);
Long f5 = file.length(); // 文件字节数
System.out.println(f5);
}
public static void fn2() {
File file = new File("E:\\java\\day3");
File[] arr = file.listFiles();
System.out.println(arr);
}
}
2. IO流
2.1 IO流对象的分类
/*
* IO:Input Output IO作用是将数据从一个设备中流入到另一个设备
* 数据文件:从磁盘中流向内存中,从磁盘中流向移动存储设备,从一台电脑流向另一台电脑
* 一切都是字节:任何数据文件都是字节组成,字节是计算机中最小的存储单元*/
/*
* IO流对象的分类
* 1.按照操作的文件类型分类
* 文本类型文件--选择流对象字符流 文本文件:使用文本工具,记事本打开文件后可以直接阅读的
* 非文本类型文件--选择流对象字节流
* 2按照数据的流向分类
* 输入流:Java程序从其他地方读取数据
* 输出流:Java程序中的数据,写入到其他地方
* 3.IO流对象的分类归纳
* 字节输出流:OutputStream 抽象类
* 字节输入流:InputStream 抽象类
* 字符输出流: Writer 抽象类
* 字符输入流: Reader 抽象类*/
2.2 IO流 字节流 输出(写)
/*
* java.io.OutputStream是所有字节输出流的超类:可以写入任何类型文件
* 写入字节的方法 write
* void write(int b)写入单个字节
* void write(byte[] b) 写入字节数组
* void write(byte[] b,int off,int len) 写入数组的一部分,开始索引,写入的个数*/
/*
* FileOutputStream
* 构造方法:FileOutputStream(File file)
* 构造方法:FileOutputStream(Sting file)
* 创建字节输出流对象,绑定参数就是要写入的数据目的
* 任何一个操作系统都具备IO的能力,JVM依赖操作系统实现IO的功能,IO流对象使用完后,要释放资源*/
/*
* 字节输出流写入文件的步骤
* 1.创建字节输出流对象,构造方法中,绑定文件路径,写入目的
* 2.调用流对象的方法write写入数据
* 3.释放资源*/
public static void main(String[] args) throws IOException {
// fn1();
// fn2();
fn3();
}
// 写入单个字节
public static void fn1() throws IOException {
// 普通创建文件,但是不能写入
/*File file = new File("E:\\java\\day3\\1.txt");
boolean b = false;
try {
b = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(b);*/
// 使用FileOutputStream 字节输出流对象,构造方法中,绑定文件路径,写入目的
FileOutputStream output = null;
output = new FileOutputStream("E:\\java\\day3\\1.txt");
if (output != null) {
output.write(45);
output.write(49);
output.write(48);
output.write(48); // 在方法未执行完之数据会追加
output.close(); // 释放资源
System.out.println("写入完成");
} else {
System.out.println("写入出错了");
}
}
// 写入数组字节
public static void fn2() throws IOException {
FileOutputStream output = new FileOutputStream("E:\\java\\day3\\1.txt");
byte[] bytes = {97, 98, 99, 100, 101, 102};
output.write(bytes);
output.write("我是一个小学生".getBytes());
// 写入数组的一部分
output.write(bytes, 1, 2);
output.close();
System.out.println("输出成功");
}
// 追加写入和换行
public static void fn3() throws IOException {
// 追加写入,在FileOutputStream构造方法中将第二个参数设为true
// 换行就需要系统的换行符号 \r\n
FileOutputStream output = new FileOutputStream("E:\\java\\day3\\1.txt", true);
output.write("你好啊".getBytes()); // 没有从头覆盖
output.write("\r\n我不好".getBytes());
output.close();
System.out.println("写入完毕");
}
}
2.3 IO流 字节流 输入(读)
public class IOTestRead {
/*
* 字节输入流
* java.io.InputStream是所有字节输入流的超类:可以读取任何类型文件
* 读取字节的方法 read()
* int read()读取单个字节,读取到流的末尾返回-1
* int read(byte[] b)读取字节数组,读取到流的末尾返回 -1*/
/*
* FileInputStream
* 构造方法:FileInputStream(File file)
* 构造方法:FileInputStream(String file)
* 创建字节输入流对象,绑定参数就是要读取的数据源文件*/
public static void main(String[] args) throws IOException {
// fn1();
fn2();
}
// 字节输入流,读取单个字节 => int read()读取单个字节
public static void fn1() throws IOException {
FileInputStream input = new FileInputStream("E:\\java\\day3\\1.txt");
int num = 0;
while ((num = input.read()) != -1) {
// System.out.println(num); //返回的是字节码,可以使用char转换
System.out.println((char) num);
}
input.close();
}
// 字节输入流,读取字节数组 int read(byte[] b) 返回读取到的字节的个数
// String类的构造方法=>new String(字节数组,开始索引,转换个数)
public static void fn2() throws IOException {
FileInputStream input = new FileInputStream("E:\\java\\day3\\1.txt");
ArrayList list = new ArrayList();
int code = 0;
while ((code = input.read()) != -1) {
list.add(code);
}
Object[] arr = new Object[list.size()];
list.toArray(arr);
for (Object num : arr) {
System.out.println((char) ((int) num));
}
input.close();
}
}
2.4 IO流 字节流 读写(复制)
public class IOTestReadAndWrite {
/*
* 文件复制就是IO流对象的读写
*/
public static void main(String[] args) throws IOException {
// fn1();
fn2();
}
// 单个读取和写入
public static void fn1() throws IOException {
FileInputStream input = new FileInputStream("E:\\java\\day3\\1.txt");
FileOutputStream output = new FileOutputStream("E:\\java\\day3\\2.txt");
int code = 0;
while ((code = input.read()) != -1) { // 读取字节码
output.write(code); // 写入字节码
}
input.close();
output.close(); // 释放资源
System.out.println("读写完成");
}
// 提高效率使用数组
public static void fn2() throws IOException {
File file = new File("E:\\java\\day3\\1.txt");
long count = file.length(); // 获取文件字节数
byte[] bytes = new byte[(int) count];
FileOutputStream output = new FileOutputStream("E:\\java\\day3\\2.txt");
FileInputStream input = new FileInputStream("E:\\java\\day3\\1.txt");
int code = 0;
while ((code = input.read(bytes)) != -1) {
// 字节输出流,写入字节数组,0索引开始,写入读取到的个数
output.write(bytes, 0, code);
}
input.close();
output.close();
System.out.println("读写成功");
}
}
2.5 IO流 字节流 缓冲流
public class IOTestBuffered {
/*
* 字节流的缓冲流
* 使用字节流的缓冲流,提高原有流对象的读写性能
* 字节流缓冲流本质也是字节流
* BufferedOutputStream 继承OutputStream
* 方法write()写入单个字节或者字节数组
* BufferedOuputStream 构造方法 传递字节输出流
* new BufferedOuputStream (new FileOutputStream()) 传递哪个基础流,就对哪个基础流高效操作
* BufferedInputStream 继承InputStream
* 方法read()读取单个字节,读取字节数组
* BufferedInputStream(InputStream in) 传递字节输入流
* new BufferedInputStream(new FileInputStream())*/
public static void main(String[] args) throws IOException {
fn1();
}
public static void fn1() throws IOException {
File file =
new File(
"D:\\BaiduNetdiskDownload\\高级二期\\01JavaSE阶段的教学视频笔记【完结】\\day01\\video\\01-Java概述-从项目到代码.mp4");
int count = (int) file.length(); // 拿到字节长度
byte[] bytes = new byte[count];
FileInputStream input =
new FileInputStream(
"D:\\BaiduNetdiskDownload\\高级二期\\01JavaSE阶段的教学视频笔记【完结】\\day01\\video\\01-Java概述-从项目到代码.mp4"); // 读取流
BufferedInputStream binput = new BufferedInputStream(input); // 读取缓冲流
FileOutputStream output =
new FileOutputStream(
"D:\\BaiduNetdiskDownload\\高级二期\\01JavaSE阶段的教学视频笔记【完结】\\day01\\video\\01测试读取操作.mp4"); // 写入流
BufferedOutputStream boutput = new BufferedOutputStream(output);
int code = 0;
while ((code = binput.read(bytes)) != -1) { // 读取
boutput.write(bytes, 0, code); // 写入
}
binput.close();
boutput.close(); // 释放
System.out.println("缓冲流读写完成");
}
}
2.6 IO流 字符流
public class IOTestCharacter {
/*
* 字符流
* 只能操作文本文件
* Write类,是所有字符输出流的父类(写入文本文件)
* write()写入字符
* flush()刷新该流的缓冲(写入数据,先写到内存),只有刷新了才会写入文件中
* Read类,是所有字符输入流的父类(读取文本文件)
* int read()读取单个字符/读取字符数组*/
/*
* OutputStreamWriter类=>继承Writer,是字符的输出流,同时又是转换流
* 构造方法:OutputStreamWrite(OutputStream out)传递任意字节输出码
* 构造方法:OutputStreamWrite(OutputStream out,String 编码表名)传递任意字节输出码
* InputStreamReader继承Reader,字符输入流,读取文本文件
* 构造方法:InputStreamReader(InputStream out)传递任意字节输入流
* 构造方法:InputStreamReader(InputStream out,String 编码表名)传递任意字节输入流*/
public static void main(String[] args) throws IOException {
// fn1();
// fn2();
// fn3();
// fn4();
// fn5();
fn6();
}
// 字符输出流
public static void fn1() throws IOException {
// 创建字节流
FileOutputStream output = new FileOutputStream("E:\\java\\day3\\2.txt");
// 创建转换流对象,构造方法传递字节的输出流
OutputStreamWriter osw = new OutputStreamWriter(output, "gbk");
// 写入字符串
osw.write("你好啊");
// 刷新流
osw.flush();
// 资源释放
osw.close();
System.out.println("写入完成");
}
// 字符读取流
public static void fn2() throws IOException {
// 创建字节流输入对象
FileInputStream input = new FileInputStream("E:\\java\\day3\\1.txt");
// 创建字符流对象,绑定字节输入流,指定编码
InputStreamReader isr = new InputStreamReader(input);
// 查询当前文件字节数,创建一个大小相同的数组
File file = new File("E:\\java\\day3\\1.txt");
int count = (int) file.length();
char[] chars = new char[count];
// 保存read的返回值
int r = 0;
r = isr.read(chars);
// 数组转为字符串
System.out.println(new String(chars, 0, r));
isr.close();
System.out.println("读取成功");
}
// 便携类 输出
public static void fn3() throws IOException {
/*
* FileWrite继承OutputStreamWrite
* 是字符的输出流,写入文本文件
* 采取默认的编码表
* FileWrite构造方法直接传递字符串的文件名即可*/
FileWriter fw = new FileWriter("E:\\java\\day3\\fw.txt");
// 写入字符串就完事
fw.write("你好吗");
fw.close();
}
// 便携类 读取
public static void fn4() throws IOException {
/*
* FileReader继承InputStreamRead
* 是字符的输入流,读取文本文件
* 采取默认的编码表
* FileReader构造方法直接传递字符串的文件名即可*/
FileReader fw = new FileReader("E:\\java\\day3\\fw.txt");
File file = new File("E:\\java\\day3\\fw.txt");
char[] chars = new char[(int) file.length()];
int r = 0;
while ((r = fw.read(chars)) != -1) {
System.out.println(new String(chars, 0, r));
}
System.out.println("读取完成");
fw.close();
}
// 缓冲流 输出
public static void fn5() throws IOException {
/*BufferedWriter : 字符流的缓冲流,继承Writer,写入文本文件
特殊的方法 : newLine() 写入文本换行符,平台无关性
构造方法: BufferedWriter(Writer w)可以传递任意字符输出流*/
FileWriter fw = new FileWriter("E:\\java\\day3\\2.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("第一行");
bw.newLine();
bw.write("第二行");
bw.close();
System.out.println("写入成功");
}
// 缓冲流 读取
public static void fn6() throws IOException {
/*BufferedReader : 字符流的缓冲流,继承Reader,读取文本文件
特殊的方法 :String readLine() 读取文本一行,平台无关性
构造方法: BufferedReader (Reader r)可以传递任意字符输入流*/
FileReader fr = new FileReader("E:\\java\\day3\\2.txt");
File file = new File("E:\\java\\day3\\2.txt");
char[] chars = new char[(int) file.length()];
BufferedReader br = new BufferedReader(fr);
/* String str = null;
while ((str = br.readLine()) != null) { //按行来读取
System.out.println(str);
}*/
int r = 0;
while ((r = br.read(chars)) != -1) {
System.out.println(new String(chars, 0, r)); // 全部读取
}
br.close();
}
}
2.7 IO流 打印流
public class IOTestPrint {
public static void main(String[] args) throws IOException {
/*
* 打印流
* PrintStream:字节输出流
* PrintWriter:字符输出流
* 打印流特性:
* 打印流负责输出打印,不关心数据源
* 方便的打印各种形式数据
* 打印流永远不会抛出IOException异常
* 具有自动刷新*/
fn1();
}
public static void fn1() throws IOException {
/*
* 打印流输出,在打印流的构造方法中,传递流(字节,字符)
* 自动刷新:构造方法中第一个参数必须是IO流对象,不能是字符串,第二个方法为true 意思是自动刷新
* 调用方法:printf,println,format 三个其中一个,启用自动刷新*/
FileWriter fw = new FileWriter("E:\\java\\day3\\1.txt");
PrintWriter pw = new PrintWriter(fw, true);
pw.println(1.5);
pw.close();
}
}