一BigDecimal/BigInteger
--1,BigDecimal专门用来解决小数运算不精确的解决方案
--2,BigInteger专门用来处理超大整数运算的解决方案
--3,BigDecimal创建对象
BigDecimal(double val) -- 有坑
BigDecimal(String val) -- 提倡
--4,常用方法
BigDecimal add(BigDecimal augend) --加法运算
BigDecimal subtract(BigDecimal subtrahend) --减法运算
BigDecimal multiply(BigDecimal multiplicand) --乘法运算
BigDecimal divide(BigDecimal divisor) --除法运算
--5,测试
package cn.tedu.api;
import java.math.BigDecimal;
import java.util.Scanner;
//测试 小数运算精确的解决方案
public class Test3_BigDecimal {
public static void main(String[] args) {
// method() ;//暴露问题
method2() ;//解决浮点数运算不精确
}
private static void method2() {
//接收用户输入的两个小数 ,并做 +-*/ 运算
double a = new Scanner(System.in).nextDouble() ;
double b = new Scanner(System.in).nextDouble() ;
//1,创建BigDecimal对象
// BigDecimal(double val) -- 有坑,更不精确了!!!!
// BigDecimal bd1 = new BigDecimal(a);
// BigDecimal bd2 = new BigDecimal(b);
// BigDecimal(String val) -- 提倡 -- 把a b转成String类型
BigDecimal bd1 = new BigDecimal(a+"");
BigDecimal bd2 = new BigDecimal(b+"");
BigDecimal bd3 = bd1.add(bd2);//加法运算
System.out.println(bd3);
bd3 = bd1.subtract(bd2);//减法运算
System.out.println(bd3);
bd3 = bd1.multiply(bd2);//乘法运算
System.out.println(bd3);
//除法运算时,如果发生了除不尽的现象,直接抛出异常:java.lang.ArithmeticException:
//Non-terminating decimal expansion; no exact representable decimal result.
// bd3 = bd1.divide(bd2);//除法运算
//divide(a,b,c);-a是要做除法运算的对象-b是保留的小数位数-c是舍入方式
bd3 = bd1.divide(bd2,5,BigDecimal.ROUND_HALF_UP);//除法运算
System.out.println(bd3);
}
//暴露问题
public static void method() {
//接收用户输入的两个小数 ,并做 +-*/ 运算
double a = new Scanner(System.in).nextDouble() ;
double b = new Scanner(System.in).nextDouble() ;
System.out.println(a+b);//不精确
System.out.println(a-b);//不精确
System.out.println(a*b);//不精确
System.out.println(a/b);//不精确
}
}
二.File类
--1,文件和目录路径名的抽象表示形式。
--2,创建对象
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
package cn.tedu.io;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
//测试 File类
public class Test4_File {
public static void main(String[] args) throws IOException {
//1,创建对象--封装文件或者文件夹的路径
File file = new File("D:\\iotest\\1.txt");
//2,常用方法
System.out.println( file.length() );//求字节量
System.out.println( file.exists() );//判断文件是否存在
System.out.println( file.isFile() );//判断是否是一个文件
System.out.println( file.isDirectory() );//判断是否是一个文件夹
System.out.println( file.getName() );//获取文件名
System.out.println( file.getParent() );//获取父路径
System.out.println( file.getAbsolutePath() );//获取完整路径
System.out.println( file.createNewFile() );//创建一个不存在的文件
file = new File("D:\\iotest\\abc");
System.out.println( file.mkdir() );//新建一个不存在的文件夹
//
// file = new File("D:\\iotest\\abc\\x\\y\\z");
// System.out.println( file.mkdirs() );//新建多个不存在的文件夹
//
// file = new File("D:\\iotest\\222.txt");
// System.out.println( file.delete() );//删除文件 或者 空的文件夹
//列出文件夹里的资源
file = new File("D:\\iotest");//指定文件夹路径
String[] strs = file.list();//获取文件名 并存入String[]
// [1.txt, abc]
System.out.println(Arrays.toString(strs));
File[] files = file.listFiles();//获取文件 并存入File[]
// [D:\iotest\1.txt, D:\iotest\abc]
System.out.println(Arrays.toString(files));
//TODO 接收用户输入的一串路径
String path = new Scanner(System.in).nextLine();
File f = new File(path);
//判断如果是文件,求文件的字节量
if(f.isFile()) {//如果是文件,返回true
System.out.println( f.length() );
}else if(f.isDirectory()) {//如果是文件夹,返回true
File[] fs = f.listFiles();//判断如果是文件夹,列出所有资源
System.out.println(Arrays.toString(fs));
}
}
}
三.字节流-- 对所有二进制文件都可以进行读写操作,更加常用!
--读取 : 指把磁盘中的数据 读取 到程序中.in
--写出 : 指把程序中准备好的数据 写出 到磁盘中.out
四字节读取流
--InputStream -- 字节读取流的 抽象 父类 -- 不能new,我们只能学习他的共性方法
--常用方法
void close()
关闭此输入流并释放与该流关联的所有系统资源。
abstract int read()
从输入流中读取数据的下一个字节。
int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
--FileInputStream -- 学习子类创建对象
--FileInputStream 从文件系统中的某个文件中获得输入字节。
--创建对象
FileInputStream(String pathname)
FileInputStream(File file)
--BufferedInputStream -- 学习子类创建对象
--BufferedInputStream 为另一个输入流添加一些功能,会创建一个内部缓冲区数组。
--创建对象
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream(InputStream in, int size)
创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in, 以便将来使用。
--测试
package cn.tedu.io;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
//测试 字节读取流
//FileInputStream BufferedInputStream都可以用来读取
//效率上来讲: BufferedInputStream > FileInputStream
//原因是:FileInputStream 是一个一个字节的读取
//BufferedInputStream是一个数组一个数组的读取/缓冲流/高级流
//本质上,底层就是维护了一个byte[]数组叫 buf,用来缓冲数据,默认大小是8192,8*1024字节=8K数据.
//把数组里的数据一次性的给程序读取进来.减少了程序冲流里获取数据的次数,提高了效率
public class Test1_InputStream {
public static void main(String[] args) throws IOException {
// FIS();//FileInputStream读取流
BIS();//BufferedInputStream读取流
}
//BufferedInputStream读取流
private static void BIS() throws IOException {
//1,创建对象
InputStream in = new BufferedInputStream( new FileInputStream("D:\\iotest\\1.txt") );
//2,开始读取
int b = 0 ;//定义变量,记录read()返回的值
while( ( b = in.read() ) != -1) {
System.out.println(b);
}
//3,释放资源
in.close();
}
//FileInputStream读取流
public static void FIS() throws IOException {
//1,创建多态对象 -- 读取指定位置的文件
//触发了FileInputStream的String类型参数的构造方法
InputStream in = new FileInputStream("D:\\iotest\\1.txt");
//触发了FileInputStream的File类型参数的构造方法
// File file = new File("D:\\iotest\\1.txt");
// InputStream in2 = new FileInputStream(file);
InputStream in2 = new FileInputStream( new File("D:\\iotest\\1.txt") );
//2,开始读取
// int b = in.read() ;//读取方法返回值是整数
// System.out.println( b );//a->97
// System.out.println( in.read() );//98
// System.out.println( in.read() );//99
// //--问题1:如果没数据了,还能读吗?--可以读,永远返回-1!!
// System.out.println( in.read() );//-1
// System.out.println( in.read() );//-1
//---改造,重复执行read()
int b = 0 ;//b记录读取到的数据
while( ( b = in.read() ) != -1) {//-1代表没数据可读了
System.out.println(b);//打印读取到的数据
}
//3,释放资源
in.close();
in2.close();
}
}
五.字节写出流
--OutputStream--字节写出流的父类,被修饰成立一个抽象类,不能new只能学习共性方法
--常用方法
void close()
关闭此输出流并释放与此流有关的所有系统资源。
void flush()
刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b)
将指定的字节写入此输出流。
--FileOutputStream--方法都是从父类继承来的,那就直接学习子类创建对象
--是用于将数据写出到文件中的输出流
--创建对象
FileOutputStream(String name)
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
--BufferedOutputStream--方法都是从父类继承来的,那就直接学习子类创建对象
--该类实现缓冲的输出流
--创建对象
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
测试--
package cn.tedu.io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//测试 字节写出流
//1,效率上来讲:BufferedOutputStream > FileOutputStream
//2,原因:
//FileOutputStream是一个一个字节向磁盘输出
//BufferedOutputStream是一个数组一个数组向磁盘输出/高级流/缓冲流
//本质上,底层维护了一个byte[] buf,用来缓冲数据.默认大小是8192,相当于8K
public class Test2_OutputStream {
public static void main(String[] args) throws IOException {
// FOS();//FileOutputStream写出流
BOS();//BufferedOutputStream写出流
}
//BufferedOutputStream写出流
private static void BOS() throws IOException {
//1,创建对象--把数据写出到指定文件中
//默认的数据覆盖模式
//OutputStream out = new BufferedOutputStream(
// new FileOutputStream("D:\\iotest\\1.txt"));
//TODO 数据追加模式
OutputStream out = new BufferedOutputStream(
new FileOutputStream("D:\\iotest\\1.txt",true));
//2,开始写出
out.write(49);
out.write(49);
out.write(49);
//3,释放资源
out.close();
}
//FileOutputStream写出流
private static void FOS() throws IOException {
//1,创建对象--指把数据写出到磁盘的哪个文件中去
//OutputStream out = new FileOutputStream("D:\\iotest\\1.txt");//默认就是数据覆盖模式
OutputStream out = new FileOutputStream("D:\\iotest\\1.txt",true);//数据追加模式
//OutputStream out2 = new FileOutputStream(new File("D:\\iotest\\1.txt"));
//2,开始写出
out.write(97);
out.write(98);
out.write(99);
//3,释放资源
out.close();
// out2.close();
}
}
六.字符流 -- 只能对字符文件txt进行读写操作
--读取 : 指把磁盘中的数据 读取 到程序中.in
--写出 : 指把程序中准备好的数据 写出 到磁盘中.out
七 .字符读取流
--Reader--用于读取字符流的抽象类,不能new只能学习共性方法
--常用方法
abstract void close()
关闭该流并释放与之关联的所有资源。
int read()
读取单个字符。
int read(char[] cbuf)
将字符读入数组。
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。
--FileReader--方法都是继承来的,我们重点学习创建对象
--用来读取字符文件的便捷类。
--创建对象
FileReader(String fileName)
FileReader(File file)
--BufferedReader--方法都是继承来的,我们重点学习创建对象
--从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以 指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
--创建对象
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
package cn.tedu.io;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
//测试 字符读取流
//效率上谁快:BufferedReader > FileReader
//原因:
//FileReader 是一个一个字符的读取
//BufferedReader 是一个数组一个数组的读取
//本质上,就是因为底层维护了一个char[] cb,用来缓冲数据,默认大小是8192相当于8K
public class Test3_Reader {
public static void main(String[] args) throws IOException {
// FR();//FileReader读取流
BR();//BufferedReader读取流
}
//BufferedReader读取流
private static void BR() throws IOException {
//1,创建对象
Reader in = new BufferedReader(new FileReader("D:\\iotest\\1.txt"));
//2,开始读取
int b = 0 ;
while( ( b=in.read() ) != -1) {
System.out.println(b);
}
//3,释放资源
in.close();
}
//FileReader读取流
public static void FR() throws IOException {
//1,创建对象
Reader in = new FileReader("D:\\iotest\\1.txt");//触发了String参数的构造
// Reader in = new FileReader( new File("D:\\iotest\\1.txt") );//触发了File参数的构造
//2,开始读取
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// //问题1:没数据也可以继续读取,不会抛出异常,只不过永远返回-1
// System.out.println( in.read() );
// System.out.println( in.read() );
//TODO --改造
int b = 0 ;//定义变量,记录读取到的数据
while( ( b=in.read() ) != -1) {//只要有数据就一直读,如果是-1就代表没数据了
System.out.println(b);
}
//3,释放资源
in.close();
}
}
八.字符写出流
--Writer--字符流写出流的父类,被修饰为了抽象类.不能new,只能学习共性方法
--常用方法
abstract void close()
关闭此流,但要先刷新它。
abstract void flush()
刷新该流的缓冲。
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str)
写入字符串。
void write(String str, int off, int len)
写入字符串的某一部分。
--FileWriter--子类继承了父类的所有方法,重点学习子类创建对象
--用来写入字符文件的便捷类。
--创建对象
FileWriter(File file)
FileWriter(String fileName)
FileWriter(File file, boolean append)
FileWriter(String fileName, boolean append)
--BufferedWriter子类
--将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区 的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
--创建对象
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
--测试
package cn.tedu.io;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
//测试 字符写出流
public class Test4_Writer {
public static void main(String[] args) throws IOException {
// FW();//FileWriter写出流
BW();//TODO BufferedWriter写出流
}
//BufferedWriter写出流
private static void BW() {
Writer out = null;
try {
//1,创建对象
out = new BufferedWriter( new FileWriter("D:\\iotest\\1.txt") ) ;
//2,开始写出
out.write("今天电影院开业,你准备好了吗?");
} catch (IOException e) {
e.printStackTrace();
} finally{//finally语句块,就是保证无论会不会出现异常,都一定要执行的代码
//3,释放资源--必须保证一定会执行!
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//FileWriter写出流
private static void FW() throws IOException {
//1,创建对象
// Writer out = new FileWriter("D:\\iotest\\1.txt");//默认就是数据覆盖模式
Writer out = new FileWriter("D:\\iotest\\1.txt",true);//数据追加模式
// Writer out = new FileWriter( new File("D:\\iotest\\1.txt") );
//2,开始写出
out.write(97);
out.write(97);
out.write(97);
out.write("大家好,我叫皮皮虾!!!");
//3,释放资源
out.close();
}
}
--IO练习:
--需求:完成文件复制的练习,把A文件中的数据,复制到B文件中去
--工具类代码:
package cn.tedu.io;
import java.io.Closeable;
import java.io.IOException;
public class IOUtils {
//参数最好能够通用,也就是是说,
//最好能够把所有的字节流字符流高级流普通流都释放掉--多态Closeable.close()
public static void close(Closeable c) {
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
--测试代码:
package cn.tedu.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
//测试 文件复制
//1,读取源文件的数据
//2,把数据写出到目标文件里去
public class Test1_Copy {
public static void main(String[] args) {
//1,接收键盘输入的源文件路径
String frompath = new Scanner(System.in).nextLine();
File from = new File(frompath);
//2,接收键盘输入的目标文件路径
String topath = new Scanner(System.in).nextLine();
File to = new File(topath);
//3,调用复制方法
copy(from,to);
}
//针对释放资源时的优化方式2:jdk1.7对于IO自动资源管理的优化--try with resource
private static void copy3(File from, File to) {
try (
//0,创建读取流和写出流--字节流/高级流/普通流/字符流
InputStream in = new BufferedInputStream( new FileInputStream(from) );
OutputStream out = new BufferedOutputStream( new FileOutputStream(to) );
)
{
//1,读取源文件的数据
int b = 0 ;//定义变量,记录读到的数据
while( ( b = in.read() ) != -1) {
//2,把数据写出到目标文件里去
out.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//针对释放资源时的优化方式1:提供工具类
private static void copy2(File from, File to) {
InputStream in = null;
OutputStream out = null;
try {
//0,创建读取流和写出流--字节流/高级流/普通流/字符流
in = new BufferedInputStream( new FileInputStream(from) );
out = new BufferedOutputStream( new FileOutputStream(to) );
//1,读取源文件的数据
int b = 0 ;//定义变量,记录读到的数据
while( ( b = in.read() ) != -1) {
//2,把数据写出到目标文件里去
out.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//3,释放资源--保证一定会被执行,放入finally块里
IOUtils.close(in);
IOUtils.close(out);
}
}
//复制方法
private static void copy(File from, File to) {
InputStream in = null;
OutputStream out = null;
try {
//0,创建读取流和写出流--字节流/高级流/普通流/字符流
in = new BufferedInputStream( new FileInputStream(from) );
out = new BufferedOutputStream( new FileOutputStream(to) );
//1,读取源文件的数据
int b = 0 ;//定义变量,记录读到的数据
while( ( b = in.read() ) != -1) {
//2,把数据写出到目标文件里去
out.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//3,释放资源--保证一定会被执行,放入finally块里
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}