其实Java基础教程系列第十五篇:深入解析IO流与递归算法的问题并不复杂,但是又很多的朋友都不太了解,因此呢,今天小编就来为大家分享Java基础教程系列第十五篇:深入解析IO流与递归算法的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
read() : 将文件上的字节读取到内存中的数组中
FileOutputStream : 输出流
write(byte[] b) : 将字节数组中的字节数据写入文件
缓冲区将在内存中创建一个8192容量的字节数组。内存的计算效率远高于硬盘,因此只要减少硬盘的读写次数,效率就会得到提高。
定义小数组的标准格式:来读写字节数据比缓冲流要快一点,因为定义小数组是对一个数组进行操作,而缓冲流是对两个数组进行操作。
公共类Demo3_ArrayCopy {
公共静态无效主(字符串[] args)抛出IOException {
//方法();
//方法2();
FileInputStream fis=new FileInputStream("韩雪-思念.mp3");
FileOutputStream fos=new FileOutputStream("Copy.mp3");
byte[] arr=新字节[1024*8];
int 长度;
while((len=fis.read(arr)) !=-1) {
fos.write(arr,0,len);
}
fis.close();
fis.close();
}
close方法:具有刷新功能。在关闭流之前,会刷新缓冲区,并将缓冲区中的所有字节刷新到文件中。
*flush :有刷新功能,flush后可以继续写入。
* 从字节流读取中文的问题。读取中文时,字节流可能读取到一半中文,造成乱码。
* 字节流写入中文的问题:字节流直接操作字节,所有中文比较都将字符串转为字节数组
* 写入回车换行write("rn".getBytes());
//这是1.6及之前版本的标准异常处理代码
private static void method() 抛出FileNotFoundException, IOException {
//为什么要加null?这是一个局部变量,所有东西都必须赋值。
文件输入流fis=null;
文件输出流fos=null;
尝试{
fis=new FileInputStream("xxx.txt");
fos=new FileOutputStream("yyy.txt");
整数b;
while((b=fis.read()) !=-1) {
fos.write(b);
}
}最后{
//嵌套tryfinally的目的就是尽可能的关闭一个
尝试{
如果(fis!=null){
fis.close();
}
}最后{
如果(fos!=null){
fos.close();
}
}
}
}
}
///这些抽象类具有自动关闭功能。只要实现了AutoCloseable,它们就会具有自动关闭发布流的功能。
//这是jdk1.7版本的标准异常处理代码
原理: try() 中创建的流对象必须实现AutoCloseable 接口。如果实现的话,在执行try后的{}(读写代码)后,会自动调用流对象的close方法来关闭并释放流。
尝试(
//这些抽象类具有自动关闭功能。只要实现了AutoCloseable,它们就会具有自动关闭发布流的功能。
FileInputStream fis=new FileInputStream("xxx.txt");
FileOutputStream fos=new FileOutputStream("yyy.txt");
MyClose mc=new MyClose();
){
整数b;
while((b=fis.read()) !=-1) {
fos.write(b);
}
/*FileInputStream fis=new FileInputStream("xxx.txt");
FileOutputStream fos=new FileOutputStream("yyy.txt");*/
}
/*fis.close();
fos.close();*/
}
/*
* 图像加密
* 将写入的字节与之前的数字进行异或。这个数字是关键。解密的时候再异或一下就可以了。
*/
公共类测试1 {
公共静态无效主(字符串[] args)抛出IOException {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("2017619-Monday-141543.jpg"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("Copy.jpg"));
整数b;
while((b=bis.read()) !=-1) {
//运算符^异或两次是其本身,这里所有异或一次都是为了加密
bos.write(b^123);
}
bis.close();
bos.close();
}
//解密
/*BufferedInputStream bis=new BufferedInputStream(new FileInputStream("Copy.jpg"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("Copy2.jpg"));
整数b;
while((b=bis.read()) !=-1) {
//运算符^异或两次是其本身,这里所有异或一次都是为了加密
bos.write(b^123);
}
bis.close();
bos.close();
*
*
*/
}
* 在控制台输入文件的路径,将文件复制到当前项目中
*分析:
* 1.创建键盘输入对象,定义方法判断键盘输入路径,如果是文件则返回
* 2.在main方法中接收文件
* 3.文件的读写
*/
公共类测试2 {
公共静态无效主(字符串[] args)抛出IOException {
//获取文件
文件file=getFile();
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(文件));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file.getName()));
整数b;
while((b=bis.read()) !=-1) {
bos.write(b);
}
bis.close();
bos.close();
}
/*
* 定义一个方法获取键盘输入的文件路径,封装成File对象返回
* 1.返回值类型File
* 2. 参数列表无
*
*/
公共静态文件getFile() {
扫描仪sc=新扫描仪(System.in);
//接收键盘输入路径
//字符串行=sc.nextLine();
System.out.println("请输入文件路径");
而(真){
字符串行=sc.nextLine();
//封装成File对象并进行判断
文件文件=新文件(行);
if(!file.exists()) {
System.out.println("您输入的文件路径不存在,请重新输入:");
}否则if(file.isDirectory()) {
System.out.println("请输入文件夹路径,请重新输入");
}别的{
返回文件;
}
}
}
}
/*
* 将键盘输入的数据复制到当前项目下的text.txt文件中。当遇到退出时,键盘输入的数据就会退出。
*分析:
* 1.创建键盘输入对象
* 2.创建输出流对象并关联text.txt文件
* 3.定义无限循环
* 4.遇到quit时退出循环
* 5.如果不退出,写出内容
* 6.关闭流
*/
公共类测试3 {
公共静态无效主(字符串[] args)抛出IOException {
//1.创建键盘输入对象
扫描仪sc=新扫描仪(System.in);
//2.创建输出流对象并关联text.txt文件
FileOutputStream fos=new FileOutputStream("text.txt");
System.out.println("请输入数据");
//3.定义无限循环
而(真){
字符串lin=sc.nextLine();
//4.遇到quit时退出循环
if("退出".equals(lin)) {
休息;
}
//5.如果你不退出,就把内容写出来。
//将鼻血写成字符串,转成字节数组
fos.write(lin.getBytes());
fos.write("rn".getBytes());
}
fos.close();
}
}
*/
/*
* 从键盘输入文件夹路径并计算文件夹的大小
* 从键盘输入文件夹路径
* 1.无限循环
* 2.定义无限循环
* 3.将获奖结果存储并封装到File对象中
* 4.判断File对象
* 5.返回文件夹路径对象
* 统计文件夹的大小
* 1.定义求和变量
* 2.获取文件夹中的所有文件和文件夹ListFiles();
* 3.遍历数组
* 4.如果判断为文件,则计算大小并相加。
* 5.判断是文件夹并递归调用
*/
公共类测试1 {
公共静态无效主(字符串[] args){
/*文件目录=getDir();
System.out.println(getFileLength(dir));*/
//直接获取文件大小为0
文件目录=新文件("F:\day06");
System.out.println(dir.length());
}
/*
* 从键盘输入接收文件夹路径
* 1.返回值类型File
* 2. 参数列表无
*
*/
公共静态文件getDir() {
//1.创建键盘输入对象
扫描仪sc=新扫描仪(System.in);
System.out.println("请输入文件夹路径:");
//2.环形
而(真){
//将键盘输入结果存储封装成File对象
字符串行=sc.nextLine();
文件目录=新文件(行);
//判断File对象
if(!dir.exists()) {
System.out.println("您输入的文件夹路径不存在,请输入文件夹路径:");
}否则if(dir.isFile()) {
System.out.println("您输入了文件路径,请输入文件夹路径:");
}别的{
//返回文件夹路径对象
返回目录;
}
}
}
/*
* 统计文件夹的大小
* 1.返回值类型long
* 2.参数列表文件
*
*/
公共静态长getFileLength(文件目录){
//1.定义求和变量
长长度=0;
//2.获取文件夹中的所有文件和文件夹ListFiles();
File[] subFiles=dir.listFiles();
//3.遍历数组
for (文件子文件: 子文件) {
//4.如果判断是文件,则计算大小并相加。
if(subFile.isFile()) {
len=len + subFile.length();
//5.判断是文件夹并递归调用
}别的{
len=len + getFileLength(子文件);
}
}
返回长度;
}
}
*/
/*
/*从键盘接收一个文件夹路径并删除该文件夹
* 删除该文件夹
*分析:
* 1.获取该文件夹下的所有文件和文件夹
* 2.遍历数组
* 3.判断文件直接删除
* 4.如果是文件夹,则递归调用
* 5.循环结束后,删除空文件夹
*/
公共类测试2 {
公共静态无效主(字符串[] args){
//获取文件夹路径
文件目录=Test1.getDir();
删除文件(目录);
}
/*
* 删除该文件夹
* 1.返回值类型void
* 2.参数列表:文件目录
*
*/
公共静态无效deleteFile(文件目录){
//1.获取该文件夹下的所有文件和文件夹
File[] subFiles=dir.listFiles();
//2.遍历数组
for (文件子文件: 子文件) {
//3.判断文件是否直接删除
if(subFile.exists()){
子文件.delete();
//4.如果是文件夹则递归调用
}别的{
删除文件(子文件);
}
}
//5.循环结束后,删除空文件夹
目录.删除();
}
}
/*
* 从键盘接收两个文件夹路径,将一个文件夹的内容(包含内容)复制到另一个文件夹
*分析:
* 1.在目标文件夹中创建原始文件夹
* 2.获取原文件夹中的所有文件和文件夹,存放到File数组中
* 3.遍历数组
* 4.如果是文件,则使用io流读写
* 5.如果是文件夹,则递归调用
*/
公共类测试3 {
公共静态无效主(字符串[] args)抛出IOException {
文件src=Test1.getDir();
文件dest=Test1.getDir();
if(src.equals(dest)) {
System.out.println("目标文件夹是原文件夹的子文件夹");
}别的{
复制(源,目标);
}
}
/*将其中一个文件夹(包含内容)复制到另一个文件夹
* 1.返回值类型void
* 2.参数列表:文件src、文件dest
*
*/
公共静态无效复制(文件src,文件dest)抛出IOException {
//1.在目标文件夹中创建原始文件夹
文件newDir=new File(dest, src.getName());
newDir.mkdir();
//2.获取原文件夹下的所有文件和文件夹,存放到File数组中
File[] subFiles=src.listFiles();
//3.遍历数组
for (文件子文件: 子文件) {
if(subFile.isFile()) {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(subFile));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File(newDir,subFile.getName())));
整数b;
while((b=bis.read()) !=-1) {
bos.write(b);
}
bos.close();
bis.close();
}别的{
复制(子文件,新目录);
}
}
}
UTF-8: 以UTF-8编码的Java文件对于英文字符占用1个字节,对于中文字符占用3个字节。
GBK: GBK编码的中文占用两个字节,英文占用一个字节。
Windows中.txt文件编码的1个字符占用1个字节,1个汉字占用2个字节(日语中1个日文字符也占用2个字节)
}
/*
read() : 一次读取一个字节
//创建文件输入流对象并与aaa.txt关联
FileInputStream fis=new FileInputStream("aaa.txt");
//定义变量记录每次读取的字节数
整数b;
//将每次读取的字节赋值给b并判断是否为-1
while((b=fis.read() !=-1) {
系统(b);
}
fis.close();
为什么read()方法的返回值是int?
因为字节输入流可以操作任何类型的文件,比如图片、音频等,所以这些文件在底层都是以二进制形式存储的。如果每次读取都返回byte,那么中间读取的时候就有可能遇到11111111。
那么这个11111111就是byte类型的-1。当我们的程序遇到-1时,就会停止读取。后续数据无法读取,所以读取时使用int类型接收。如果前面加上11111111,则更上级
24个0组成4个字节,然后将byte类型的-1编程为int类型的255。这样可以保证读取到整个数据,并且结束标志的-1是int类型。
write() : 一次写入一个字节
//如果没有bb.txt则创建一个
FileOutputStream fos=new FileOutputStream("bb.txt");
//虽然写入的是int数,但是写入时会去掉前24个零,全部写入的是一个字节。
//fos.write(97);
fos.write(98);
fos.write(99);
fos.close();
缓冲思想:
通过字节流一次读写数组的速度显然比一次一个字节读写数据要快很多。
这就是Java本身设计时添加数组的缓冲效果。
也考虑到了这种设计思想(装饰设计模式),所以提供了字节缓冲流
缓冲输入流
BufferedInputStream 有一个内置的缓冲区(数组)
从BufferedInputStream 读取字节时
BufferedInputStream 会一次性从文件中读取8192 个,将它们存储在缓冲区中,然后返回1 个给程序。
当程序再次读取时,无需寻找文件,直接从缓冲区中获取。
直到所有缓冲区都被使用为止,再次从文本中读取8192。
缓冲输出流
BufferedOutputStream也有一个内置的缓冲区(数组)
当程序将字节写入流时,它不会直接写入文件,而是先将它们写入缓冲区。
直到缓冲区满了,BufferedOutputStream会将缓冲区中的数据一次性写入到文件中。
复制代码:
//创建一个文件输入流对象,与youth.mp3关联
FileInputStream fis=new FileInputStream("知情权.mp3");
//创建一个缓冲区来修改fis
BufferedInputStream bis=new BufferedInputStream(fis);
//创建输出流对象并将其与copy.MP3关联
FileOutputStream fos=new FileOutputStream("copy.mp3");
//创建缓冲区来装饰fos
BufferedOutputStream bos=new BufferedOutputStream(fos);
整数b;
while((b=bis.read() !=-1) {
bos.write;
}
//只关闭被装饰的对象
bis.close();
bos.close();
小数组读写和缓冲读取哪个更快?
如果与Buffered 相比大小为8192 字节,则定义一个小数组
定义一个小数组稍微好一点,因为读写操作都是同一个数组
Buffered 对两个数组进行操作
齐平还是接近,哪一个更快?
冲洗()方法:
它用于刷新缓冲区流区域。刷新后就可以再次写出来了。
克洛
se()方法: 用来关闭流程释放资源的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭之前刷新缓冲区,关闭后不能再写出. * File类:文件和目录路径名的抽象表示形式。 * 文件:可以保存数据的文件 * 目录路径名:指的文件夹,可以保存文件的 * 一个File对象 可以指一个文件 也可以指一个文件夹 * 构造方法: * 1.public File(String filename); * 2.public File(String parent,String child) * 3.public File(File parent,String child) */ public class FileDemo01 { public static void main(String[] args) { // TODO Auto-generated method stub //1.public File(String filename); File f1 = new File("E:\黑马66期\1.txt"); System.out.println(f1); //2.public File(String parent, String child) File f2 = new File("E:\黑马66期","1.txt"); System.out.println(f2); //3.public File(File parent, String child) File parent = new File("E:\黑马66期"); File f3 = new File(parent, "1.txt"); System.out.println(f3); } } * 文件:可以保存数据的文件 * 目录路径名:指的文件夹,可以保存文件的 * File类的成员方法: * 第一组 获取方法 * public String getAbsolutePath();//获取绝对路径(以盘符开头的路径); * public String getPath();//获取路径,你用构造方法创建File对象时写那个路径 * public String getName();//获取不带路径的文件名 * public long length();//获取只能文件字节大小 */ public class FileDemo02 { public static void main(String[] args) { // TODO Auto-generated method stub //获取绝对路径 File f1 = new File("E:\黑马66期\1.txt"); // File f1 = new File("a.txt"); // String absolutePath = f1.getAbsolutePath(); // System.out.println(absolutePath); //获取路径 // String path = f1.getPath(); // System.out.println(path); //获取名字 // String name = f1.getName(); // System.out.println(name); //获取文件的长度 // long len = f1.length(); // System.out.println(len); //能不能获取文件夹的长度,不能获取,获取到的是一个不确定的值 // File f2 = new File("E:\黑马66期\test"); // long len = f2.length(); // System.out.println(len); } } * 文件和文件夹的创建删除等 * 1.public boolean createNewFile();//只能创建文件类型File对象,如果此文件存在 那么创建失败 * 2.public boolean mkdir();//makeDirectory,创建文件夹类型的File对象 * 3.public boolean exists();//判断File 对象是否存储在 * 4.public boolean isDirectory();//判断是否是文件夹 * 5.public boolean isFile();//判断是否是一个文件 * 6.public boolean delete();//删除文件和文件夹对象 7.public boolean endsWith() : 判断 */ public class FileDemo03 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建文件 File f1 = new File("E:\黑马66期\test\a.txt"); // boolean b = f1.createNewFile(); // System.out.println(b); //2.创建文件夹 // File f2 = new File("E:\黑马66期\test\a.txt"); // boolean b = f2.mkdir(); // System.out.println(b); //3.判断File对象是否存在 // File f3 = new File("E:\黑马66期\test\abcd.txt"); // System.out.println(f3.exists()); //4.判断到底是文件还是文件夹 // System.out.println(f1.isDirectory()); // System.out.println(f1.isFile()); //5.删除File对象(可以是文件也可以是文件夹) File fd = new File("E:\黑马66期\test\abc.txt"); System.out.println(fd.delete()); } } * File类中另外两个比较重要的方法 * 1. public String[] list();//列出代表文件夹的File对象中的文件和目录, * 如果调用方法的File对象表示的是一个文件,会返回null * 2. public File[] listFiles();//列出代表文件夹的File对象中的文件和目录, * 如果调用方法的File对象表示的是一个文件,会返回null */ public class FileDemo01 { public static void main(String[] args) { // TODO Auto-generated method stub //1.public String[] list() // File fileDir = new File("F:\demo"); // String[] files = fileDir.list(); // //遍历这个files数组 // for (String file : files) { // System.out.println(file); // } //2.File[] listFiles() File fileDir = new File("F:\demo\1.txt"); File[] files = fileDir.listFiles(); for (File file : files) { System.out.println(file.getAbsolutePath()); } } } listFiles():过滤器 案例: Java.io.File.listFiles(FileFilter filter) 返回抽象路径名数组,表示在目录中此抽象路径名表示,满足指定过滤器的文件和目录。 声明 以下是java.io.File.listFiles(FileFilter filter) 方法的声明: public File[] listFiles(FileFilter filter) 参数 filter - File filter 返回值 该方法返回抽象路径名数组,表示在目录中此抽象路径名表示,满足指定过滤器的文件和目录。 异常 SecurityException -- 如果安全管理器存在并且其SecurityManager.checkRead(java.lang.String) 方法拒绝对文件的读访问 例子 下面的例子显示 java.io.File.listFiles(FileFilter filter)方法的用法。 package com.yiibai; import java.io.File; import java.io.FileFilter; public class FileDemo { public static void main(String[] args) { File f = null; File[] paths; try{ // create new file f = new File("c:/test"); FileFilter filter = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } }; // returns pathnames for files and directory paths = f.listFiles(filter); // for each pathname in pathname array for(File path:paths) { // prints file and directory paths System.out.println(path); } }catch(Exception e){ // if any error occurs e.printStackTrace(); } } } 让我们编译和运行上面的程序,这将产生以下结果: c:testchild_test.txt c:testchild_test.xlsx * 递归:是一个算法,只要含有方法这种概念的编程语言都可以使用 * 就是在一个方法内部,调用了自己 * StackOverflowError:堆栈溢出错误(内存溢出) * 递归:1.不能无限的调用自己,必须有出口 * 2.必须保证递归调用方法的次数有一定限制 * 递归在JavaEE开中用的还是比较少的 * 而且递归有一个致命的缺点:急剧消耗内存(建议:实际开发能不用就不用) * 递归的分类: * 直接递归: A方法内部调用A方法 * 间接递归: A方法内部调用B B方法内部调用C .... Z方法内部调用A * 递归的练习: * 递归的代码演示,计算1-n之间的和,使用递归完成 * 1.使用递归: a.确定规律(分解式子) b.确定出口 * 递归的代码演示: 计算第100个斐波那契数列的元素的值 * a.确定规律(分解式子) b.确定出口 * 第一百个斐波那契数列的元素的值 f(100) = f(99)+f(98) * ... * f(1) = 1 f(2) = 1 * 世界一个著名的算法 汉诺塔算法 * 求斐波那契数列的前20个数和 */ 1+1+2+3+5+8+12+20 public class DiGuiDemo01 { public static int getSum1(int a,int b){ //a = 1,b = 1 if(b >((b-1)+(b-2)) { return sum; } int temp = b; b = a + b ; a = temp; sum = b + getsum1(a,b); return sum ;b + getsum1(a , b);//b = 2,a = 1;b = 3,a = 2;b = 5, } public static void main(String[] args) { // TODO Auto-generated method stub // int num = getSum(1000); // System.out.println(num); long num = getFBNum(30);//1 1 2 3 5 8 13 21 34 55 System.out.println(num); } /* * 求第100个斐波那契数列的元素的值 */ public static long getFBNum(int n){ if(n==1 || n == 2){ return 1; } return getFBNum(n-1)+getFBNum(n-2); } /* * 写一个方法求1-n的和 * 1+2+...+n=== f(n) * 1+2+...n-1 === f(n-1)+n * f(n) = f(n-1)+n; * f(n-1) = f(n-2)+(n-1) * f(n-2) = f(n-3)+n-2.. * .... * f(2) = f(1)+2 * f(1) = 1 */ public static int getSum(int n){ if(n == 1){ return 1; } return getSum(n-1)+n; // int sum = 0; // for (int i = 1; i< n+1; i++) { // sum+=i; // } // return sum; } public static void demo01(){ System.out.println("demo01"); demo01(); } } import java.io.File; /* * 需求: 给你一个文件夹的File对象 * 要求列出该文件夹下所有文件(如果包括有文件夹,那么要求也要列出子文件夹下的文件) */ public class FileDiGuiDemo { public static void main(String[] args) { // TODO Auto-generated method stub showFiles(new File("D:\")); } /* * 定义方法:列出一个文件夹的File对象的中的文件 */ public static void showFiles(File fileDir){//参数代表一个文件夹的File对象 if(fileDir==null || fileDir.isFile()){ System.out.println("我要的是一个文件夹的File,文件的File不行!"); return; } File[] files = fileDir.listFiles(); if(files==null){ return; } for (File file : files) { if(file.isFile()){ System.out.println(file); }else if(file.isDirectory()){ //是一个文件夹 那么不管他 showFiles(file);//调用自己 ,传入一个文件夹 } } // File[] files = fileDir.listFiles(); // System.out.println(files); // System.out.println(files.length); } } /* * File中的另外一个方法: * File[] listFiles(FileFilter filter);//列出当前文件夹下 我们要求的File对象 * */ public class FilterDemo01 { public static void main(String[] args) { // TODO Auto-generated method stub //1.创建文件夹对象 File fileDir = new File("F:\demo"); //2.调用方法 //2.1先创建一个过滤器的实现类对象 FileFilter ff = new FileFilter(){ @Override public boolean accept(File pathname) { // TODO Auto-generated method stub if(pathname.getName().length()<= 6){ return true; } return false; } }; File[] files = fileDir.listFiles(ff); System.out.println(files.length); for (File file : files) { System.out.println(file); } } } /* * 策略设计模式: * 核心思想:把逻辑和算法分离,提高程序的扩展和灵活性. * * 核心技术:把方法作为参数传递(传递的一个接口的实现类) * * 自定义一个工具类 MyCollections 提供一个静态方法sort用来排序数组 * 自定义一个工具类 MyCollections 提供一个静态方法sort用来字符串数组 */ public class CeLveDemo2 { public static void main(String[] args) { demo01(); System.out.println(); demo02(); } public static void demo02() { String[] strs = {"java","hello","world","heimama","baiducn","man","idaidaodo"}; MyCollections.sortString(strs, new CompareStringInterface() { @Override public boolean compare(String str1, String str2) { // TODO Auto-generated method stub if(str1.charAt(0)>str2.charAt(0)) { return true; } return false; } }); for(String string : strs) { System.out.print(string + " "); } System.out.println(); } /* * 排序int 数组 * */ public static void demo01() { int[] num3 = {2,56,3,5674,67,43,35,67890}; MyCollections.sort(num3, new CompareInterface() { @Override public boolean compare(int num1, int num2) { // TODO Auto-generated method stub if(num1< num2) { return true; } return false; } }); for(int num : num3) { System.out.print(num + " "); } } } public class MyCollections { private MyCollections() {} public static void sort(int[] nums,CompareInterface ci) { //冒泡 for(int i = 0; i< nums.length -1; i++) { for(int j = 0 ; j< nums.length - 1- i; j++) { //交换 int temp = nums[j]; nums[j] = nums[j+1]; nums[j+1] = temp; } } } /* * 字符串排序 */ public static void sortString(String[] arr,CompareStringInterface sci) { for(int i = 0; i< arr.length-1 ; i++) { for(int j = 0; j< arr.length-1-i; j++) { //比较 arr[j] arr[j+1] if(sci.compare(arr[j], arr[j+1])) { String str = arr[j]; arr[j] = arr[j+1]; arr[j+1] = str; } } } } } interface CompareInterface { public abstract boolean compare(int num1,int num2); } interface CompareStringInterface { public abstract boolean compare(String str1,String str2); } File file = new File("demo02.txt"); //文件的大小 System.out.println(file.getTotalSpace()); //File对象的路径名 System.out.println(file.getPath()); //文件的绝对路径 System.out.println(file.getAbsolutePath()); /* import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; public class Test5 { public static void main(String[] args) { File file = new File("D:\新建文件夹\新建文件夹"); System.out.println(file); /* FileFilter ff = new FileFilter() { @Override public boolean accept(File pathname) { //File file = new File(pathname); return pathname.isFile() && pathname.getName().endsWith(".txt"); //return false; } }; File[] list = file.listFiles(ff); for (File file2 : list) { System.out.println(file2); } */ /* File[] files = file.listFiles(new FileFilter() { //把文件夹下面的所有文件包括文件夹进行判断,如果返回true则添加到File[] files数组中 @Override public boolean accept(File pathname) {//这个File pathname : 表示的是这个是路径的File对象 // TODO Auto-generated method stub //File file = new File(pathname); System.out.println(pathname); return true; } });*/ /*File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { //File dir :这个是盘符的意思(也就是文件名称以前的东西),name : 这个是文件名称 // TODO Auto-generated method stub File file = new File(dir,name); return file.isFile() && file.getName().endsWith(".txt"); } });*/ File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { // TODO Auto-generated method stub System.out.println(dir); System.out.println(name); return true; } }); /*for (File file2 : files) { System.out.println(file2); }*/ } } */ /* File : renameTo(File file) : 重命名的方法(将原先的File对象的名字修改为一个新的File对象) * newLine() 与 rn的区别 * newLine()是跨平台的方法 * rn只支持的是windows系统 标准读写字符流操作 *将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换 * 分析: * 1.创建输入输出流对象 * 2.创建集合对象 * 3.将读到的数据存储在集合中 * 4.倒着遍历集合将数据写到文件上 * 5.关流 * 注意事项: * 流对象尽量晚开早关 */ public class Tet1 { public static void main(String[] args) throws IOException { //改写后尽量晚开早关 //1.创建输入输出流对象 BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); //2.创建集合对象 ArrayListlist = new ArrayList<>(); //3.将读到的数据存储在集合中 String line; while((line = br.readLine()) != null) { list.add(line); } br.close(); BufferedWriter bw = new BufferedWriter(new FileWriter("yyy.txt")); //4.倒着遍历集合将数据写到文件上 for(int i = list.size() -1; i >= 0;i--) { bw.write(list.get(i)); bw.newLine(); } //关流 bw.close(); } } public class Demo5_LineNumberReader { public static void main(String[] args) throws IOException { //多了一个行号:可以添加行号 LineNumberReader lnr = new LineNumberReader(new FileReader("xxx.txt")); String line; //添加的行号以101开始的 lnr.setLineNumber(100); while((line = lnr.readLine()) != null) { System.out.println(lnr.getLineNumber() + ":" + line); } lnr.close(); } } /* * 装饰设计模式:耦合性不强,被装饰的类的变化与装饰类的变化无关 */ public class Demo_Wrap { public static void main(String[] args) { HeiMaStudent hms = new HeiMaStudent(new Student()); hms.code(); } } interface Coder { public void code(); } class Student implements Coder { @Override public void code() { // TODO Auto-generated method stub System.out.println("javase"); System.out.println("javaweb"); } } class HeiMaStudent implements Coder { //获取学生引用(获取学生对象) //获取被装饰类的引用 private Student s; //2.在构造方法中传入被装饰类的对象 public HeiMaStudent(Student s) { this.s = s; } //3.对原有的的功能进行升级 @Override public void code() { // TODO Auto-generated method stub s.code(); System.out.println("ssh"); System.out.println("数据库"); System.out.println("大数据"); System.out.println("..."); } } public class Demo7_TransTo { public static void main(String[] args) throws IOException { //method(); //method1(); /* * BufferedReader -- InputStreamReader(字节流,编码表)字节通向字符的桥梁,通过指定的编码表将字节转换为字符.---FileInputStream -- ut-8txt * BufferedWriter -- OutputStreamWriter(字节流,编码表)字符通向字节的桥梁,通过指定的编码表将字符转换为字节 -- FileOutputStream -- gbk.txt * * */ //更高效的读 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8")); //更高效的写 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk")); int c; while((c = br.read()) != -1) { bw.write(c); } br.close(); bw.close(); } private static void method1() throws UnsupportedEncodingException, FileNotFoundException, IOException { //指定码表读字符 InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"uTf-8"); //指定码表写字符 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"); int c; while((c = isr.read()) != -1) { osw.write(c); } isr.close(); osw.close(); } private static void method() throws FileNotFoundException, IOException { //用默认编码表读写,出现乱码 FileReader fr = new FileReader("utf-8.txt"); FileWriter fw = new FileWriter("gbk.txt"); int c; while(( c = fr.read()) != -1) { fw.write(c); } fr.close(); fw.close(); } } /* * 当我们下载一个试用软件,没有购买正版的时候,每执行一次就会体系我们换有多少次使用机会用学过的IO流只是,模拟试用版软件 * 使用10次机会,执行一次就提示一次您换有几次机会,如果次数到了 * 分析: * 1.创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性 * 2.将读到的字符串转换为int数 * 3.对int数进行判断,如果大于零,就将其--写回去,如果不大于零,就提示请购买正版 * 4.在if判断中要将--的结果打印,并将结果通过输出流写到文件上 * 5. */ public class Test2 { public static void main(String[] args) throws IOException { //1.创建带缓冲的输入流对象,因为要使用readLine方法,可以保证数据的原样性 BufferedReader br = new BufferedReader(new FileReader("config.txt")); //2.将读到的字符串转换为int数 String line = br.readLine(); //System.out.println(line); //将数字字符串转换为数字 int times = Integer.parseInt(line); //3.对int数进行判断,如果大于零,就将其--写回去,如果不大于零,就提示请购买正版 if(times >0) { //4.在if判断中要将--的结果打印,并将结果通过输出流写到文件上 System.out.println("您还有" + times-- + "次机会"); FileWriter fw = new FileWriter("config.txt"); fw.write(times + ""); fw.close(); }else { System.out.println("您的试用次数已到,请购买正版"); } br.close(); } } * 递归:方法字节调用自己 * 递归的弊端:不能调用次数过多,容易导致栈内存溢出 * 递归的好处:不用知道循环次数 * 构造方法用不能使用递归调用 * 递归调用不一定必须有返回值 * IO流对象: 数据进行读取和写入 * Input:数据读取 * Output:数据写出 Java中IO流分类: 按照操作数据分类 字节流:能读所有任意的文件 字符流:只能读写文本文件,((只要能用文本工具打开而且打开后还能看懂的)(记事本,notepad++等等)这些都是文本文件) 文本文件有:.txt,.java.html,.css,.其他编程语言的源码 注意:world,excel,ppt都不是文本文件 按照数据的流向分类 输入流:从外界设备 读取数据 到内存; 输出流:从内存写数据 到外界设备. 总结:总共有四种流 1.字符输入流:reader是根类(基类)(抽象类) 方法:read(读一个字符,读一个字符数组) FileReader,BufferedReader 2.字符输出流 :writer是根类(基类)(抽象类) 方法:writer(写一个字符,写一个字符数组(一部分),写一个字符串(一部分) FileWriter,BufferedWriter 3.字节输入流: InputStream(基类)(抽象类) 方法:read(一个字节,读一个字节数组) FileInputStream 4.字节输出流:OutputStream(基类)(抽象类) 方法:writer(写一个字节,写一个字节数组(一部分) FileOutputStream java中的流命名十分讲究: 功能+流的基类(FileReader,OutputStream) OutputStream:字节输出流根类 1.public voidwrite(int b) ; 写一个字节 2. * InputStream:字节输入流(读数据) * 子类:FileInputStream * 1.public int read();//读取一个字节 * 2.public int read(byte[] bs);//读取一个字节数组 */ public class InputStreamDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建字节输入流对象(多态) InputStream is = new FileInputStream("a.txt"); /* * 1.创建了一个字节输入流对象 * 2.如果文件不存在 那么报错 * 3.把流指向文件 */ //2.一次读取一个字节 //int b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100 //System.out.println((char)b);//0000 0000 0101 0100 //b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100 //System.out.println((char)b);//0000 0000 0101 0100 //3.一次读取一个字节数组 byte[] bs = new byte[4]; int len = is.read(bs); System.out.println(len); System.out.println(new String(bs,0,len)); //再读一次 len = is.read(bs); System.out.println(len); System.out.println(new String(bs,0,len)); } } * OutputStream:字节输出流根类 * 子类:FileOutputStream * 1.public void write(int b);//写一个字节 * 2.public void wirte(byte[] bs);//写一个字节数组 * 3.public void wirte(byte[] bs,int start,int len);//写一个字节数组的一部分 * 追加问题: * 只要创建流的时候; * new FileOutputStream("a.txt",true); * 换行问题: * windows: rn * Linux: n * Mac Os: r */ public class OutputStreamDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建一个文件的字节输出流(多态的方式) OutputStream os = new FileOutputStream("a.txt"); /* * 1.创建了一个字节输出流对象 * 2.如果文件不存在,创建这个文件对象 * 3.让这个流指向这个文件 */ //2.调用写数据方法 write //写一个字节 // os.write(106); // os.write(97); // os.write(118); // os.write(97); //写一个字节数组 ILOVEYOUTIGER // byte[] bs = {106,97,118,97,97,97}; //byte[] bs = "ILoveJavaEE".getBytes(); //写"中国我爱你" // byte[] bs1 = "中国我爱你".getBytes(); // System.out.println( bs1.length); // System.out.println(bs1[0]); // System.out.println(bs1[1]); // os.write(bs1); //写一个字节数组的一部分 // byte[] bs = "中国我爱你".getBytes(); // os.write(bs, 0, 6); for(int i = 0;i< 10;i++){ os.write("我爱你中国".getBytes()); os.write("rn".getBytes()); } //3.关闭流 os.close(); } } /* * 字节流复制文件(可以复制任意文件) C:UsersyingpengDesktoppictures3.png * 1.源文件 : 3.png---->FileInputStream * 2.目标文件: copy.png---->FileOutputStream */ public class CopyFileDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建流对象(2个,一个读 一个写) FileInputStream fis = new FileInputStream("C:\Users\yingpeng\Desktop\pictures\3.png"); FileOutputStream fos = new FileOutputStream("copy.png"); //2.一边读取数据 一边写入数据 //a.一次读取一个字节 写入一个字节 // int b = fis.read(); // fos.write(b); //标准代码================== // int b = 0; // while( (b = fis.read())!=-1){ // fos.write(b); // } //b.一次读取一个字节数组 long s = System.currentTimeMillis(); //标准代码 byte[] bs = new byte[1024];//保存读取到的数据 int len = 0;//保存实际读取到的字节数 while( (len = fis.read(bs))!=-1 ){ fos.write(bs,0,len); } //3.释放资源 fos.close(); fis.close(); long e = System.currentTimeMillis(); System.out.println(e-s); } } * FileReader---->BufferedReader * FileWriter---->BufferedWriter * FileInputStream---->BufferedInputStream * FileOutputStream----->BufferedOutputStream * 1.BufferedOutputStream:字节缓冲输出流(写数据) * public BufferedOutputStream(OutputStream out) * a.public void write(int b); * b.public void write(byte[] bs); * c.public void wirte(byte[] bs,int start,int len); */ public class BufferedDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建字节缓冲输出流对象 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt")); //2.调用bos的写数据方法 //写一个字节 // bos.write(49); // bos.write(48); // bos.write(48); //写一个字节数组 // byte[] bs = {49,48,48,48}; // bos.write(bs); //写 "helloworld" // byte[] bs = "helloworld".getBytes(); // bos.write(bs); byte[] bs = "凤a姐".getBytes(); System.out.println(bs.length); bos.write(bs,2,3); //3.关闭流 bos.close(); } } /* * BufferedInputStream-->字节缓冲输入流(读数据) * 构造: * public BufferedInputStream(InputStream in) * 练习:使用BufferedInputStream读取一个txt文件打印到控制台 */ public class BufferedInputStreamDemo { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建字节缓冲输入流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ArrayList.java")); //a.一次读取一个字节 // int b = 0;//保存读取到字节 // while((b = bis.read())!=-1){ // System.out.print((char)b); // } //b.一次读取一个字节数组 int len = 0;//实际读取的个数 byte[] bs = new byte[1024]; while((len=bis.read(bs))!=-1){ System.out.print(new String(bs,0,len)); } //3.关闭 bis.close(); } public static void demo01() throws IOException{ //1.创建字节缓冲输入流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.txt")); //调用bis的读数据方法 //a.一次读取一个字节 // int b = bis.read(); // System.out.println((char)b); //b.一次读取一个字节数组 // byte[] bs = new byte[2]; // int len = bis.read(bs); // System.out.println(len); // System.out.println(new String(bs,0,len)); // // len = bis.read(bs); // System.out.println(len); // System.out.println(new String(bs,0,len)); //3.关闭 bis.close(); } } */ /* /* * 内存输出流:该输出流可以向内存中写数据,把内存当作一个缓冲区,写出之后 * FileInputStream读取中文的时候会出现乱码 * 解决方案: * 1.使用字符流 * InputStream:字节输入流(读数据) * 子类:FileInputStream * 1.public int read();//读取一个字节 * 2.public int read(byte[] bs);//读取一个字节数组 */ public class InputStreamDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //1.创建字节输入流对象(多态) InputStream is = new FileInputStream("a.txt"); /* * 1.创建了一个字节输入流对象 * 2.如果文件不存在 那么报错 * 3.把流指向文件 */ //2.一次读取一个字节 //int b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100 //System.out.println((char)b);//0000 0000 0101 0100 //b = is.read();//0000 0000 0000 0000 0000 0000 0101 0100 //System.out.println((char)b);//0000 0000 0101 0100 //3.一次读取一个字节数组 byte[] bs = new byte[4]; int len = is.read(bs); System.out.println(len); System.out.println(new String(bs,0,len)); //再读一次 len = is.read(bs); System.out.println(len); System.out.println(new String(bs,0,len)); } } */ public class DmeoByteArrayOutputStream { public static void main(String[] args) throws IOException { //emthod(); //在内存中创建了可以增长的内存数组 FileInputStream fis = new FileInputStream("e.txt"); //ByteArrayOutputStream不用关流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b; //将读取到的数据逐个写到内存中 while ((b = fis.read()) != -1) { baos.write(b); } // //将缓冲区的数据全部获取出来,并赋值给arr数组 //他可以使用指定的编码表转换 byte[] arr = baos.toByteArray(); System.out.println(new String(arr)); //使用的是默认的编码表进行转换输出 //将缓冲区的内容转换为了字符串,在输出语句中可以省略调用toString()方法 System.out.println(baos.toString()); fis.close(); } //使用字符流解决问题中文输入问题 private static void emthod() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("e.txt"); byte[] arr = new byte[3]; int len; while((len = fis.read(arr)) != -1) { System.out.println(new String(arr,0,len)); } fis.close(); } } /* public class Test { public static void main(String[] args) throws IOException { //创建流对象(2个,一个读,一个写) //一次读取一个字节数组 FileInputStream fis = new FileInputStream("韩雪 - 想起.mp3"); FileOutputStream fos = new FileOutputStream("Copy.mp3"); //标准代码 //保存读到到的数据 byte[] bs = new byte[1024]; //保存实际读取到的字节数 int len; while((len = fis.read(bs)) != -1) { fos.write(bs,0,len); } //3.释放资源 fos.close(); fis.close(); } } * 复制单级文件夹: * 0.创建目标文件夹(如果不存在) F:\test * 1.创建一个File对象(代表要复制的源文件夹) E:\demo * 2.调用File对象的listFiles方法 获取文件夹中所有的文件对象 * 3.挨个复制文件对象 到 目标文件夹中 * 源文件 E:\demo\1.txt--->目标文件 F:\test\1.txt */ public class CopyDirectoryDemo { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //0.创建目标文件夹(如果不存在) F:\test File fileDest = new File("F:\test"); if(!fileDest.exists()){ fileDest.mkdir(); } //1.创建源文件夹的File对象 File fileSrc = new File("E:\demo"); //调用fileSrc的listFiles File[] files = fileSrc.listFiles(); for (File file : files) { System.out.println(file);//源文件 E:demo1.txt File newFile = new File(fileDest,file.getName());//目标文件 F:\test\1.txt System.out.println(newFile); //复制文件 从file 复制到newFile copyFile(file,newFile); } } public static void copyFile(File file, File newFile) throws IOException { // TODO Auto-generated method stub //复制文件 源文件 file 目标文件 newFile BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); //循环读取文件 写入文件 int len = 0; byte[] bs = new byte[1024]; while((len= bis.read(bs))!=-1){ bos.write(bs, 0, len); } //关闭流 bis.close(); bos.close(); System.out.println("复制文件"+file.getAbsolutePath()+"成功!"); } } * 求前n个斐波那契数列的元素之和 * 1.求第n个斐波那契数列的元素 * f(n) = f(n-1)+f(n-2) * f(2) = 1 * f(1) = 1 * 2.求前n个斐波那契数列的元素之和 * sum(n) = sum(n-1)+ getFBNum(n) * sum(1) = 1 * 留一个题: * 求前n个数的和 * 1 1+2 1+2+3 1+2+3+4 1+2+3+4+5 第n个数为 1 3 6 10 15 */ public class DiGuiDemo { public static int sum(int n) { if(n == 1) { return 1; } return n + sum(n-1); //n = 3,(3+2+1) } public static int getSum(int n) { if(n == 1) { return 1; } return sum(n) + getSum(n-1); } public static void main(String[] args) { // TODO Auto-generated method stub //测试 // int num = getFBNum(5); // System.out.println(num); int sum = getSum(6);//1 1 2 3 5 8 System.out.println(sum); } /* * 求第n个斐波那契数列的元素 */ public static int getFBNum(int n){ if(n==1){ return 1; } if(n==2){ return 1; } return getFBNum(n-1)+getFBNum(n-2); } /* *前n个元素之和 */ public static int getSum(int n){ if(n==1){ return 1; } //sum(n) = sum(n-1)+ getFBNum(n) return getSum(n-1)+getFBNum(n); } } * Properties类:是Map接口的一个实现,具有map接口下的所有功能 * 没有泛型,Key和Value都是String类型 * 1.put(String key,String value)---->setProperty(String key,String value) * 2.get(String key)---->getProperty(String key); * 3.删除方法 还是使用 map接口中的remove方法 * 4.keySet();//以键找值 ----->SetstringPropertyNames(); * 5.entrySet();//键值对 只要map中有 * 持久属性集的用法: * public void store(OutputStream out, String comments); * 把属性集Properties对象中数据保存到 一个输入流中 * public void load(InputStream inStream); * 从输入流中加载数据 */ public class PropertiesDemo { public static void main(String[] args) throws IOException { // //1.创建一个Properties对象 // Properties ps = new Properties(); // //2.添加数据 // ps.setProperty("zhangsan", "18"); // ps.setProperty("lisi", "28"); // ps.setProperty("rose", "38"); // ps.setProperty("jack", "48"); // //3.保存数据 // ps.store(new FileOutputStream("abc.properties"), ""); //4.从输入流中加载数据 Properties ps = new Properties(); System.out.println(ps); ps.load(new FileInputStream("abc.properties")); System.out.println(ps); } /* * 基本用法 */ public static void demo01(){ //1.创建一个Properties对象 Properties ps = new Properties(); //2.添加数据 ps.setProperty("zhangsan", "18"); ps.setProperty("lisi", "28"); ps.setProperty("rose", "38"); ps.setProperty("jack", "48"); //System.out.println(ps); // String value = ps.getProperty("jack"); // System.out.println(value); //遍历ps集合 SetnamesSet = ps.stringPropertyNames(); //foreach或者迭代器 for (String name : namesSet) { String value = ps.getProperty(name); System.out.println(name+"="+value); } } } /* * 一个文件夹复制到另外一个盘符下(这个被复制的文件夹里面有还有文件夹,文件夹里面还有文件.) * 复制多个文件夹以及内容进行复制 * 分析: * 1.创建新的文件路径(这个是需要复制到的位置)对象,再创建一个路径对象 * 2.定义方法,这个方法里面判断当前文件夹下面所有的文件, * 3.如果是文件用方法进行复制, * 4.如果是文件夹就用新的file对象去封装成一个新的盘符路径,再把新的盘符路径和这个循环出来的文件进行递归 */ public class Test5 { public static void main(String[] args) throws IOException { File file = new File("F:\demo"); File newFile = new File("E:\dmeo2"); method(file,newFile); } //用方法进行递归判断寻找文件并创建文件夹 public static void method(File file,File newFile) throws IOException { File[] files = file.listFiles(); for (File file2 : files) { if(file2.isDirectory()) { File file3 = new File(newFile,file2.getName()); file3.mkdirs(); method(file2,file3); }else { File file4 = new File(newFile,file2.getName()); copy(file2,file4); } } } //用方法进行文件复制 private static void copy(File file2, File file4) throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream(file2); FileOutputStream fos = new FileOutputStream(file4); byte[] b = new byte[1024]; int i; while((i = fis.read(b)) != -1) { fos.write(b, 0, i); } fis.close(); fos.close(); } } UTF-8:字母代表一个字节,汉子代表三个字节 GBK : 字母是一个字节,汉子是两个字节 public static void main(String[] args) throws IOException { //1.封装源目录: File srcDir = new File("D:\单级目录"); //2.封装目标目录: File destDir = new File("E:\"); //3.判断目标目录下是否包含要复制的目录: destDir = new File(destDir,srcDir.getName());//new File("E:\单级目录"); if(!destDir.exists()){ destDir.mkdir();//创建目录 } //4.获取源目录下所有子文件的File数组; File[] fileArray = srcDir.listFiles(); if(fileArray!= null){ //5.遍历数组,获取每个File对象; for(File f : fileArray){ //针对每个File对象创建独立的输入流(字节流) FileInputStream in = new FileInputStream(f); //并向目标位置创建独立的输出流(字节流) FileOutputStream out = new FileOutputStream(new File(destDir,f.getName())); //开始复制-->一次复制一个字节数组 byte[] byteArray = new byte[1024 * 8]; int len = 0; while((len = in.read(byteArray)) != -1){ out.write(byteArray,0,len); } out.close(); in.close(); } } System.out.println("复制完毕!"); } <上一题 public static void main(String[] args) throws Exception { //创建源目录 File file = new File("D:/java"); //获取文件 File[] files = file.listFiles(); //创建输入流对象 InputStream in = null; //创建输出流对象 OutputStream out = null; //记录源文件夹中文件的名称 String fileName = null; // 记录 目标文件夹中文件的名称 String destName = null; //指定目标文件夹 File f = new File("D:/jad"); //遍历 for (File file2 : files) { in = new FileInputStream(file2); //查看 目标文件夹 是否存在 if(!f.exists()){ f.mkdir(); } //获取源文件夹中文件的名称 fileName = file2.getName(); destName = fileName; //创建复制的文件输出流 out = new FileOutputStream(new File("D:/jad/"+destName)); int len = 0; byte[] b = new byte[1024]; //完成复制 while((len = in.read(b))!= -1){ out.write(b, 0, len); //System.out.println(new String(b,0,len)); } } } <上一题 1.删除目录主要用到的知识:File类和递归。 2.本题的完整代码为: public class Test { public static void main(String[] args) { delete(new File("D:/a")); } public static void delete(File f) { // 判断是否是文件夹 if (f.isDirectory()) { File[] files = f.listFiles(); for (File file : files) { delete(file); file.delete(); } } // 删除操作 f.delete(); } } public static void main(String[] args) throws Exception { //1、明确源文件与目的地 File sourse = new File("E:1.mp3"); File order = new File("E:\1_copy.mp3"); //2、创建两个流对象 FileOutputStream out = new FileOutputStream(order); FileInputStream in = new FileInputStream(sourse); //3、循环读,并且将每一次读到的内容都使用输出流输出到目的地 int len = -1; byte[] b = new byte[1024]; while((len = in.read(b))!=-1){ //4、说明内容有效,文件还没有结束,可以循环读 //5、此时向目的地写数组中的内容,要明确有效数据的个数 out.write(b,0,len); } //5、循环结束后,就复制完成了,关闭资源 out.close(); in.close(); } package cn.baidu04_Test; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 复制文件夹(含子文件夹) * 需求: D:\YesDir 文件夹 复制到 当前项目下的 Copy目录中 * 分析: * 数据源 --- D:\YesDir 文件夹 * 目的地 --- Copy 文件夹 * 1.找到数据源,看数据源是否存在 * 指定目的地 * 2.看是否有目的地文件夹 * 如果没有目的地文件夹,创建目的地文件夹 * 3.获取数据源中所有的File对象 * 4.通过遍历,得到数据源中每一个File对象 * 5.判断是否为文件夹 * 是:说明是文件夹, 进入到子文件夹中 * file -- D:\YesDir\小视频 * 完成子文件夹的复制 * a.找到数据源,看数据源是否存在 * file -- D:\YesDir\小视频 * b,指定目的地 * dest -- Copy\小视频 * 子文件夹名称 = 目的地文件夹 当前要复制的File目录的名称 * c, 递归,回到步骤2 * 否:说明是文件,复制文件 * file -- D:YesDir大话西游.mp3 * a,指定数据源 file -- D:YesDir大话西游.mp3 * b,指定目的地 dest -- Copy大话西游.mp3 * 目的地文件名称 = 目的地文件夹 + 当前要复制的File文件的名称 * c,读数据源中的数据 * d,把数据写到目的地 * e,关闭流 */ public class CopyDirs { public static void main(String[] args) throws IOException { //1.找到数据源,看数据源是否存在 File srcPath = new File("D:\YesDir"); //2.目的地 //File destPath = new File("D:\YesDir\Yes"); --》死循环复制(直到磁盘满,不能删除,得使用递归删除或者使用360强制删除) File destPath = new File("Copy"); //3,开始进行复制文件夹 copyDir( srcPath, destPath); } //复制文件夹的方法 private static void copyDir(File srcPath, File destPath) throws IOException { /首先 感叹号 是‘非’的意思, f应该是一个对象的实例,这里应该是file对象, exists(), 是f那个实例对应的对象的方法 从名字看 是是否存在的意思, 连起来的意思就是: f这个文件对象是不是不存在 //2.看是否有目的地文件夹,如果没有目的地文件夹,创建目的地文件夹 if (!destPath.exists()) { destPath.mkdir(); } //3.获取数据源中所有的File对象 File[] files = srcPath.listFiles(); if (files == null) { System.out.println(srcPath); //System.out.println("该文件夹是受系统保护的文件夹,它拒绝访问!"); return ; //这样处理的好处是,保证程序不会出现NullPointerException } //4.通过遍历,得到数据源中每一个File对象 for (File file : files) { //5.判断是否为文件夹 if (file.isDirectory()) { //是:说明是文件夹, 进入到子文件夹中 //file -- D:\YesDir\小视频 //dest -- Copy\小视频 //子文件夹名称 = 目的地文件夹 当前要复制的File目录的名称 File dest = new File(destPath, file.getName()); copyDir(file, dest);//这里写dest为了创建子文件夹 } else { //否:说明是文件,复制文件 //file -- D:YesDir大话西游.mp3 //dest -- Copy大话西游.mp3 //目的地文件名称 = 目的地文件夹 + 当前要复制的File文件的名称 File dest = new File(destPath, file.getName()); copyFile(file, dest);//这里的dest是要复制到新的文件名称 } } } //复制文件 private static void copyFile(File file, File dest) throws IOException { //指定数据源 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); //指定目的地 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest)); //读 byte[] buffer = new byte[1024]; int len = -1; while ( (len = bis.read(buffer)) != -1) { //写 bos.write(buffer, 0, len); } //关闭流 bos.close(); bis.close(); } } * 计算机中只能识别是0101010101001 * 1.老美 想了一个办法 把英文和英文符号----->对应成一个10进制数字------>转成2进制---->电脑 * A---65 a---97 0---48 * 2.ASCII码表,把所有的英文和符号 对应了一个十进制(所有其他码表都必须兼容它) * 3.GB2312: 把常用中文(6000-7000),一一对应成数字,中文两个字节 * 4.GBK: 把基本所有的中文(20000多个),一一对应成数字,中文两个字节 * 5.Unicode(万国码表):在这个码标中,所有的字符 都是两个字节 * A----65---- 0000 0000 0100 0001 * 6.UTF-8:(基于Unicode),一个字节能表示的字符,坚决不用两个字节 * 英文1个字节, 中文(3个字节) * 常用的中文码表:GBK(中文2个字节),UFT-8(中文3字节) * 流的分类: * 根据操作的数据: * 字节流 * 字符流 * 根据数据的流向; * 输入流 * 输出流 * java中四大流 * 字节输入流:InputStream * 读取数据read:一个字节,一个字节数组 * 字节输出流:OutputStream * 写出数据write:一个字节,一个字节数组 * 字符输入流:reader * 读取数据(read):一个字符,一个字符数组 * 字符输出流:writer * 写出数据(write):一个字符,一个字符数组,一个字符串 * java流命名是十分规范,比如:FileReader(字符输入流) */ public class IODemo02 { public static void main(String[] args) { // TODO Auto-generated method stub } } /* * OutputStreamWriter extends Writer (字符输出流) * write方法: 一个字符,一个字符数组, 一个字符串 * OutputStreamWriter 是字符流通向字节流的桥梁,查表(编号) * 构造方法: * public OutputStreamWriter(OutputStream out, String charsetName);//查指定的码表 * public OutputStreamWriter(OutputStream out);//默认查GBK码表 * InputStreamReader extends Reader (字符输入流) * 读取方法:一个字符,一个字符数组 * InputStreamReader 是字节流通向字符流的桥梁:查表(解码) * 构造方法: * public InputStreamReader(InputStream in, String charsetName);//查指定码表 * public InputStreamReader(InputStream in);//默认GBK码表 */ public class OutputStreamWriterDemo { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //创建一个流对象 // InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt")); InputStreamReader isr = new InputStreamReader(new FileInputStream("utf8.txt"),"GBK"); int ch = isr.read(); System.out.println((char)ch); ch = isr.read(); System.out.println((char)ch); ch = isr.read(); System.out.println((char)ch); isr.close(); } public static void demo01() throws IOException{ // OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt")); OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf8.txt"),"UTF-8"); //ows调用写数据方法 osw.write("你好"); //关闭 osw.close(); } } /* * 序列化流:写对象到字节输出流中,由字节输出流再去写文件 * ObjectOutputStream * 构造: * public ObjectOutputStream(OutputStream out); * 反序列化流:从字节输入流中读取数据,再解析成对象 * ObjectInputStream * 构造: * public ObjectInputStream(InputStream in); * 异常: * 1.只要写序列化的过程中出现NotSerializableException异常 * 那么肯定是 该类没有实现java.io.Serializable接口 * 2.如果出现这个异常InvalidClassException异常:找不到类异常 * 2.1 在写入对象之后,修改了原来的类,那么读取的时候就会InvalidClassException异常:找不到类异常 * 2.2该类包含未知数据类型 * 2.3该类没有可访问的无参数构造方法(写一个标准的类必须有无参构造) * 3.关于java.io.Serializable的问题: * 3.1一个类实现java.io.Serializable接口,而这接口中没有方法 * 这个接口就是一个标记,如果有标记可以序列化,如果没有标记不能序列化 * 3.2java为会这个类提供一个版本号,如果类修改了,那么这个版本号就会改变 * 就是通过这个版本号来表示类改没改变 * 4.瞬态关键字: transient * 这个关键字可以修饰成员变量,这个成员变量,当序列化的时候会被忽略 */ public class SerializableDemo01 { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub //writeObject(); readObject(); } public static void readObject()throws Exception{ //创建反序列化流对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt")); //调用ois读对象的方法 Object obj = ois.readObject(); //打印对象(obj对象实际上是Person对象) System.out.println(obj); } public static void writeObject()throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt")); //调用写对象的方法 Person p = new Person(10, "小王",10086); //java.io.NotSerializableException oos.writeObject(p); //关闭 oos.close(); } } /* * 打印流: * PrintWriter:可以打印到File对象,字符串形式的文件名中,字节输出流中,字符输出流中 * PrintStream:可以打印到File对象,字符串形式的文件名中,字节输出流中 * 以上两个流的用法完全一样 * 只有一点区别:打印的目的地有所不同 */ public class PrintDemo01 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub PrintWriter pw = new PrintWriter("aaa.txt"); pw.print("abc"); pw.print(true); pw.print(12); pw.close(); //我们以前用的 // System.out实际上就是一个打印流 } } /* * Properties类:实现了map接口,那么我们可以认为就是一个map集合(HashMap) * 1.Properties没有泛型,属性名和属性值,都是String类型 * 2.它是一个可以持久化的属性集(自带写数据到文件 ,从文件中读取数据) * 3.这些持久化的方法都是和流有关系的 * 特殊的成员方法: * 1. setProperty(String key,String value);//类似于map.put(K,V); * 2. public String getProperty(String key);//类似于map.get(K); * 3. public SetstringPropertyNames();//类似于map.keySet(); * 持久化相关的方法: * 将Properties对象中的数据 保存到文件中 * store(OutputStream out); * store(Writer w); * 将文件中的键值对 读取到Properties对象 * load(InputStream intput); * load(Reader r); * Properties通常作为配置文件 */ public class PropertiesDemo { public static void main(String[] args) throws IOException { readProperties(); } public static void readProperties() throws IOException{ Properties ps = new Properties();//就看成一个map集合 //读取数据 ps.load(new FileInputStream("abc.properties")); System.out.println(ps); } public static void writeProperties() throws IOException{ Properties ps = new Properties();//就看成一个map集合 ps.setProperty("zhangsna", "18"); ps.setProperty("alilbba", "28"); ps.setProperty("rose", "38"); ps.setProperty("jack", "48"); ps.setProperty("isAutoGengxin", "0"); //写数据到文件中 FileOutputStream fos = new FileOutputStream("abc.properties"); ps.store(fos, "a啊解放路啊fagg"); fos.close(); } /* * 演示基本方法 */ public static void demo01(){ //创建Properties对象 Properties ps = new Properties();//就看成一个map集合 ps.setProperty("zhangsna", "18"); ps.setProperty("alilbba", "28"); ps.setProperty("rose", "38"); ps.setProperty("jack", "48"); //System.out.println(ps); Setnames = ps.stringPropertyNames(); Iteratorit = names.iterator(); while(it.hasNext()){ String name = it.next(); String value = ps.getProperty(name); System.out.println(name+"="+value); }【Java基础教程系列第十五篇:深入解析IO流与递归算法】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
Java学到了第十五篇了?真是厉害啊!感觉我离学会Java还差好多
有9位网友表示赞同!
一直都很想了解一下IO流,这下终于可以学习了
有5位网友表示赞同!
递归算法听起来挺复杂的,希望能简单易懂地讲解
有10位网友表示赞同!
学习java的基础很重要,为将来写更复杂程序打基础
有6位网友表示赞同!
这篇文章会不会讲一些实际应用场景呢?那样更容易理解
有10位网友表示赞同!
希望代码实例能写的比较多,这样能更直观地理解算法
有13位网友表示赞同!
以前遇到递归问题总觉得摸不着头脑,希望能解开这个迷雾
有6位网友表示赞同!
学习java的同时也要了解这些基础知识,不会感觉学得很面面俱到
有5位网友表示赞同!
IO流和递归算法都是很有用的技能,希望掌握它们
有17位网友表示赞同!
现在很多编程语言都用到 IO 流和递归算法吧?
有9位网友表示赞同!
学习完了之后可以练一练实战项目吗?
有8位网友表示赞同!
这篇文章应该会很实用啊!以后开发的时候就能用上了
有19位网友表示赞同!
感觉Java的这十五篇基础知识涵盖得很全面了!
有20位网友表示赞同!
希望作者能把复杂的概念解释得更通俗易懂,能让初学者都能看明白
有12位网友表示赞同!
学习新的技能太兴奋了!期待这个文章能够深入浅出地讲解
有18位网友表示赞同!
这十五篇的知识点都很有用,可以作为学习java的基础
有5位网友表示赞同!
感觉学JAVA越来越有趣了!这些基础知识都是需要掌握的关键
有18位网友表示赞同!
继续努力学习,争取早日成为一名优秀的Java程序员
有7位网友表示赞同!
通过深入理解IO流和递归算法,可以提高编程能力!
有17位网友表示赞同!