递归

1、递归的概念: 在函数自身内部,调用函数本身的方式,称为递归。

2、递归的注意事项:包括递进去,归出来两步。
   即:首先依次执行【函数调自身语句】上半部分的代码,知道最里层。(递进去),然后 ,再从最里层开始,依此执行【函数调自身语句】下半部分代码。(归出去)

3、递归必须通过合适的语句及时的跳出,否则容易造成死循环。

使用递归计算阶乘:

 public class Demo01_digui {

     public static void main(String[] args) {

         Scanner in = new Scanner(System.in);
System.out.print("请输入一个数:");
int i = in.nextInt();
System.out.println(jiecheng(i));
; } public static long result = 1; public static long jiecheng(int num) {
result *= num;
num -= 1;
if (num > 0) {
jiecheng(num);
}
return result;
} }

File--文件

1.File的基本概念:Java文件类以抽象的方式代表文件名和目录路径。File对象代表磁盘中实际存在的文件和目录。通过以下构造方法创建一个File对象。

2.作用:主要用于文件和目录的创建、文件的查找和文件的删除等。

3.文件的分割(写法):可以使用"/"(通常用于Linux系统,widows也使用),"\\"(通常用于widows),注意一个"\"需要转义。

4.构造函数:

     //1.直接传入一个路径,拿到一个文件或者一个文件夹
File file1 = new File("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\tes.txt");
//2.第一个参数传入父路径,第二个参数传入子路径或者文件
File file2 = new File("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14", "tes.txt");
//3.第一个参数传入file对象,第二个参数传入子路径或者文件
File file3 = new File(file1, "tes.txt");

5.创建File对象成功后,可以使用以下列表中的方法操作文件。

(1)file.canRead():判断文件是否可读.返回true/false
(2)file.canWrite():判断文件是否可写.返回true/false
(3)file.equals():判断两个文件是否相等
(4)file.exists():检测文件是否存在
(5)file.getAbsolutePath():获取文件的绝对路径。
(6)file.getName():取到一个文件名或者文件夹名
(7)file.getPath():取到当前文件或者文件夹的父路径
(8)file.isAbsolute():判断当前文件是否是绝对路径
(9)file.isDirectory():检测当前文件是否是个目录(文件夹)。
(10)file.isFile():检测当前路径是否是文件。
(11)file.delete():删除文件。返回true/false(文件夹中包含内容的时候不可以删除)
(12)file.android():创建新的文件。返回true/false
(13)file.mkdir():创建新的一层路径(文件夹),只有当文件夹不存在时才能创建成功。如果file中有一层不存在就没法往下创建。
(14)file.mkdirs():创建多层路径。只要有没有的就可以创建。
(15)file.getTotalSpace():获得文件分区的总大小。
(16)file.getUsableSpace():获得文件分区的可用大小。
(17)file.lenght():返回当前文件或文件夹的大小。
(18)file.list():返回当前目录中的文件和文件夹的名字,返回值类型为String类型的数组。
(19)file.list(FilenameFilter filenameFilter):它传入的是个接口重写accept()方法,返回true显示所有,返回false全不显示。
(20)file.listFiles():返回当前目录中的文件和文件夹的目录,返回值类型是File类型的数组。同样可以对其进行过滤:FilenameFilter 和FileFilter两种过滤方法。
(21)file.renameTo(file2):重命名一个文件,要求传入一个心的.

练习:删除磁盘规定文件目录下的文件夹及其所有文件

public class Demo02_File {

    public static void main(String[] args) {

        File file = new File("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test");

        search(file);

    }

    //删除文件夹及其所有的文件
public static void search(File file) { if(file.isFile()){
file.delete();
}else if(file.isDirectory()){ File[] f = file.listFiles(); for (File file2 : f) {
search(file2);
}
file.delete();
}
} }

I/O流

I/O流概述

1.概念:IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数据传输,Java对于数据的操作都是通过流实现,而java用于操作流的对象都在IO包中。

2.分类:

根据流的方向:输入流和输出流。
根据读取文件的大小:字节流和字符流。
根据读取的方式:结点流和缓存流。

3.输入流和输出流:

所有输入流类都是抽象类InputStream(字节输入流),或者抽象类Reader(字符输入流)的子类;
所有输出流都是抽象类OutputStream(字节输出流),或者抽象类Writer(字符输出流)的子类。
字节流按字节读取,只能读取字符,读取中文会乱码。字符流读取中文。

基本流--FileInputStream/FileOutputStream

FileInputStream的单个字节读取:FileInputStream in = new FileInputStream("text.txt");
FileOutputStream的单个字节写入:FileOutputStream out = new FileOutputStream("text2.txt"));
int a=fis.read();//read()一次读取一个字节
fos.write(101);//write()一次写一个字节

写法:

1.使用整形,对文件中的字节一个一个的读取

     public static void main(String[] args) {

         try {
//字节流读取
FileInputStream in = new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test\\test.txt");
int n = -1;
StringBuffer sb = new StringBuffer();
while ((n = in.read())!=-1) {
sb.append((char)n);
}
System.out.println(sb); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }

2.使用byte数组直接声明为输入流的长度,一次性读出所有文字

        public static void main(String[] args) {

        try {
//字节流读取
FileInputStream in = new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test\\test.txt"); //使用byte数组直接声明为输入流的长度,一次性读出所有文字
byte[] bytes = new byte[1024];
in.read(bytes);
StringBuffer sb = new StringBuffer();
sb.append(new String(bytes));
System.out.println(sb); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

练习:1.读取文件中的文字然后倒序写入新文件

    public static void main(String[] args) {

        try {
//字节流读取
FileInputStream in = new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test\\test.txt");
//FileOutputStream()后面加true指文件后面可追加,而不是从文件开头写入。(可以省略不写,不写默认false)
FileOutputStream out = new FileOutputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test\\out.txt");
int n = -1;
StringBuffer sb = new StringBuffer();
while ((n = in.read())!=-1) {
sb.append((char)n);
}
sb.reverse();
out.write(sb.toString().getBytes());//将字符串转换成byte数组,并写入文件 in.close();
out.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }

2.复制一个文件夹中所有的文件(不包含文件夹)

     public class Test02_CopyFiles {

         public static void main(String[] args) {
/**
* 将一个文件夹中的所有文件,全部复制到一个新的文件夹。
*/
File oldDir = new File("F:/test");
File newDir = new File("F:/test2");
try {
copyDir(oldDir, newDir);
} catch (IOException e) {
e.printStackTrace();
}
} public static void copyDir(File oldDir,File newDir) throws IOException{
if(!oldDir.exists() || !oldDir.isDirectory()){
System.out.println("原路径不存在或不是目录!");
return;
}
if(!newDir.exists() || !newDir.isDirectory()){
System.out.println("新路径不存在或不是目录!");
return;
}
if(oldDir.equals(newDir)){
System.out.println("两个路径相同,无法复制!");
return;
}
File[] files = oldDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.isFile()){
return true;
}
return false;
}
}); FileInputStream fis = null;
FileOutputStream fos = null; for (File file : files) {
fis = new FileInputStream(file);
String newPath = newDir.getAbsolutePath()+"\\"+file.getName();
System.out.println(newPath);
fos = new FileOutputStream(newPath);
int n = -1;
while ((n = fis.read()) != -1) {
fos.write(n);
}
} fis.close();
fos.close(); System.out.println("copy成功!!!"); } }

缓存流

BufferedInputStream/BufferedOutputStream

1.基本概念:在基本流的基础上进行包装,在读取和写入时,通过缓存进行:先将内容写入到缓存区,缓存区满后再进行读取或写入操作。

2.优点:优点:可以大大减少文件的操作次数,提高写入效率。

3.使用:基本用法与基本流相同,方法也相同。

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("text.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("text2.txt"));
这种写法,我们称之为IO流,IO关闭时只需要关闭最外层流,内层流自动关闭。
bis.close();
bos.flush();//用来刷新缓冲区的,刷新后可以再次写出(字节缓冲流内置缓冲区,如果没有读取出来,可以使用flush()刷新来)
bos.close();//用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出

4.具体写法:

 public class Demo04_BufferInputStream_BufferOutputStream {

     public static void main(String[] args) {

         try {
FileInputStream fis = new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test");
FileOutputStream fos = new FileOutputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day14\\test2");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos); int i = -1;
while ((i=bis.read())!=-1) {
bos.write(i);
} bis.close();
bos.flush();
bos.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

DataInputStream/DataOutputStream

采用二进制对文件进行读写操作。
与基本流相比,可以直接抄写Java中的基本数据类型。
另外,如果操作的文件是一个二进制文件,需要使用DataInputStream/DataOutputStream替代FileInputStream/FileOutputStream
同样,Data系列的流也有read()和wirte()方法。
注意:使用DataInputStream写入的文件为二进制文件,那么读取的使用就必须要用DataOutputStrea来读。

public class Demo05_DataInputStream_DataOutputStream {

    public static void main(String[] args) {
/**
* DataInputStream/DataOutputStream
*
* 采用二进制对文件进行读写操作。
* 与基本流相比,可以直接抄写Java中的基本数据类型。
*
*/ String name = "aaa";
int age = 12;
double height =123.1; DataInputStream dis = null;
DataOutputStream dos = null; try {
dos = new DataOutputStream(new FileOutputStream("text.txt")); dos.writeUTF(name);//写入一个字符串格式
dos.writeInt(age);//写入整形
dos.writeDouble(height);//写入浮点型 dis.close();
       dos.flush();
dos.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

ObjectInputStream/ObjectOutputStrea

直接继承java.io.OutputStream/InputStream
1.与基本流相同,可以直接使用read()和write()方法进行读写。
2.与DataInputStream/DataOutputStream相同,可以对Java基本数据直接进行读写。readInt()/writeInt();
3.可以只用readObject()和writeObject(),直接对对象进行操作。

[对象的序列化和对象的反序列化]

1.对象的序列化:将程序中的对象,持久化的保存在文件中的过程。ObjectOutputStream
2.对象的反序列化:将文件中保存的对象,重新读取得到程序中的过程。ObjectInputStream
注意:如果要将对象进行序列化操作,那么实体类必须实现可序列化接口,即 implements Serializable。添加序列化版本ID(private static final long serialVersionUID = 1L;),只要版本号相同,表示序列化和反序列化时操作的对象是同一个对象,那么对实体类进行增加属性或者减少属性之后进行序列化和反序列化不会报错。
如果不添加版本号,那么系统就会认为增加后的实体类和原来的实体类不是一个实体类。

 public class Demo06_ObjectInputStream_ObjectOutputStream {

     public static void main(String[] args) {
Person zhangsan = new Person("张三", 12, 180); ObjectInputStream ois = null;
ObjectOutputStream oos = null; try {
//对象的序列化
oos = new ObjectOutputStream(new FileOutputStream("E:\\Workspaces\\test.txt"));
oos.writeObject(zhangsan);
//对象的反序列化
ois = new ObjectInputStream(new FileInputStream("E:\\Workspaces\\test.txt"));
Person p = (Person) ois.readObject(); System.out.println(p.getName()); ois.close();
oos.flush();
oos.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }
//实体类,实现序列化接口
class Person implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private double height;
public Person(String name, int age, double height) {
super();
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", height=" + height + "]";
} }

字符流

1.概念:在处理数据单元时,以一个字符作为单位,而字节流,是以一个字节流作为单位。父类是Reader和Writer,这两个类也是一个抽象类。

Reader 是所有的输入字符流的父类,它是一个抽象类。
Writer 是所有的输出字符流的父类,它也是一个抽象类。

基类FileReader/FileWriter:

在使用读写操作的时候,只能使用系统的默认的编码格式,无法指定编码,如果文件格式与系统默认格式不一致,那使用这两个方法读写的时候会导致中文乱码。

public class Demo01_FileReader_FileWriter {

    /**
* 在处理数据单元时,以一个字符作为单位,而字节流,是以一个字节流作为单位
*
* 字符流的基类是:Reader和Writer
*
*/
public static void main(String[] args) {
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\io.txt");
fr = new FileReader("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\test.txt");
fw.write("dddd");
//写入过程中必须刷新后才能读出(或者关闭)
fw.flush(); int num = 0 ;
StringBuffer sb = new StringBuffer();
while ((num = fr.read())!=-1) {
sb.append((char)num);
}
System.out.println(sb); } catch (Exception e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
}

InputStreamReader/OutputStreamWriter

将字节输出流转为字符输入/输出流,是字符流通向字节流的桥梁,可使用指定的 charset 将要写入流中的字符编码成字节。

编码:

ASCII码:美国标准信息码。
ISO8859-1:欧洲码。
Unicode编码,万国码,可以分为:UTF-6,UTF-8,UTF-16
ANSI编码,可以分为:GB2312/GBK:简体中文,big-5:繁体中文

 public class Demo02_InputStreamReader_OutputStreamWriter {

     public static void main(String[] args) {
InputStreamReader isr = null;
OutputStreamWriter osw = null; try {
isr = new InputStreamReader(new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\io.txt"),"GBK");
osw = new OutputStreamWriter(new FileOutputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\test.txt"),"utf-8"); osw.write("啊大撒旦撒大帝发");
//必须要刷新
osw.flush(); int n = 0;
StringBuilder sb = new StringBuilder();
while ((n=isr.read())!=-1) {
sb.append((char)n);
}
System.out.println(sb); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
isr.close();osw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

BufferedReader/BufferedWriter:缓存流存储。

 public class Demo03_BufferedReader_BufferedWriter {

     public static void main(String[] args) {
// TODO Auto-generated method stub
//与字节流的缓存流使用相同
BufferedReader br = null;
BufferedWriter bw = null; try {
br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\io.txt"),"utf-8"));
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\Workspaces\\javaSE\\src\\com\\jianglai\\day15\\test.txt"),"utf-8")); bw.write("dasdd哈哈哈");
bw.flush(); int n = 0;
StringBuilder sb = new StringBuilder();
while ((n=br.read())!=-1) {
sb.append((char)n);
}
System.out.println(sb); /**
* 原来读取到的字符串是UTF-8格式
* 使用s.getBytes("utf-8"):表示用utf-8对字符串进行解码为字节数组。
*
* s = new String(s.getBytes("utf-8"),"GBK");
* 表示将解码后的字节数组,重新使用GBK的解码,组合成字符串。
*
* 最终,一个UTF-8的字符串,经过解码编码转换成GBK格式的字符串。
*/
String s = sb.toString()+"dasdada发发散发啊";
s = new String(s.getBytes("utf-8"),"GBK");
bw.write(s); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
br.close();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

Java基础学习(六)-- 递归以及文件I/O流基础详解的更多相关文章

  1. [原创]java WEB学习笔记43:jstl 介绍,core库详解:表达式操作,流程控制,迭代操作,url操作

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  2. “全栈2019”Java第六十七章:内部类、嵌套类详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. “全栈2019”Java第六十四章:接口与静态方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. “全栈2019”Java第六十二章:接口与常量详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 《手把手教你》系列基础篇(九十一)-java+ selenium自动化测试-框架设计基础-Logback实现日志输出-下篇(详解教程)

    1.简介 为了方便查看和归档:(1)不同包的日志可能要放到不同的文件中,如service层和dao层的日志:(2)不同日志级别:调试.信息.警告和错误等也要分文件输出.所以宏哥今天主要介绍和分享的是: ...

  6. 转:关于将Java编译过的.class文件打成jar可执行文件/JAR详解

    原文链接:关于将Java编译过的.class文件打成jar可执行文件/JAR详解 如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是制作一个可执行的 JAR 文件包,然后就可以像. ...

  7. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  8. “全栈2019”Java第一百零五章:匿名内部类覆盖作用域成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. “全栈2019”Java多线程第三十章:尝试获取锁tryLock()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

随机推荐

  1. Android This Activity already has an action bar supplied by the window decor

    This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ ...

  2. android 极细线

    最后找到一个还算好用的方法:伪类 + transform 原理是把原先元素的 border 去掉,然后利用:before或者:after重做 border ,并 transform 的 scale 缩 ...

  3. apiCloud中实现头部与内容分离与操作规范,App头部header固定,头部与内容分离

    官方案例 1.头部拆分成一个页面比如news-text <!doctype html> <html> <head> <meta charset="u ...

  4. apiCloud中api.ajax方法跨域传参获取数据

    apiCloud中的ajax方法,可以自动处理跨域访问数据,不必使用jsonp来处理了. 使用ajax方法,必须要在apiready = function() {}方法中 获取参数 var pageP ...

  5. Oracle 数据泵使用详解--精华版

    数据泵使用EXPDP和IMPDP时应该注意的事项: EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端 ...

  6. Kettle的设计

    不多说,直接上干货! 大家都知道,这2001年以来,一直在同各种ETL工具做斗争,所以Matt 确定了Kettle的一个主要设计目标是尽可能开放.主要就是指: 开发,可读的元数据格式(XML). 开放 ...

  7. WPF学习(二) - 绑定

    绑定,这个看起来很神奇的东西,于我这种喜欢刨根儿的人而言,理解起来非常困难.    WPF绑定的核心思想是:数据层属性值的改变,能反应给展示层,反之亦然,并且这个响应的过程能被分离出来. 传统Winf ...

  8. 【原创】关于JMS[1]

    面向消息中间件(MOM)为分布式系统提供异步,解耦,稳定,可扩展和安全的行为.MOM在分布式计算领域是一个重要的概念.它允许应用使用代理器API在分布式环境实现各种功能.Java消息服务(Java M ...

  9. virtualbox挂载目录失败mount: unknown filesystem type ‘vboxsf’

    转自[https://blog.csdn.net/u011486871/article/details/79443375] [有小修改] 错误提示:Vagrant was unable to moun ...

  10. mycat读写分离+垂直切分+水平切分+er分片+全局表 测试

    原文http://blog.163.com/bigoceanwu@126/blog/static/172718064201683031639683/ 读写分离:利用最基础的mysql主从复制,事务性的 ...