小学数学练习
1.1【问题描述】
编写一个帮助小学生练习数学的程序,帮助小学生练习 100 以内的四种数学运算:加、减、乘、除。
1.2【基本要求】
a) 程序应先询问用户的 ID 号(ID 号包括两个大写字母和 4 位数字),例如:
请输入用户 ID 号:AB1234
程序应对输入的 ID 号验证,符合 ID 号要求的格式, 然后程序提示三种选择:
(1)开始测试
(2)检查分数
(3)退出
b) 测试:该程序将给出 10 道数学题,例如:
12 * 3 =36
48 + 32 =80
…
56 / 28 =2
注意:
i)学生将依次回答每一个问题(在等于号后面给出答案) ,然后给出下一道题。
ii)试题应包含四种数学运算:加、减、乘、除, 它们是随机产生的。 相邻的问题应该是不同的操作,
每个操作必须至少出现一次。 报告中应给出实现方法或算法。
iii)为每道题随机生成数字, 但必须确保参与运算的数字和结果都小于 100 且大于零的整数, 除法时
还要注意两个整数要能整除。 报告中应给出实现方法或算法。
iv)十道题做完后,记录学生完成这十道题所用的时间。
v)给每个学生一个分数。将该学生的 ID、成绩和使用时间保存到一个名为 record.txt 的文件中。
vi)在屏幕上输出以下信息:(3 列信息, 第 1 列是 b) 中的测试题, 蓝色部分)
问题 | 正确答案 | 你的答案
c) 成绩检查:从文件“record.txt” 中列出该学生的所有历史成绩(其他学生的不显示)。例如:
你以前的记录是:
AB1234 80 150 秒
AB1234 50 182 秒
AB1234 90 98 秒
1.3【模块划分】
// 主类
public class One{}
// 用户类
class User{}
// 功能类
class Fun{}
// 封装主类
public class One {
public static void main(String[] args) {
// 初始化界面
Fun fun = new Fun();
// 加载一位新的用户
User user = new User(fun.start());
// 用户进入界面
fun.index(user);
}
}
/**
* 封装用户类
*/
class User{
/**
* 用户ID
*/
private String id;
/**
* 用户成绩
*/
private int scores = 0;
/**
* 用户所用时间
*/
private int time = 0;
/**
* 用户做题数据
*/
private String data = "";
/**
* 初始化用户
*/
public User(String id){
this.id = id;
}
// 一堆堆get,set方法
.......
// 添加数据的方法
public void addData(String data){
this.data = this.data.concat(data);
}
}
class Fun{
/**
* 用户输入ID号模块
*/
public String start(){}
/**
* 首页
*/
public void index(User user){}
/**
* 保存成绩
*/
public void recordUser(User user) {}
/**
* 检查用户
*/
public void checkUser(User user){}
/**
* 随机出题
*/
public void test(User user){}
/**
* 加法
*/
public void add(User user){}
/**
* 减法
*/
public void delete(User user){}
/**
* 乘法
*/
public void multi(User user){}
/**
* 除法
*/
public void div(User user){}
/**
* 校验用户名
*/
public boolean verify(String id){}
/**
* 用户输入ID号模块
*/
public String start(){
System.out.print("请输入用户 ID 号");
Scanner sc = new Scanner(System.in);
String id = sc.next();
while (!verify(id)){
System.out.println("ID 号包括两个大写字母和 4 位数字,请重新输入用户ID");
id = sc.next();
}
return id;
}
/**
* 校验用户名
*/
public boolean verify(String id){
// 正则表达式
String format = "[A-Z]{2}[0-9]{4}";
return id.matches(format);
}
/**
* 加法
*/
public void add(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(0);
String ques = tar[0] + "+" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[2]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[2] + " | " + result + "--");
}
/**
* 减法
*/
public void delete(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(0);
String ques = tar[2] + "-" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[0]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[0] + " | " + result + "--");
}
/**
* 乘法
*/
public void multi(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(1);
String ques = tar[0] + "*" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[2]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[2] + " | " + result + "--");
}
/**
* 除法
*/
public void div(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(1);
String ques = tar[2] + "\\" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[0]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + + tar[0] + " | " + result + "--");
}
/**
* 数字生成工具
*/
public int[] randTil(int cal){
int[] tar = new int[3];
int num1 = (int)(Math.random()*99) + 1;
int num2 = (int)(Math.random()*99) + 1;
if(cal == 0){
tar[2] = Math.max(num1, num2);
if(num1 > num2){
tar[0] = tar[2] - num2;
tar[1] = num2;
}else {
tar[0] = num1;
tar[1] = tar[2] - num1;
}
}
if(cal == 1){
tar[0] = (int)(Math.random()*(100/num1-1)) + 1;
tar[1] = num1;
tar[2] = tar[0] * tar[1];
}
return tar;
}
/**
* 随机出题
*/
public void test(User user){
// 初始化用户答题数据
user.setData("");
// 创建储存题目分布数组
int[] num = new int[10];
// 上一次出现过的数字
int lastNum = -1;
// 先保证四种运算出现一次
for (int i = 0; i < 4; i++) {
lastNum = randNoRe(lastNum,0, 10);
num[lastNum] = i + 1;
}
lastNum = -1;
for(int i = 0; i < 10; i++){
if(num[i] == 0){
// 只填未填好的数字
num[i] = randNoRe(lastNum, 1, 4);
if(i < num.length - 1){
if(num[i] == num[i + 1]){
i--;
num[i] = 0;
continue;
}
}
}
lastNum = num[i];
}
for(int n : num){
switch (n){
case 1 : add(user); break;
case 2 : delete(user); break;
case 3 : multi(user); break;
case 4 : div(user); break;
default:break;
}
}
String[] datas = user.getData().split("--");
System.out.println("问题 | 正确答案 | 你的答案");
for (String data : datas) {
System.out.println(data);
}
System.out.println("本次得分:" + user.getScores());
}
/**
* 随机生成与上一次不同的数字组成的数组
* lastNum:上一个数字,a,b生成范围
*/
public int randNoRe(int lastNum, int a, int b){
int n = (int)(Math.random()*b + a);
while(lastNum == n) {
n = (int) (Math.random()*b + a);
}
return n;
}
/**
* 文件路径
*/
private static final String FILE_PATH = "E:\\record.txt";
/**
* 保存成绩
*/
public void recordUser(User user) {
FileWriter fileWriter = null;
try {
File file = new File(FILE_PATH);
// 判断文件是否存在
if (!file.isFile()) {
file.createNewFile();
}
// 追加文件
fileWriter = new FileWriter(file, true);
// 追加内容
fileWriter.append(user.getId()).append(" ").append(String.valueOf(user.getScores())).append(" ").append(String.valueOf(user.getTime())).append(" 秒-");
}catch (Exception e){
e.printStackTrace();
}finally {
if(fileWriter != null){
try {
// 刷新流对象中的缓冲中的数据
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 检查用户
*/
public void checkUser(User user){
String[] s1 = null;
FileReader fileReader = null;
try{
// 处理流读取
fileReader = new FileReader(new File(FILE_PATH));
BufferedReader bf = new BufferedReader(fileReader);
String s;
while ((s = bf.readLine()) != null){
s1 = s.split("-");
}
// 判断是否是新用户
boolean flag = true;
for(String str : s1){
if(str.substring(0,6).equals(user.getId())){
// 控制打印次数
if(flag){
System.out.println("你以前的记录是:");
flag = false;
}
System.out.println(str);
}
}
// 是新用户
if(flag){
System.out.println("新用户,欢迎你使用!");
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 首页
*/
public void index(User user){
// 列出用户历史成绩
checkUser(user);
boolean flag = true;
while (flag) {
System.out.println("(1)开始测试\n" +
"(2)检查分数\n" +
"(3)退出"
);
// 用户进行功能选择
Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();
switch (choice) {
case 1:
// 初始化用户成绩
user.setScores(0);
// 开始计时
long start = System.currentTimeMillis();
// 开始测试
test(user);
// 结束计时
long end = System.currentTimeMillis();
// 设置用户游戏时间
user.setTime((int) ((end - start) / 1000));
// 保存成绩
recordUser(user);
break;
case 2:
// 检查分数
checkUser(user);
break;
case 3:
flag = false;
System.out.println("退出成功");
break;
default:break;
}
}
}
1.4【算法思想】
关于如何生成10个数字(每个数字与前一个不同,每个数字至少出现过一次)
1.5【题解】
import java.io.*;
import java.util.Scanner;
/**
* @author xh
*/
public class One {
public static void main(String[] args) {
// 初始化界面
Fun fun = new Fun();
// 加载一位新的用户
User user = new User(fun.start());
// 用户进入界面
fun.index(user);
}
}
/**
* 用户类
*/
class User{
/**
* 用户ID
*/
private String id;
/**
* 用户成绩
*/
private int scores = 0;
/**
* 用户所用时间
*/
private int time = 0;
/**
* 用户做题数据
*/
private String data = "";
/**
* 初始化用户
*/
public User(String id){
this.id = id;
}
public String getId() {
return id;
}
public int getScores() {
return scores;
}
public void setScores(int scores) {
this.scores = scores;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public void addData(String data){
this.data = this.data.concat(data);
}
}
class Fun{
/**
* 文件路径
*/
private static final String FILE_PATH = "E:\\record.txt";
/**
* 用户输入ID号模块
*/
public String start(){
System.out.print("请输入用户 ID 号");
Scanner sc = new Scanner(System.in);
String id = sc.next();
while (!verify(id)){
System.out.println("ID 号包括两个大写字母和 4 位数字,请重新输入用户ID");
id = sc.next();
}
return id;
}
/**
* 首页
*/
public void index(User user){
// 列出用户历史成绩
checkUser(user);
boolean flag = true;
while (flag) {
System.out.println("(1)开始测试\n" +
"(2)检查分数\n" +
"(3)退出"
);
// 用户进行功能选择
Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();
switch (choice) {
case 1:
// 初始化用户成绩
user.setScores(0);
// 开始计时
long start = System.currentTimeMillis();
// 开始测试
test(user);
// 结束计时
long end = System.currentTimeMillis();
// 设置用户游戏时间
user.setTime((int) ((end - start) / 1000));
// 保存成绩
recordUser(user);
break;
case 2:
// 检查分数
checkUser(user);
break;
case 3:
flag = false;
System.out.println("退出成功");
break;
default:break;
}
}
}
/**
* 保存成绩
*/
public void recordUser(User user) {
FileWriter fileWriter = null;
try {
File file = new File(FILE_PATH);
// 判断文件是否存在
if (!file.isFile()) {
file.createNewFile();
}
// 追加文件
fileWriter = new FileWriter(file, true);
// 追加内容
fileWriter.append(user.getId()).append(" ").append(String.valueOf(user.getScores())).append(" ").append(String.valueOf(user.getTime())).append(" 秒-");
}catch (Exception e){
e.printStackTrace();
}finally {
if(fileWriter != null){
try {
// 刷新流对象中的缓冲中的数据
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 检查用户
*/
public void checkUser(User user){
String[] s1 = null;
FileReader fileReader = null;
try{
// 处理流读取
fileReader = new FileReader(new File(FILE_PATH));
BufferedReader bf = new BufferedReader(fileReader);
String s;
while ((s = bf.readLine()) != null){
s1 = s.split("-");
}
// 判断是否是新用户
boolean flag = true;
for(String str : s1){
if(str.substring(0,6).equals(user.getId())){
// 控制打印次数
if(flag){
System.out.println("你以前的记录是:");
flag = false;
}
System.out.println(str);
}
}
// 是新用户
if(flag){
System.out.println("新用户,欢迎你使用!");
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 随机出题
*/
public void test(User user){
// 初始化用户答题数据
user.setData("");
// 创建储存题目分布数组
int[] num = new int[10];
// 上一次出现过的数字
int lastNum = -1;
// 先保证四种运算出现一次
for (int i = 0; i < 4; i++) {
lastNum = randNoRe(lastNum,0, 10);
num[lastNum] = i + 1;
}
lastNum = -1;
for(int i = 0; i < 10; i++){
if(num[i] == 0){
// 只填未填好的数字
num[i] = randNoRe(lastNum, 1, 4);
if(i < num.length - 1){
if(num[i] == num[i + 1]){
i--;
num[i] = 0;
continue;
}
}
}
lastNum = num[i];
}
for(int n : num){
switch (n){
case 1 : add(user); break;
case 2 : delete(user); break;
case 3 : multi(user); break;
case 4 : div(user); break;
default:break;
}
}
String[] datas = user.getData().split("--");
System.out.println("问题 | 正确答案 | 你的答案");
for (String data : datas) {
System.out.println(data);
}
System.out.println("本次得分:" + user.getScores());
}
/**
* 随机生成与上一次不同的数字组成的数组
* lastNum:上一个数字,a,b生成范围
*/
public int randNoRe(int lastNum, int a, int b){
int n = (int)(Math.random()*b + a);
while(lastNum == n) {
n = (int) (Math.random()*b + a);
}
return n;
}
/**
* 数字生成工具
*/
public int[] randTil(int cal){
int[] tar = new int[3];
int num1 = (int)(Math.random()*99) + 1;
int num2 = (int)(Math.random()*99) + 1;
if(cal == 0){
tar[2] = Math.max(num1, num2);
if(num1 > num2){
tar[0] = tar[2] - num2;
tar[1] = num2;
}else {
tar[0] = num1;
tar[1] = tar[2] - num1;
}
}
if(cal == 1){
tar[0] = (int)(Math.random()*(100/num1-1)) + 1;
tar[1] = num1;
tar[2] = tar[0] * tar[1];
}
return tar;
}
/**
* 加法
*/
public void add(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(0);
String ques = tar[0] + "+" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[2]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[2] + " | " + result + "--");
}
/**
* 减法
*/
public void delete(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(0);
String ques = tar[2] + "-" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[0]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[0] + " | " + result + "--");
}
/**
* 乘法
*/
public void multi(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(1);
String ques = tar[0] + "*" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[2]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + tar[2] + " | " + result + "--");
}
/**
* 除法
*/
public void div(User user){
Scanner sc = new Scanner(System.in);
int[] tar = randTil(1);
String ques = tar[2] + "\\" + tar[1] + "=";
System.out.print(ques);
int result = sc.nextInt();
if(result == tar[0]){
user.setScores(user.getScores() + 10);
}
user.addData(ques + "|" + + tar[0] + " | " + result + "--");
}
/**
* 校验用户名
*/
public boolean verify(String id){
String format = "[A-Z]{2}[0-9]{4}";
return id.matches(format);
}
}
知识总结
一、文件
问题引入:如何判断输入、输出?
参照物:Java程序
输出:程序→文件
把内存中的数据储存到持久化设备
,这个动作称为输出 Output
,写
输入:文件→程序
把持久设备上的数据读取到内存中
,这个动作称为输入 Input
,读
Java中把文件或者目录(文件夹)都封装成File对象,如果我们要去操作硬盘上的文件,或者文件夹只要找到File这个类,调用它的功能操作文件或者文件夹
1.File类的构造函数
String pathName = "e:\\hello.java";
File f1 = new File(pathName);
File f2 = new File("e:\\","hello.java");
File dir = new File("e:\\");
File f3 = new File(dir,"hello.java");
2.File类的获取
3.文件和文件夹的创建删除等
4.listFiles()方法介绍
File[] files = dir.listFiles();
for(File file : files){
System.out.println(file);
}
注意:
1、指定的目录必须是存在
2、指定的必须是目录
。否则容易引发返回数组为null,出现NullPointerException
二、流
关键字
input 输入 output 输出 stream 流 writer 字符输入流 reader 字符输入流 File 文件
只要会了字节流就都会了
字节流能处理一切
有诗曰:输入还是输出?字符还是字节?
流的分类表
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream |
转换流能都将字符流转成字节流
1.字节流
1.1、字节输出流OutputStream
输出流中定义都是写write方法
1.11、FileOutputStream类
给文件续写、换行
File file = new File("c:\\file.txt");
// 第二个参数 传入true
FileOutputStream fos = new FileOutputStream(file, true);
String str = "\r\n" +"换行内容";
fos.write(str.getBytes());
1.2、字节输入流InputStream
1.21、读写数据read(byte[])方法
FileOutputStream fos = new FileOutputStream(destFile);
// 缓冲区,临时数组容器
byte[] buf = new byte[1024];//长度定义成1024的整数倍
int len = 0;
while((len=fis.read(buf))!=-1){
System.out.println(new String(buf,0,len));
// 将数组中的指定长度的数据写入到输出流中。
fos.write(buf, 0, len);
}
// 关闭资源。
fos.close();
2、字符流
2.1.字符编码表
编码表:其实就是生活中字符和计算机二进制的对应关系表。
1、ASCII: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx
2、iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
3、GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数
GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0
- GB18030:最新的中文码表,目前还没有正式使用。
4、unicode:国际标准码表:无论是什么文字,都用两个字节存储。
- Java中的char类型用的就是这个码表。char c = 'a';占两个字节。
- Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。
5、UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。
能识别中文的码表:GBK、UTF-8;正因为识别中文码表不唯一,涉及到了编码解码问题。
对于我们开发而言;常见的编码 GBK UTF-8 ISO-8859-1
编码与解码:
文字--->(数字) :编码。 “abc”.getBytes() byte[]
(数字)--->文字 : 解码。 byte[] b={97,98,99} new String(b)
2.2.FileReader读取包含中文的文件
FileReader fr = new FileReader("D:\\test\\cn.txt");
int ch = 0;
while((ch = fr.read())!=-1){
//输出的字符对应的编码值
System.out.println(ch);
//输出字符本身
System.out.println((char)ch);
}
FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
fos.write("文字".getBytes());
fos.close();
2.3.flush()和close()的区别
flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用
。
close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用
。如果写入数据
多,一定要一边写一边刷新
,最后一次可以不刷新,由close完成刷新并关闭。
3.转换流
字符流与字节流之间的桥梁
OutputStreamWriter流对象,如何把字符转成字节输出的呢?
其实在OutputStreamWriter流中维护自己的缓冲区,当我们调用OutputStreamWriter对象的write方法时,会拿着字符到指定的码表中进行查询
,把查到的字符编码值转成字节数
存放到OutputStreamWriter缓冲区中。然后再调用刷新
功能,或者关闭流
,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。
//创建读取文件的字节流对象
InputStream in = new FileInputStream("c:\\ccf.txt");
//创建转换流对象
//InputStreamReader isr = new InputStreamReader(in);这样创建对象,会用本地默认码表读取,将会发生错误解码的错误
InputStreamReader isr = new InputStreamReader(in,"utf-8");
//使用转换流去读字节流中的字节
int ch = 0;
while((ch = isr.read())!=-1){
System.out.println((char)ch);
}
//关闭流
isr.close();
注意:在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。
总结:
字节--->字符 : 看不懂的--->看的懂的。 需要读。输入流。 InputStreamReader(我们需要字符
)
字符--->字节 : 看的懂的--->看不懂的。 需要写。输出流。 OutputStreamWriter(文件需要字节
)
4.缓冲流
Java中提供了一套缓冲流,它的存在,可提高IO流的读写速度
4.1.字节缓冲流
字节缓冲流根据流的方向,共有2个
- 写入数据到流中,字节缓冲输出流 BufferedOutputStream
- 读取流中的数据,字节缓冲输入流 BufferedInputStream
内部都包含了一个缓冲区
,通过缓冲区读写
,就可以提高了IO流的读写速度
4.11 字节缓冲输出流BufferedOutputStream
/*
* 写数据到文件的方法
* 1,创建流
* 2,写数据
* 3,关闭流
*/
private static void write() throws IOException {
//创建基本的字节输出流
FileOutputStream fileOut = new FileOutputStream("abc.txt");
//使用高效的流,把基本的流进行封装,实现速度的提升
BufferedOutputStream out = new BufferedOutputStream(fileOut);
//2,写数据
out.write("hello".getBytes());
//3,关闭流
out.close();
}
4.12.字节缓冲输入流 BufferedInputStream
/*
* 从文件中读取数据
* 1,创建缓冲流对象
* 2,读数据,打印
* 3,关闭
*/
private static void read() throws IOException {
//1,创建缓冲流对象
FileInputStream fileIn = new FileInputStream("abc.txt");
//把基本的流包装成高效的流
BufferedInputStream in = new BufferedInputStream(fileIn);
//2,读数据
int ch = -1;
while ( (ch = in.read()) != -1 ) {
//打印
System.out.print((char)ch);
}
//3,关闭
in.close();
}
4.2.字符缓冲流
4.2.1字符缓冲输出流 BufferedWriter
void newLine() 根据当前的系统,写入一个换行符
/*
* BufferedWriter 字符缓冲输出流
* 方法
* public void newLine()写入一个行分隔符
*
* 需求: 通过缓冲输出流写入数据到文件
* 分析:
* 1,创建流对象
* 2,写数据
* 3,关闭流
*
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建流
//基本字符输出流
FileWriter fileOut = new FileWriter("file.txt");
//把基本的流进行包装
BufferedWriter out = new BufferedWriter(fileOut);
//2,写数据
for (int i=0; i<5; i++) {
out.write("hello");
out.newLine();
}
//3,关闭流
out.close();
}
}
4.2.2字符缓冲输入流 BufferedReader
public String readLine()
读取一个文本行,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
/*
* BufferedReader 字符缓冲输入流
*
* 方法:
* String readLine()
* 需求:从文件中读取数据,并显示数据
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//1,创建流
BufferedReader in = new BufferedReader(new FileReader("file.txt"));
//2,读数据
//一次一个字符
//一次一个字符数组
//一次读取文本中一行的字符串内容
String line = null;
while( (line = in.readLine()) != null ){
System.out.println(line);
}
//3,关闭流
in.close();
}
}
流的总结:
四个明确:
明确一:要操作的数据是数据源还是数据目的。
源:InputStream Reader 目的:OutputStream Writer
先根据需求明确要读,还是要写。
明确二:要操作的数据是字节还是文本呢?
源: 字节:InputStream 文本:Reader 目的: 字节:OutputStream 文本:Writer
明确具体的体系。
明确三:明确数据所在的具体设备。
源设备: 硬盘:文件 File开头。 内存:数组,字符串。 键盘:System.in; 网络:Socket 目的设备: 硬盘:文件 File开头。 内存:数组,字符串。 屏幕:System.out 网络:Socket
要使用哪个流对象
明确四:是否需要额外功能呢?
额外功能: 转换吗?转换流。InputStreamReader OutputStreamWriter 高效吗?缓冲区对象。BufferedXXX
三个过程
向文件中写入数据的过程
1,创建输出流对象 2,写数据到文件 3,关闭输出流
从文件中读数据的过程
1,创建输入流对象 2,从文件中读数据 3,关闭输入流
文件复制的过程
1,创建输入流(数据源) 2,创建输出流(目的地) 3,从输入流中读数据 4,通过输出流,把数据写入目的地 5,关闭流
三、小案例
1、文件的基本操作
@Test
public void testFile() throws Exception{
//创建文件
File file = new File("E:\\test\\b.txt");
file.createNewFile();
//查看文件夹下的文件
File file2 = new File("E:\\test\\b.txt");
String[] list = file2.list();
for (int i = 0; i < list.length; i++) {
System.out.println(list[i]);
}
}
2、复制文件带有进度条
@Test
public void testFileInputStream() throws Exception {
File file = new File("E:\\test\\a\\233.mp4");
//拿到文件的大小
long dataLength = file.length();
//构建一个输入流,他的数据要流入内存,咱们的程序
InputStream inputStream = new FileInputStream(file);
//构建一个输出流,他的数据要从内存(咱们的程序)流到另一个文件夹
OutputStream outputStream = new FileOutputStream("E:\\test\\b\\233.mp4");
//新建一个水泵,能存一点水,每次对对1k
byte[] buffer = new byte[1024 *1024*50];
Long currentLength = 0L;
//如果read返回-1说明读完了
int len;
int showNumber = 0;
while ( (len = inputStream.read(buffer)) != -1 ){
outputStream.write(buffer,0,len);
currentLength += len;
//当下加载了百分之多少
int currentPer = (int)(((double)currentLength/dataLength)*100);
//目的是不重复显示
if(showNumber != currentPer){
showNumber = currentPer;
System.out.println("已经拷贝了百分之" + showNumber);
}
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
3、字节流读文件
@Test
public void testInputStream() throws Exception{
//怼了一个输入流到文件上
InputStream wordInput = new FileInputStream("E:\\test\\a\\word.txt");
//建立缓冲区
byte[] bytes = new byte[1024];
int len;
while ( (len = wordInput.read(bytes)) != -1 ){
System.out.println(new String(bytes,0,len, Charset.forName("ISO8859-1")));
}
wordInput.close();
}
4、字符流对文件
@Test
public void testReader() throws Exception{
//怼了一个输入流到文件上
Reader reader = new FileReader("E:\\test\\a\\word.txt");
BufferedReader br = new BufferedReader(reader);
String str;
while ((str = br.readLine()) != null){
System.out.println(str);
}
reader.close();
br.close();
}
5、向文件里写内容
@Test
public void testWriter() throws Exception{
//怼了一个输入流到文件上
Writer writer = new FileWriter("E:\\test\\a\\writer.txt");
BufferedWriter bw = new BufferedWriter(writer);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.print("请输入:");
String words = scanner.next();
bw.write(words);
bw.flush();
}
}
6、StringReader就是往String上怼
@Test
public void testStringReader() throws Exception{
//怼了一个string
OutputStream os = new FileOutputStream("E:\\test\\a\\user.txt");
ObjectOutput oo = new ObjectOutputStream(os);
oo.writeObject(new User("小航",3,4));
oo.flush();
oo.close();
os.close();
}
四:小实验-下载网易云音乐
step1:https://music.163.com/
进入官网,随便搜首歌曲
step2:进入页面,打开开发者工具(浏览器F12),选择network
step3:选择media过滤,选择一个有效链接https://m701.music.126.net/20210714161041/4fa28b697be05c47052a5b51039e5668/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/5755656629/2ce0/caf3/9e65/4e8df6c581219b094bdce6db938379be.m4a
step4:打开ideal,创建一个class文件Url
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* @author xh
*/
public class Url {
// 文件基本路劲
private static final String BASE_URL = "C:\\Users\\Administrator\\Desktop\\homework\\";
public static void main(String[] args) throws Exception{
download("https://m701.music.126.net/20210714161041/4fa28b697be05c47052a5b51039e5668/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/5755656629/2ce0/caf3/9e65/4e8df6c581219b094bdce6db938379be.m4a");
}
/**
* 下载方法
*/
private static void download(String path) throws IOException {
System.out.println("文件开始下载!");
// 创建一个url对象
URL url = new URL(path);
// 打开和网络的连接,拿到流对象
InputStream inputStream = url.openStream();
// 获取文件名(从最后一个 / 截取字符串)
String fileName = url.getFile().substring(url.getFile().lastIndexOf("/") + 1);
System.out.println(url.getFile().substring(url.getFile().lastIndexOf("/") + 1));
File file = new File(BASE_URL + fileName);
boolean newFile = file.createNewFile();
if(newFile){
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len = inputStream.read(buf)) != -1){
outputStream.write(buf,0,len);
outputStream.flush();
}
inputStream.close();
outputStream.close();
System.out.println("文件下载成功!");
}else{
System.out.println("文件下载失败!");
}
}
}