一、File类的学习
1、创建File对象,定位操作系统的文件(文件,文件夹)
File类概述
a.File类在包java.io.File下,代表操作系统的文件对象(文件,文件夹)
b.File类提供了:定位文件,获取文件本身信息,删除文件,创建文件,创建文件夹等功能
实现代码:
package file.io.d1_file;
import java.io.File;
/**
目标:学会创建File对象,定位操作系统的文件(文件,文件夹)
*/
public class FileDemo {
public static void main(String[] args) {
//1.创建File对象(指定文件路径)
File f=new File("D:\\Desktop\\images\\画.png");
//文件的字节大小
long size=f.length();
System.out.println(size);
//2.File创建对象,支持绝对路径,支持相对路径
//绝对路径
File f1=new File("D:\\Desktop\\images\\R-C (1).jpg");
System.out.println(f1.length());
//相对路径:一般定位在模块中的文件。相对到工程下
File f2=new File("src/data.txt");
System.out.println(f2.length());
//3.File创建文件也可以为文件夹
File f3=new File("D:\\Desktop\\images");
//判断路径是否存在
System.out.println(f3.exists());
}
}
2、File类获取文件的API
实现代码:
package file.io.d1_file;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.logging.SimpleFormatter;
/**
目标:学习File类获取文件的API
-
*/
public class FileDemo2 {
public static void main(String[] args) {
//1.绝对路径创建一个文件夹对象
File f1=new File("D:\\Desktop\\images\\R-C (2).jpg");
//a.获取它的绝对路径
System.out.println(f1.getAbsolutePath());
//b.获取文件定义时使用的路径
System.out.println(f1.getPath());
//c.获取文件名称:带后缀
System.out.println(f1.getName());
//d.获取文件大小:字节个数
System.out.println(f1.length());
//e.获取文件最后修改的时间
long time=f1.lastModified();
//修改格式
System.out.println("文件最后修改的时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time));
//f.判断文件时文件还是文件夹
System.out.println(f1.isFile());//true
System.out.println(f1.isDirectory());//false
System.out.println("---------------------------------------");
//1.相对路径创建一个文件夹对象
File f2=new File("src/data.txt");
//a.获取它的绝对路径
System.out.println(f2.getAbsolutePath());
//b.获取文件定义时使用的路径
System.out.println(f2.getPath());
//c.获取文件名称:带后缀
System.out.println(f2.getName());
//d.获取文件大小:字节个数
System.out.println(f2.length());
//e.获取文件最后修改的时间
long time2=f2.lastModified();
//修改格式
System.out.println("文件最后修改的时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time2));
//f.判断文件时文件还是文件夹
System.out.println(f2.isFile());//true
System.out.println(f2.isDirectory());//false
}
}
3、File类的创建文件与删除文件的方法
实现代码:
package file.io.d1_file;
import java.io.File;
import java.io.IOException;
/**
目标:File类的创建与删除的方法
*/
public class FileDemo3 {
public static void main(String[] args) throws Exception {
File f1=new File("src/data.txt");
//a.创建新文件,创建成功返回true,反之返回false,不需要这个以后文件写出去都会自动创建
System.out.println(f1.createNewFile());//返回false
File f2=new File("src/data2.txt");
System.out.println(f2.createNewFile());//true(几乎不用,因为以后文件都是自动创建的)
//b.mkdir创建一级目录
File f3=new File("D:\\Desktop\\images\\aaa");
System.out.println(f3.mkdir());
//c.mkdir创建多级目录
File f4=new File("D:\\Desktop\\images\\bbb\\ccc\\ddd");
System.out.println(f4.mkdirs());//支持多级创建
//d.删除文件夹或空文件夹(只能删空文件夹)
System.out.println(f2.delete());
//删除f3
System.out.println(f3.delete());
//删除f4
System.out.println(f4.delete());
}
}
4、遍历文件夹
实现代码:
package file.io.d1_file;
import java.io.File;
import java.util.Arrays;
/**
目标:学习遍历文件夹
*/
public class FileDemo4 {
public static void main(String[] args) {
//1.定位一个文件夹
File f=new File("D:\\Desktop\\images");
String[] names=f.list();
for (String name : names) {
System.out.println(name);
}
//2.一级文件对象
//获取当前目录下所有的一级文件对象到一个文件对象数组中返回(重点)
File[] files=f.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
//注意:
// 当调用者不存在返回null
// 当调用者是文件时返回null
// 当调用者是空文件时返回一个长度为0的数组
}
}
二、方法递归的学习
1、方法递归形式
a.方法直接调用自己或间接调用自己的形式。
b.递归作为一种算法在程序设计语言中广泛应用。
c.递归分为直接递归(方法自己调用自己)与间接递归(方法调用其他方法又调回方法自己)。
代码实现:
public class RecusionDemo1 { public static void main(String[] args) { } public static void test(){ System.out.println("=============方法被调用============="); test();//方法递归(直接递归) } }
2、方法递归的几个案例
a、计算1-n的阶乘
实现代码:
package file.io.d2_recusion;
import java.util.Scanner;
/**
* 计算1-n的阶乘
*/
public class RecusionTest1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要算的阶乘:");
int n = sc.nextInt();
System.out.println(Factorial(n));
}
/**
定义一个阶乘的方法(1.递归公式 2.递归走向终结点 )
*/
public static int Factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * Factorial(n - 1);
}
}
}
运行截图:
b、计算1-n的和
package file.io.d2_recusion;
import java.util.Scanner;
/**
* 计算1-n的和
*/
public class RecusionTest2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要算1-n和中n的值:");
int n = sc.nextInt();
System.out.println(Sum(n));
}
/**
定义一个求和的方法(1.递归公式 2.递归走向终结点 )
*/
public static int Sum(int n) {
if (n==1){
return 1;
}else {
return Sum(n-1)+n;
}
}
}
运行截图:
c、猴子吃桃问题 :
猴子第一天摘了若干桃子,当即吃了一半多一个,第二天吃了前天的剩余桃子的一半多一个, 以此类推,等到第十天就只剩1个桃子了,问第一天摘了多少桃子?
实现代码:
package file.io.d2_recusion;
/**
递归案例:猴子吃桃问题
猴子第一天摘了若干桃子,当即吃了一半多一个,第二天吃了前天的剩余桃子的一半多一个,
以此类推,等到第十天就只剩1个桃子了,问第一天摘了多少桃子?
*/
public class RecusionTest3 {
public static void main(String[] args) {
System.out.println(eatPeaches(1));
}
/**
定义一个方法,求出吃的个数
1.找出递归公式:
第x天桃子的个数:f(x)=f(x+1)*2+1;
2.递归终结点:
第x=10天桃子个数为1;
3.递归方向走向终结点。
*/
public static int eatPeaches(int n){
if (n==10){
return 1;
}else {
return 2*eatPeaches(n+1)+2;
}
}
}
运行截图:
d、非规律化递归案例:啤酒问题
啤酒2元1瓶,4个盖子可以换1瓶,2个空瓶可以换1瓶, 问10元钱可以喝多少瓶啤酒,剩余多少空瓶和盖子?
分析:将喝的啤酒瓶,啤酒盖,换算成钱。
实现代码:
package file.io.d2_recusion;
/**
* 非规律化递归案例;啤酒问题
* 啤酒2元1瓶,4个盖子可以换1瓶,2个空瓶可以换1瓶,
* 问10元钱可以喝多少瓶啤酒,剩余多少空瓶和盖子?
*/
public class RecusionTest4 {
//定义一个静态的成员变量用于存储可以买的酒的数量
public static int totalNumber;//啤酒总数量
public static int lastBottleNumber;//空瓶的数量
public static int lastCoverNumber;//瓶盖总数量
public static void main(String[] args) {
//1.拿钱买酒
buy(10);
//4.输出
System.out.println("可以喝的啤酒数量:" + totalNumber);
System.out.println("剩余空瓶的数量:" + lastBottleNumber);
System.out.println("剩余盖子的数量数量:" + lastCoverNumber);
}
public static void buy(int money) {
//2.可以立马买几瓶
int buyNumber = money / 2;
totalNumber += buyNumber;
//3.把盖子和瓶子换算成钱
//统计本轮总的盖子数和瓶子数
int coverNumber = lastCoverNumber + buyNumber;
int bottleNumber = lastBottleNumber + buyNumber;
//计算出盖子和瓶子的总金额
int allMoney = 0;
if (coverNumber >= 4) {
allMoney += (coverNumber / 4) * 2;
}
lastCoverNumber = coverNumber % 4;
if (bottleNumber >= 2) {
allMoney += (bottleNumber / 2) * 2;
}
lastBottleNumber = bottleNumber % 2;
//如果剩余的钱大于2,则继续递归
if (allMoney >= 2) {
buy(allMoney);
}
}
}
运行截图:
e、非规律化递归案例:文件搜索
去D盘找到11111.txt文件
实现代码:
package file.io.d2_recusion;
import java.io.File;
/**
目标:去D盘找到11111.txt文件
*/
public class RecusionDemo2 {
public static void main(String[] args) {
//2.传入目录 与 文件名
searchFile(new File("D:\\"),"11111.txt");
}
/**
* 1.搜索某个目录下的全部文件,找到我们想要的文件
* @param dir
* @param fileName
*/
public static void searchFile(File dir,String fileName){
//3.判断dir是否为目录
if (dir!=null&&dir.isDirectory()){
//可以找了
//4.提取当前文件夹的全部一级文件对象
File[] files=dir.listFiles();
//5.判断是否存在一级文件夹
if(files!=null&&files.length>0){
//6.判断当前遍历一级文件对象是文件还是目录
for (File file : files) {
//7.判断是否为我们找的文件,如果是则输出其路径,不是则继续搜索
if(file.getName().contains(fileName)){
//8.已经找到输出路径
System.out.println("该文件路径为:"+file.getAbsolutePath());
// //启动文件
// try {
// Runtime r=Runtime.getRuntime();
// r.exec(file.getAbsolutePath());
// } catch (Exception e) {
// e.printStackTrace();
// }
}else {
//没有找到,继续搜索
searchFile(file,fileName);
}
}
}
}
// else {
// System.out.println("您当前搜索的不是文件夹!!!");
// }
}
}
运行截图:
三、 IO流的学习
1、前置内容
字符集基础知识
a.计算机底层不可以直接存储字符,计算机中底层只能存储二进制(0,1)
b.二进制是可以转换成十进制
c.常见的字符集
e.自己进行文字的编码和解码
实现代码:
package file.io.d3_charset;
import java.util.Arrays;
/**
目标:学会自己进行文字的编码和解码
*/
public class Test {
public static void main(String[] args) throws Exception {
//1.编码:把文字转换成字节(使用指定的编码)
String name="abc我爱你中国";
byte[] bytes=name.getBytes();//以当前代码默认字符集进行编码(UTF-8)
// byte[] bytes=name.getBytes("GBK");//指定编码GBK
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));
//2.解码:把字节转换成对应的中文形式(编码前和编码后的字符集必须一致)
String rs=new String(bytes);//以当前代码默认字符集解码(UTF-8)
// String rs=new String(bytes,"GBK");//指定GBK解码
System.out.println(rs);
}
}
运行截图:
总结:计算机底层可以表示十进制编号。计算机可以给人类字符进行编号存储,这套编号就是字符集。
2、IO流
a.IO流概念:
I表示intput,是数据从硬盘文件读入到内存的过程,称为输入,负责读。
O表示output,是内存程序的数据从内存到写出到影片文件的过程,称为输出,负责写。
b.IO流的分类:
c.IO流的实现类
d.
字节输入流
实现代码:
package file.io.d4_byte_stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
目标:学习文件字节的输入流管道与源文件接通
*/
public class FileInputStreamDemo1 {
public static void main(String[] args) throws Exception {
//1.创建一个文件字节输入流管道与源文件接通
// InputStream is=new FileInputStream(new File("file-io-app\\src\\data.txt"));
//简化写法
InputStream is=new FileInputStream("src\\data.txt");
//2.读取一个字节返回
// int b1=is.read();
// System.out.println((char) b1);
//
// int b2=is.read();
// System.out.println((char) b2);
//
// int b3=is.read();
// System.out.println((char) b3);
//
// int b4=is.read();//读取完毕返回-1
// System.out.println(b4);
//3.使用循环改进
//定义变量记录每次读取的字节
int b;
while ((b=is.read())!=-1){
System.out.println(b);
}
}
}
package file.io.d4_byte_stream;
import java.io.FileInputStream;
import java.io.InputStream;
/**
目标:使用文件字节输入流每次读取一个字节输入流数据
*/
public class FileInputStreamDemo2 {
public static void main(String[] args) throws Exception {
//1.创建文件字节输入流管道
InputStream is=new FileInputStream("src\\data02.txt");
//2.定义字节数组,用于读取字节数组
// byte[] buffer=new byte[3];//3B,3个字节
// int len=is.read(buffer);
// System.out.println("读取了几个字节:"+len);
// String rs=new String(buffer);
// System.out.println(rs);
//
//
// int len1= is.read(buffer);
// System.out.println("读取了几个字节:"+len1);
// String rs1=new String(buffer);
// System.out.println(rs1);
//
// int len2= is.read(buffer);
// System.out.println("读取了几个字节:"+len2);
// //读多少倒多少
// String rs2=new String(buffer,0,len2);
// System.out.println(rs2);//cd
//改进使用循环,每次读取一个数组
byte[] buffer=new byte[3];
int len;//记录每次读取字节数
while ((len=is.read(buffer))!=-1){
//读多少倒多少
System.out.print(new String(buffer,0,len));
}
}
}
package file.io.d4_byte_stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
目标:使用文件字节输入流一次读完全部字节。可以解决乱码问题
*/
public class FileInputStreamDemo3 {
public static void main(String[] args) throws Exception {
//1.创建文件字节输入流管道
File f=new File("src\\data03.txt");
InputStream is=new FileInputStream(f);
//2.定义一个字节数组与文件大小刚刚一样大(自己定义)
// byte[] buffer=new byte[(int) f.length()];
// int len=is.read(buffer);
// System.out.println("读取了多少字节:"+len);
// System.out.println("文件大小:"+f.length());
// System.out.println(new String(buffer));
//3.官方提供的API读取文件全部字节
byte[] buffer=is.readAllBytes();
System.out.println(new String(buffer));
}
}
字节输出流
实现代码:
package file.io.d4_byte_stream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
目标:学习字节输出流
*/
public class OutputStreamDemo4 {
public static void main(String[] args) throws Exception {
//1.创建一个文件字节输出流管道与目标文件接通
// OutputStream os=new FileOutputStream("src/out04.txt");//(覆盖管道)创建后会清空之前的数据,然后写入新的数据
OutputStream os=new FileOutputStream("src/out04.txt",true);//(追加管道)创建后会不会清空之前的数据,然后写入新的数据
//2.将数据写出去
//写一个字节出去
os.write('a');
os.write(55);
//回车换行(转成字节数组)
os.write("\r\n".getBytes());
// os.write('你');
//写一个字节数组出去
byte[] buffer={'a','b',97,98,99};
os.write(buffer);
os.write("\r\n".getBytes());
//将中文转化为字节
byte[] buffer2="我爱你中国".getBytes();
os.write(buffer2);
os.write("\r\n".getBytes());
//写一个数组的一部分进文件(前3个aba)
byte[] buffer3={'a','b',97,98,99};
os.write(buffer3,0,3);
os.write("\r\n".getBytes());
//刷新
// os.flush();
//最后要关闭流,不能在用了(包括刷新)
os.close();
}
}
学会字节流实现文件拷贝,支持一切文件类型
实现代码:
package file.io.d4_byte_stream;
import java.io.*;
/**
目标:学会字节流实现文件拷贝,支持一切文件类型(字节大都用于图片,音视频等的输入输出)
*/
public class CopyDemo05 {
public static void main(String[] args) {
try {
//1.创建一个字节输入流管道与原文件接通
InputStream is=new FileInputStream("D:\\Desktop\\images\\efwfw\\毛不易《平凡的一天》(蓝光).mp4");
//2.创建字节输出流管道与目标文件接通
OutputStream os=new FileOutputStream("D:\\Desktop\\images\\毛不易《平凡的一天》(蓝光).mp4");
//3.定义字节数组转移数据
byte[] buffer=new byte[1024];
int len;//记录每次读取的字节数
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
}
System.out.println("复制完成!!!");
//关闭
is.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
e.
字符输入流
实现代码:
package file.io.d6_char_stream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
/**
目标:学习字符输入流
*/
public class FileReaderDemo1 {
public static void main(String[] args) throws Exception {
//目标:每次读取一个字符
//1.创建字符输入管道与源文件接通
Reader fr=new FileReader("src\\data03.txt");
//2.读取一个字符返回,没有可读的字符后返回-1
// int code =fr.read();
// System.out.println((char) code);
//3.使用循环遍历字符
int code;
while ((code=fr.read())!=-1){
System.out.print((char) code);
}
fr.close();
}
}
package file.io.d6_char_stream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
/**
目标:按字符数组循环读取数组
*/
public class FileRederDemo2 {
public static void main(String[] args) throws Exception {
//1.创建一个文件字符输入流与源文件接通
Reader fr=new FileReader("src\\out04.txt");
//2.用循环每次读取一个字符数组
char[] buffer=new char[1024];//1K字符
int len;//记录每次读取了多少字符
while ((len= fr.read(buffer))!=-1){
String rs=new String(buffer,0,len);
System.out.println(rs);
}
}
}
字节输出流
实现代码:
package file.io.d6_char_stream;
import java.io.FileWriter;
import java.io.Writer;
/**
目标:学习字符输出流
*/
public class FileWriterDemo3 {
public static void main(String[] args) throws Exception{
//1.创建一个输出流管道与目标文件接通
// Writer fw=new FileWriter("src\\data.txt");//覆盖数据
Writer fw=new FileWriter("src\\data.txt");//叠加数据
//2.写一个字符出去
fw.write('c');
fw.write(88);
fw.write('你');
fw.write("\r\n");
//3.写一个字符串
fw.write("我爱你中国!!!");
fw.write("\r\n");
//4.写字符串一部分
fw.write("你好吗?",0,2);
fw.write("\r\n");
//5.写字符数组的一部分出去
char[] chars="你好吗,我的朋友!!!".toCharArray();
fw.write(chars,0,5);
fw.write("\r\n");
//刷新关闭
fw.close();
}
}
四、缓冲流的学习
1、字符缓冲流
实现代码:
package io.d1_byte_buffer;
import java.io.*;
/**
* 目标:使用字节缓冲流完成数据读写操作
*/
public class ByteBufferDemo {
public static void main(String[] args) {
try (
//这里只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
//1.创建一个字节输入流管道与原文件接通
InputStream is = new FileInputStream("D:\\Desktop\\images\\efwfw\\OIP-C.jpg");
//a.把原始字节输入流包装成高级缓冲输入流
InputStream bis=new BufferedInputStream(is);
//2.创建字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("D:\\Desktop\\images\\OIP-C.jpg");
//b.把字节输出流管道包装成高级的缓冲字节输出流管道
OutputStream bos=new BufferedOutputStream(os);
) {
//3.定义字节数组转移数据
byte[] buffer = new byte[1024];
int len;//记录每次读取的字节数
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
System.out.println("复制完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
案例: 分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时
实现代码:
package io.d2_byte_buffer_time;
import java.io.*;
/**
需求:
分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时
*/
public class ByteBufferTimeDemo {
//定义常量,将复制路径固定
private static final String SRC_FILE="D:\\Desktop\\images\\efwfw\\毛不易《平凡的一天》(蓝光).mp4";
private static final String DEST_FILE="D:\\Desktop\\images\\";
public static void main(String[] args) {
//a.使用低级字节流按照与一个一个字节的形式复制文件
copy01();//慢到发指
//b.使用低级字节流按照与一个一个字节数组的形式复制文件
copy02();//比较慢
//c.缓冲流一个一个字节复制
copy03();//很慢,不推荐
//d.缓冲流一个一个字节数组复制
copy04();//很快,非常推荐
}
/**
缓冲流一个一个字节数组复制
*/
private static void copy04() {
long starTime=System.currentTimeMillis();
try (
//这里只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
//1.创建一个字节输入流管道与原文件接通
InputStream is = new FileInputStream(SRC_FILE); //a.把原始字节输入流包装成高级缓冲输入流
InputStream bis=new BufferedInputStream(is);
//2.创建字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE+"video4.mp4");
//b.把字节输出流管道包装成高级的缓冲字节输出流管道
OutputStream bos=new BufferedOutputStream(os);
) {
//3.定义字节数组转移数据
byte[] buffer = new byte[1024];
int len;//记录每次读取的字节数
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
System.out.println("复制完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("copy04高级缓冲流字节数组耗时:"+(endTime-starTime)/1000.0+"s");
}
/**
缓冲流一个一个字节复制
*/
private static void copy03() {
long starTime=System.currentTimeMillis();
try (
//这里只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
//1.创建一个字节输入流管道与原文件接通
InputStream is = new FileInputStream(SRC_FILE);
//a.把原始字节输入流包装成高级缓冲输入流
InputStream bis=new BufferedInputStream(is);
//2.创建字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE+"video3.mp4");
//b.把字节输出流管道包装成高级的缓冲字节输出流管道
OutputStream bos=new BufferedOutputStream(os);
) {
//3.定义变量,记录每次读取的字节
int b;
while ((b=bis.read())!=-1){
bos.write(b);
}
System.out.println("复制完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("copy03高级缓冲流字节耗时:"+(endTime-starTime)/1000.0+"s");
}
/**
使用低级字节流按照与一个一个字节数组的形式复制文件
*/
private static void copy02() {
long starTime=System.currentTimeMillis();
try (
//这里只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
//1.创建一个字节输入流管道与原文件接通
InputStream is = new FileInputStream(SRC_FILE);
//2.创建字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE+"video2.mp4");
) {
//3.定义字节数组转移数据
byte[] buffer = new byte[1024];
int len;//记录每次读取的字节数
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("复制完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("copy02耗时:"+(endTime-starTime)/1000.0+"s");
}
/**
使用低级字节流按照与一个一个字节的形式复制文件
*/
private static void copy01() {
long starTime=System.currentTimeMillis();
try(
//1.创建字节输入流
InputStream is=new FileInputStream(SRC_FILE);
//2.创建字节输出流
OutputStream os=new FileOutputStream(DEST_FILE+"video1.mp4");
) {
//3.定义变量,记录每次读取的字节
int b;
while ((b=is.read())!=-1){
os.write(b);
}
System.out.println("复制完成!!!");
}catch (Exception e){
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("copy01耗时:"+(endTime-starTime)/1000.0+"s");
}
}
运行截图:
2、字节缓冲流
实现代码:
package io.d3_char_buffer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
目标:学会使用缓冲字符输入流提高字符输入流的性能,新增了按照行读取的方法(经典代码)
*/
public class BufferedReaderDemo1 {
public static void main(String[] args) {
try(
//1.创建一个文件字符输入流与源文件接通
Reader fr=new FileReader("src\\data01.txt");
//a.把低级字符输入流包装成高级缓冲字符输入流
BufferedReader br=new BufferedReader(fr);
){
// //2.用循环,每次读取一个字符数组数据
// char[] buffer=new char[1024];
// int len;
// while ((len=fr.read(buffer))!=-1){
// String rs=new String(buffer,0,len);
// System.out.println(rs);
// }
// //每次读取一行
// System.out.println(br.readLine());
//用循环读取全部
String lin;
while ((lin=br.readLine())!=null) {
System.out.println(lin);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
package io.d3_char_buffer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
/**
目标:学习缓冲字符输出流使用,学会他多出来的功能newLine();
*/
public class BufferedReaderDemo2 {
public static void main(String[] args) throws Exception{
//1.创建一个输出流管道与目标文件接通
// Writer fw=new FileWriter("src\\data.txt");//覆盖数据
Writer fw=new FileWriter("src\\data02.txt",true);//叠加数据
BufferedWriter bw=new BufferedWriter(fw);
//2.写一个字符出去
bw.write('c');
bw.write(88);
bw.write('你');
bw.newLine();//换行 bw.write("\r\n");
//3.写一个字符串
bw.write("我爱你中国!!!");
bw.newLine();
//4.写字符串一部分
bw.write("你好吗?",0,2);
bw.newLine();
//5.写字符数组的一部分出去
char[] chars="你好吗,我的朋友!!!".toCharArray();
bw.write(chars,0,5);
bw.newLine();
//刷新关闭
bw.close();
}
}
案例:将打乱顺序的出师表文件,进行排序然后恢复到新文件中
运行前文件:
实现代码:
package io.d3_char_buffer;
import java.io.*;
import java.sql.Connection;
import java.util.*;
/**
需求:将打乱顺序的出师表文件,进行排序然后恢复到新文件中
*/
public class BufferedCharTest3 {
public static void main(String[] args) {
try {
//1.定义一个缓冲字符输入流管道与原文件接通
BufferedReader br=new BufferedReader(new FileReader("src\\csb.txt"));
//2.定义List集合存储每行数据
List<String> data=new ArrayList<>();
//3.定义循环,按照行读取文章
String line;
while ((line=br.readLine())!=null){
data.add(new String(line));
}
List<String> sizes=new ArrayList<>();
Collections.addAll(sizes,"壹","二","三","四","五","六","七","捌","九");
//4.排序
Collections.sort(data, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return sizes.indexOf(o1.substring(0,o1.indexOf(".")))
-sizes.indexOf(o2.substring(0,o2.indexOf(".")));
}
});
//5.将排好序的文章输入到一个文件
BufferedWriter bw=new BufferedWriter(new FileWriter("src\\csb1.txt"));
for (String s : data) {
bw.write(s);
bw.newLine();//换行
}
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行后文件:
五、转换流的学习
1、字符输入转换流
实现代码:
package io.d4_transfer_stream;
import java.io.*;
/**
目标:实现将GBK文件转为UTF-8输出
*/
public class InputStreamReaderDemo1 {
public static void main(String[] args) {
try {
//代码UTF-8 文件GBK "D:\\Desktop\\images\\测试.txt"
//1.提取GBK文件的原始字节流
InputStream is=new FileInputStream( "D:\\Desktop\\images\\测试.txt");
//2.把原始字节流转换为字符输入流
// Reader isr=new InputStreamReader(is);//默认UTF-8的方式转换成字符流(乱码)
Reader isr=new InputStreamReader(is,"GBK");//以指定的GBK编码转化成字符输入流(解决乱码问题)
//包装成缓冲字符输入流
BufferedReader br=new BufferedReader(isr);
String line;
while ((line= br.readLine())!=null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、字符输出转换流
实现代码:
package io.d4_transfer_stream;
import java.io.*;
/**
* 目标:指定字符编码写出去
*/
public class OutputStreamWriterDemo2 {
public static void main(String[] args) {
try {
//1.定义一个字节输出流
OutputStream os = new FileOutputStream("src\\out.txt");
//2.把原始字节输出流转换成字符输出流
// Writer osw=new OutputStreamWriter(os);//默认UTF-8写出去字符,和直接写FileWriter一样
OutputStreamWriter osw = new OutputStreamWriter(os,"GBK");//指定GBK的方式写字符出去
//包装成高级的缓冲字符输出流
BufferedWriter bw = new BufferedWriter(osw);
bw.write("我爱你中国!!!");
bw.newLine();
bw.write("我爱你中国!!!");
bw.write("我爱你中国!!!");
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
六、对象序列化与反序列化
1、先创建一个学生对象
package io.d5_serializable;
import java.io.Serializable;
/**
如果对象序列化,必须要实现Serializable接口
//申明序列化版本号
//序列化的版本号与反序列化的版本号必须一致才不会出错!!!
*/
public class Student implements Serializable {
//申明序列化版本号
//序列化的版本号与反序列化的版本号必须一致才不会出错!!!
private static final long serialVersionUID=4;
private String name;
private String loginName;
//transient修饰的成员变量不再参与序列化
private transient String passWord;
private int age;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, String loginName, String passWord, int age) {
this.name = name;
this.loginName = loginName;
this.passWord = passWord;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", loginName='" + loginName + '\'' +
", passWord='" + passWord + '\'' +
", age=" + age +
'}';
}
}
2、将对象进行序列化
package io.d5_serializable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
目标:学会使用对象序列化,使用ObjectOutputStream把内存中的对象存入磁盘文件中。
*/
public class ObjectOutputStreamDemo1 {
public static void main(String[] args) {
try {
//1.创建学生对象
Student s=new Student("张三","zhangsan","123456",21);
//2.对象序列化,使用对象字节输出流,包装输出流管道
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("src\\obj.txt"));
//3.直接调用序列化方法
oos.writeObject(s);
//4.释放对象
oos.close();
System.out.println("序列化完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、将对象进行反序列化
package io.d5_serializable;
import java.io.*;
/**
* 目标:学会反序列化
* 序列化的版本号与反序列化的版本号必须一致才不会出错!!!
* 如果对象序列化,必须要实现Serializable接口!!!
*/
public class ObjectInputstreamDemo2 {
public static void main(String[] args) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\obj.txt"));
Student s = (Student) ois.readObject();
System.out.println(s);
ois.close();
System.out.println("反序列化完成!!!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行截图:
七、打印流的学习
实现代码:
package io.d6_printStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
目标:学会使用打印流,高效,方便写数据到文件
*/
public class PrintDemo1 {
public static void main(String[] args) {
try {
//1.创建一个对象
PrintStream ps=new PrintStream(new FileOutputStream("src\\ps.txt",true));//连通低级管道(可在低级管道中追加数据)
// PrintStream ps=new PrintStream("src\\ps.txt");//直接到达文件,很灵活(字节输出流,只能写字节)(不可追加数据)
// PrintWriter ps=new PrintWriter("src\\ps.txt");//与上行代码没有区别,直接到达文件,很灵活(字符输出流,可写字节也可字符)
//2.写入数据
ps.println(999);
ps.println('a');
ps.println("我爱你中国!!!");
ps.println(true);
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
八、commons_io框架的学习
第三方的框架,用的时候需要导入commons-io-2.11.0.jar包 .
实现代码:
package io.d8_commons_io;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
/**
目标:学会使用commons-io框架
*/
public class CommonsIODemo1 {
public static void main(String[] args) throws Exception {
//1.完成文件的复制(任何文件)
// IOUtils.copy(new FileInputStream("D:\\Desktop\\images\\R-C (1).jpg")
// ,new FileOutputStream("D:\\Desktop\\images\\R-C (1)2.jpg"));
// //2.复制文件到文件夹下
// FileUtils.copyFileToDirectory(new File("D:\\Desktop\\images\\R-C (1).jpg")
// ,new File("D:\\Desktop\\images\\bbb"));
//
// //3.复制文件夹到文件夹中
// FileUtils.copyDirectoryToDirectory(new File("D:\\Desktop\\images")
// ,new File("D:\\Desktop\\images\\bbb"));
// //4.删除文件夹
// FileUtils.deleteDirectory(new File("D:\\Desktop\\images\\bbb\\images"));
//JDK1.7 自己做的一些一行代码完成复制操作:New IO的技术
// Files.copy(Path.of("D:\\Desktop\\images\\R-C.jpg")
// ,Path.of("D:\\Desktop\\images\\R-C1.jpg"));
//
}
}