异常:
JVM默认处理异常的方式
1: 如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:
2: 把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
3: 程序停止执行
try-catch方式处理异常(应用)
/*
演示如何自己处理异常.
自己处理异常的方式:
方式1: try.catch.finally 捕获异常.
格式:
try {
//这里写的可能出现问题的代码
} catch(异常的数据类型 对象名) {
对象名.printStackTrace(); //该方法会将: 异常的类型, 出现的原因, 及异常出现的位置打印到控制台上.
} finally {
正常情况下, 这里的代码永远会执行, 一般是用来 释放资源的.
即: 不管代码走了try, 还是走了catch, 最终都会执行这里的内容.
}
特点:
处理完异常之后, 程序会继续执行.
方式2: 声明抛出异常.
*/
public class Demo03 {
public static void main(String[] args) {
String str = "2020/11/10";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
try {
Date date = sdf.parse(str); //编译期异常.
System.out.println("我是: try");
} catch(Exception e) {
e.printStackTrace(); //该方法会将: 异常的类型, 出现的原因, 及异常出现的位置打印到控制台上.
System.out.println("我是: catch");
} finally {
System.out.println("我是finally, 我是用来 释放资源的!");
}
System.out.println("看看我执行了吗?"); //快捷键: Ctrl + alt + 字母T
}
}
声明抛出异常
•格式
throws 异常的类型; //该内容是写到方法的形参列表之前的.
特点: 处理完后, 程序会终止执行.
File类
/**
*
* 案例: File类的构造方法演示.
* File类简介:
* 概述:
* 它是java.io包下的类, 用来表示 文件(夹)的, 文件夹也叫 目录.
* 确切的说, 它是用来描述 路径的, 只要 路径是合法的路径即可, 它对应的文件存在与否没关系. 我们都可以把它创建出来.
* 构造方法:
* File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
* File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例
* File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
*
* 既然上述的三种构造方法创建的File对象都是相同的, 为啥要提供如此的多的创建对象的方式呢?
* 就是为了满足用户 灵活多变 的需求.
*/
// 向左一个 "/"杠 向右 "\\"两个斜杠 区分\r\t \n
public class FileDemo01 {
public static void main(String[] args) {
//file的构造方法演示
File f1 = new File("D:\\soft\\aaa\\java.txt");
System.out.println(f1); //D:\soft\aaa\java.txt
File f2 = new File("D:\\soft\\aaa", "java.txt");
System.out.println(f2); //D:\soft\aaa\java.txt
File f3 = new File("D:\\soft\\aaa");
File f4 = new File(f3, "java.txt");
System.out.println(f4); //D:\soft\aaa\java.txt
}
}
file类的成员方法之创建功能:
/**
案例: 演示File类的 创建功能.
涉及到的File类中的成员方法:
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir() 创建由此抽象路径名命名的目录, make directory 制造文件夹
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
*/
public class FileDemo02 {
public static void main(String[] args) throws IOException {
//在 D:\soft\aaa 目录下创建java.txt文件
File f1 = new File("D:\\soft\\aaa\\java.txt"); //首次创建都返回True
System.out.println(f1.createNewFile());
System.out.println("------------------------------------------");
//在D:\soft\aaa 目录下创建 bbb 目录
File f2 = new File("D:\\soft\\aaa\\bbb");
System.out.println(f2.mkdir());
System.out.println("------------------------------");
//在D:\soft\aaa目录下创建 bbb\ccc目录 多层级
File f3 = new File("D:\\soft\\aaa\\bbb\\ccc"); //父目录必须存在 不然创建不成功
System.out.println(f3.mkdirs());
}
}
file类的成员方法之判断功能:
/**
案例: 演示File的判断功能.
涉及到的File类中的成员方法:
public boolean exists() 测试此抽象路径名表示的File是否存在
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
*/
public class FileDemo03 {
public static void main(String[] args) {
// public boolean exists() 测试此抽象路径名表示的File是否存在
File f1 = new File("D:\\soft\\aaa\\bbb");
System.out.println(f1.exists()); // 存在true 反之 false
// public boolean isFile() 测试此抽象路径名表示的File是否为文件
System.out.println(f1.isFile()); //isFile()必须是 存在的文件才会返回true, 否则false
// public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
System.out.println(f1.isDirectory());
}
}
file类的成员方法之获取功能:
/**
* 案例: 演示File类的获取功能.
* 涉及到的File类的成员方法:
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或目录的名称
public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组
绝对路径 和 相对路径的区别是什么?
绝对路径: 固定的, 写"死"的路径, 以盘符开头.
例如: d:/abc/1.txt
相对路径: 一般是相对于当前的项目路径而言的.
例如: 你写了 1.txt, 程序会自动识别为: 项目路径 + 1.txt.
示例: 1.txt -> D:\ClassDemo\workspace1024\JavaSE\1.txt
* */
public class FileDemo04 {
public static void main(String[] args) {
File f1 = new File("D:\\IdeaProjects\\javase_afu\\day08_bigdata\\data\\a.txt");
File f2 = new File("data/a.txt");
// public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
System.out.println(f1.getAbsolutePath()); //D:\IdeaProjects\javase_afu\day08_bigdata\data\a.txt
System.out.println(f2.getAbsolutePath()); //D:\IdeaProjects\javase_afu\data\a.txt
//测试: public String getPath() 获取路径, 以什么形式创建, 就获取什么路径, 一般用于获取相对路径.
System.out.println(f1.getPath()); //D:\IdeaProjects\javase_afu\day08_bigdata\data\a.txt
System.out.println(f2.getPath()); //data\a.txt
//测试: public String getName() 返回由此抽象路径名表示的文件或目录的名称
System.out.println(f1.getName()); //a.txt
System.out.println(f2.getName()); //a.txt
//测试: public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
//需求: 获取D:\soft\aaa 下所有的 文件(夹)的 名称数组.
File f3 = new File("D:\\soft\\aaa");
String[] list = f3.list();
for (String s : list) {
System.out.println(s); // bbb java.txt
}
//测试: public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组
File[] files = f3.listFiles();
for (File f : files) {
System.out.println(f); //file对象: D:\soft\aaa\bbb
}
}
}
file类的成员方法之删除功能:
/**
* 案例: 演示File类的 删除功能.
*
* 涉及到的成员方法:
* public boolean delete(); 删除指定的文件(夹)
*
* 细节:
* 1. 要删除的文件夹必须是空文件夹.
* 2. Java中的删除, 不走回收站.
*/
public class FileDemo05 {
public static void main(String[] args) {
//删除文件夹
File f1 = new File("D:\\soft\\aaa\\bbb");
System.out.println(f1.delete());
//删除文件
File f2 = new File("D:\\soft\\aaa\\java.txt");
System.out.println(f2.delete());
}
}
IO流
IO流概述和分类【理解】
-
IO流介绍
- IO:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
- IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载
-
IO流的分类
-
按照数据的流向
- 输入流:读数据
- 输出流:写数据
-
按照数据类型来分
- 字节流
- 字节输入流
- 字节输出流
- 字符流
- 字符输入流
- 字符输出流
- 字节流
-
IO流的使用场景
- 如果操作的是纯文本文件,优先使用字符流(记事本打开可以看懂)
- 如果操作的是图片、视频、音频等二进制文件(记事本打开乱码或者看不懂)。优先使用字节流
- 如果不确定文件类型,优先使用字节流。字节流是万能的流
字节流写数据的三种方式【应用】
-
写数据的成员方法分类
方法名 说明 void write(int b) 将指定的字节写入此文件输出流 一次写一个字节数据 void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据
FileOutputStream类简介:
构造方法:
public FileOutputStream(String path); 创建基本的字节输出流对象, 关联目的地文件, String形式.
public FileOutputStream(File path); 创建基本的字节输出流对象, 关联目的地文件, File对象形式.
public class FileOutputDemo02 {
public static void main(String[] args) throws Exception{
//1.创建字节输出流对象 FileOutputStream
FileOutputStream fos = new FileOutputStream("day08_bigdata\\data\\b.txt");
/*
做了三件事情:
A:调用系统功能创建了文件
B:创建了字节输出流对象
C:让字节输出流对象指向创建好的文件
*/
//一次写一个字节
// fos.write(97); //a
//2.一次写一个字节数组
byte[] by = {97,98,99,100,101,102}; //abcdef
fos.write(by);
//3.一次写一个字节数组的一部分
fos.write(by,2,3); //在2的基础上最佳cde
//最后不要忘记释放资源
//void close():关闭此文件输出流并释放与此流相关联的任何系统资源。
fos.close();
}
}
节流写数据的两个小问题【应用】
- 字节流写数据如何实现换行
- windows:\r\n
- linux:\n
- mac:\r
- 字节流写数据如何实现追加写入
- public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
public class FileOutputDemo03 {
public static void main(String[] args) throws Exception{
//1.创建字节输出流对象 关联目的地文件
// FileOutputStream fos = new FileOutputStream("day08_bigdata\\data\\a.txt");
FileOutputStream fos = new FileOutputStream("day08_bigdata\\data\\a.txt",true); //末尾加true实现追加写入
for (int i = 1; i <= 10; i++) {
fos.write("\r\n".getBytes()); //实现换行 //String#getBytes方法 字符创转为字节数组
fos.write("HelloBigdata".getBytes());
}
//释放资源 不忘忘记
fos.close();
}
}
字节流读数据(一次读一个字节数据)
- 字节输入流
- FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream ,该文件由文件系统中的路径名name命名
- 字节输入流读取数据的步骤
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
public class FileOutputDemo04 {
public static void main(String[] args) throws Exception{
//1.创建字节输入流对象
FileInputStream fis = new FileInputStream("day08_bigdata\\data\\a.txt");
int len;
/*
fis.read():读数据
by=fis.read():把读取到的数据赋值给by
by != -1:判断读取到的数据是否是-1
*/
while ((len=fis.read())!=-1){ //为 -1说明读到了最后一个
System.out.print((char)len); //字节强转成字符
}
//最后释放资源
fis.close();
}
}
字节流读数据(一次读一个字节数组数据)
/**
* 复制图片案例
*/
public class FileInputDemo02 {
public static void main(String[] args) throws Exception {
//1.根据数据源创建字节输入流对象 读取图片
FileInputStream fis = new FileInputStream("D:\\soft\\aaa\\mn.jpg");
//2.创根据目的地创建字节输出流对象 写取图片
FileOutputStream fos = new FileOutputStream("day08_bigdata\\data\\mn.jpg");
//定义字节数组
byte[] by = new byte[1024]; // 必须是1024的整数倍
int len;
while ((len = fis.read(by))!=-1){
fos.write(by,0,len);
}
//释放资源 先开后放
fos.close();
fis.close();
}
}
IO流中必须掌握的几种读写数据的方法
第1种:普通字节流一次读取有一个字节数组
public class FileInputDemo02 {
public static void main(String[] args) throws Exception {
//1.根据数据源创建字节输入流对象 读取图片
FileInputStream fis = new FileInputStream("D:\\soft\\aaa\\mn.jpg");
//2.创根据目的地创建字节输出流对象 写取图片
FileOutputStream fos = new FileOutputStream("day08_bigdata\\data\\mn.jpg");
//定义字节数组
byte[] by = new byte[1024]; // 必须是1024的整数倍
int len;
while ((len = fis.read(by))!=-1){
fos.write(by,0,len);
}
//释放资源 先开后放
fos.close();
fis.close();
}
}
第2种:高效的字节流(也叫缓冲流)一次读写一个字节
public class TestDemo02 {
public static void main(String[] args) throws Exception{
//1.创建高效字流对象 关联数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("homework\\data\\a.txt"));
//2.创建高效流字节输出对象 写出数据
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("homework/data/b.txt"));
//一次读取一个字节 掌握
int len;
while ((len = bis.read()) !=-1){
bos.write(len);
}
//一次读取一个字节数组
/* byte[] by = new byte[8192];
int len;
while ((len = bis.read(by)) !=-1){
bos.write(by,0,len);
}*/
//关闭资源
bos.close();
bis.close();
}
}
这里值得注意的是:
为什么构造方法传递的是一个: OutputStream(或者InputStream), 而不
是具体的文件或者路径呢?
答案: 字节缓冲流仅仅提供缓冲区, 而真正的底层的读写数据还是需要基
本的流对象进行操作.
第3种:高效的字符流一次读写一行.
/**
* 10. 高效的字符流一次读写一个字符数组.
* 11. 高效的字符流一次读写一行. //必须, 必须, 必须掌握.
*/
public class TestDemo06 {
public static void main(String[] args) throws Exception {
// method01();
/**
* * 11. 高效的字符流一次读写一行. //必须, 必须, 必须掌握.
*
* 案例: 演示字符高效流独有的拷贝文件的方式.
* 涉及到的成员方法:
* BufferedReader:
* public String readLine(); 一次读取一行数据, 并返回读取到的内容, 读不到返回null
* BufferedWriter:
* public void newLine(); 根据当前操作系统, 给出对应的换行符.
* window: \r\n, Linux: \n, Mac: \r
*/
//1.创建高效的字符流对象 读取数据 一次一行
BufferedReader br = new BufferedReader(new FileReader("homework/data/a.txt"));
//2. 创建高效的字符流对象 写入数据
BufferedWriter bw = new BufferedWriter(new FileWriter("homework/data/b.txt"));
//3.一次读取一行
String line;
while ((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
}
//4.最后不要忘记释放资源
bw.close();
br.close();
}
public static void method01() throws IOException {
//1.创建高效字符流读取对象 关联数据源
BufferedReader br = new BufferedReader(new FileReader("homework/data/a.txt"));
//2.创建高效字符写入流 写去数据
BufferedWriter bw = new BufferedWriter(new FileWriter("homework/data/b.txt"));
//3.一次去读一个字符
//3.1 先创建一个字符数组
char[] ch = new char[1024];
// 定义变量, 记录读取到的数据(字节, 字符, 有效字节数, 有效字符数, 字符串)
int len;
while ((len = br.read()) != -1) {
bw.write(len);
}
//4.最后不要忘记关闭资源
bw.close();
br.close();
}
}
转换流
package com.itcast.day12homework;
/**
* 需求:
* 1.通过转换流, 将项目下data文件夹中1.txt文件的内容, 拷贝到data文件夹下2.txt文件中.
* 2.运行, 并查看返回值结果.
* <p>
* 转换流简介:
* 概述:
* 所谓的字符流 = 字节流 + 编码表, 而转换流做的事儿就是根据编码表把字节流转成字符流.
* 转换流分别是: InputStreamReader 和 OutputStreamWriter, 前者是转换输入流, 后者是转换输出流.
* 构造方法:
* InputStreamReader: 转换输入流
* public InputStreamReader(InputStream is) 采用默认码表, 把字节流封装成字符流对象.
* public InputStreamReader(InputStream is, String charsetName) 采用指定码表, 把字节流封装成字符流对象.
* OutputStreamWriter: 转换输出流
* public OutputStreamWriter(OutputStream os); 采用默认码表, 把字节流封装成字符流对象.
* public OutputStreamWriter(OutputStream os, String charsetName); 采用指定码表, 把字节流封装成字符流对象.
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 5. 转换流一次读取一个字符.
* 6. 转换流一次读取一个字符数组.
*/
public class TestDemo05 {
public static void main(String[] args) throws Exception {
//字符流 = 字节流 + 编码表
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\IdeaProjects\\javase_afu\\homework\\data\\a.txt"), "utf-8");
//转换流 读取文件
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaProjects\\javase_afu\\homework\\data\\b.txt"), "utf-8");
//一次读取一个字符
/* int len;
while ((len=isr.read()) !=-1){
osw.write(len);
}*/
//一次读取一个字符数组
char[] ch = new char[1024];
int len;
while ((len = isr.read(ch)) != -1) {
osw.write(ch, 0, len);
}
//最后释放资源
osw.close();
isr.close();
}
}