1.泛型
1.1.什么是泛型?
泛型就是限制我们的数据类型。
为什么使用泛型?
我们原来在定义集合时,是如下的定义方式:
List list = new ArrayList();//该集合没有使用泛型
list.add("java01");
list.add("java02");
String str = (String)list.get(0); //获取元素 需要进行强制类型转换
System.out.println(str);
获取元素,不方便对元素进行相应的其他操作.
1.2.如何使用泛型
List<类型> list = new ArrayList<类型>();只能在该集合中存储指定的类型.
public static void main(String[] args) {
List<String> list=new ArrayList<>();//这里就限制了集合中每个元素得类型。 后边的类型可以省略
list.add("java01");
list.add("hello"); //因为集合中只能添加String类型
list.add("world"); //因为集合中只能添加String类型String s = list.get(0); //在获取元素时 默认就是相应的数据类型 而无需在进行转换
//<K,V>:K:表示键的泛型 V:表示值的泛型
HashMap<String,Integer> map=new HashMap<>();
map.put("name",15);
map.put("age",25);Set<String> keys = map.keySet();
}
1.3.如何定义泛型类
public class 类名<标识,标识,....> {
标识 变量名;
public 标识 方法名(){
}
.......
}
定义坐标类:
public class Test03 {
public static void main(String[] args) {
//在创建泛型类对象时没有指定相应的泛型类型。则默认为Object类型
Point p1=new Point();
p1.setX(15);
p1.setX("北纬50度");//这里的泛型必须都是对象类型
Point<Integer> p2=new Point<Integer>() ;
p2.setX(25);
p2.setY(65);
Integer x = p2.getX();
Integer y = p2.getY();
p2.show();Point<String> p3=new Point<>();
}
}
class Point<T>{
private T x;
private T y;public void show(){
System.out.println("x坐标为:"+x+";y坐标为:"+y);
}public T getX() {
return x;
}public void setX(T x) {
this.x = x;
}public T getY() {
return y;
}public void setY(T y) {
this.y = y;
}
}
2. File对象
2.1.File类简介
File 类 就是当前系统中 文件或者文件夹的抽象表示
通俗的讲 就是 使用File对象 来操作我们电脑系统中的文件或者文件夹学习File类 其实就是学习 如何通过file对象 对系统中的文件/文件夹进行增删改查
2.2.创建File对象(指定文件路径)
磁盘准备一个目录AAA。以后对文件得操作都放在该目录下
public static void main(String[] args) {
/* path 路径
Creates a new <code>File</code> instance by converting the given
pathname string into an abstract pathname. If the given string is
the empty string, then the result is the empty abstract pathname
File(String) 参数为String类型的目标文件路径名
*/
//创建一个File对象 并指定文件得路径 \转移字符串
File file01 = new File("D:\\AAA\\aaa.txt");
/*
\\目录层级 在window系统下层级分割符为\ 但是在linux和mac系统上分割符为 /
我们得java代码是一种跨平台得语言。 我们得开发在window 但是我们项目得部署在linux.
我们使我们得代码能在任意系统下来用。 我们有两种解决办法
(1)第一种 因为window 兼容 / 和 \
*/
File file02 = new File("D:/AAA/bbb.txt");
// 第二种 File.separator根据当前代码所在得系统自动获取相应得分割符
System.out.println(File.separator); // \因为我们当前在window下
File file03 = new File("D:"+File.separator+"AAA"+File.separator+"ccc.txt");
}
2.2.增
package com.qy151.test5;
import java.io.File;
import java.io.IOException;
/**
* @author : wzh
* @date 2022/4/19 20:15:07
*/
public class Test2 {
public static void main(String[] args) throws IOException {
//创建File对象
File file1 = new File("D:/BBB/aaa.txt");
file1.createNewFile(); //创建相应的文件 抛出异常
File file2 = new File("D:/BBB/AAA");
file2.mkdir(); //创建目录 make directory 单层目录
File file3 = new File("D:/BBB/CCC/ddd");
file3.mkdirs(); //创建多层目录
File file4 = new File("D:/BBB/eee");
file4.createNewFile();
File file5 = new File("D:/BBB/CCC/ddd/eee.mp4");
file5.createNewFile();
//根据调用的方法不同,创建不同的类型
}
}
2.3.删
package com.qy151.test5;
import java.io.File;
/**
* @author : wzh
* @date 2022/4/19 20:24:26
*/
public class Test3 {
public static void main(String[] args) throws InterruptedException {
File file1 = new File("D:/BBB/eee");
file1.delete(); //删除文件
File file2 = new File("D:/BBB/bbbb.txt");
file2.deleteOnExit(); //当程序退出后 删除
Thread.sleep(5000); //休眠5秒
File file3 = new File("D:/BBB/AAA");
file3.delete(); //删除空目录 有文件不能删除
}
}
2.4.改
package com.qy151.test5;
import java.io.File;
import java.io.IOException;
/**
* @author : wzh
* @date 2022/4/19 20:32:14
*/
public class Test4 {
public static void main(String[] args) throws IOException {
//改
File file = new File("D:/BBB/ccc.txt");
file.createNewFile(); //创建ccc.txt文件
file.setReadable(false); //设置该文件的权限为不能读
file.setWritable(false); //设置该文件的权限为不能写
file.setReadOnly(); //设置只读的权限
file.renameTo(new File("D:/BBB/dddd.txt")); //重命名
file.renameTo(new File("D:/AAA/dddd.txt")); //写别的路径 是粘贴
}
}
2.5.查
package com.qy151.test5;
import java.io.File;
import java.util.Arrays;
/**
* @author : wzh
* @date 2022/4/19 20:41:29
*/
public class Test5 {
public static void main(String[] args) {
File file1 = new File("D:/BBB/CCC/ddd/eee.mp4");
String name = file1.getName();//得到文件的名称
System.out.println("name===========>"+name);
// File parentFile = file1.getParentFile();
// System.out.println(parentFile);
String parent = file1.getParent(); //得到父级路径的名称
System.out.println("paarnt============>"+parent);
String path = file1.getPath(); //得到文件的路径
System.out.println("path==============>"+path);
// linux中文件都有三权限 读写可执行
boolean b = file.canExecute();
boolean b1 = file.canRead();
boolean b2 = file.canWrite();
boolean f1 = file1.isFile(); //判断该文件对象是否为文件类型
System.out.println("f1=============>"+f1);
boolean f2 = file1.isDirectory(); //判断该文件对象是否为目录类型
System.out.println("f2=============>"+f2);
File file2 = new File("D:/BBB");
String[] list = file2.list(); //列出BBB目录下所有子文件的名称
System.out.println(Arrays.toString(list));
File[] files = file2.listFiles(); //列出BBB目录下所有文件对象
for(File f : files){
System.out.println(f.toString());
}
}
}
经典题目: 用的方法的递归调用。
package com.qy151.test5;
import java.io.File;
/**
* @author : wzh
* @date 2022/4/19 20:59:13
*/
public class Test6 {
public static void main(String[] args) {
//经典题目: 用的方法的递归调用
//显示指定目录下的所有文件。D:/BBB下所有的文件.
showAlLFiles("D:/BBB");
}
public static void showAlLFiles(String path){
//使用传入的路径构建文件对象
File file = new File(path);
//判断文件是否存在 或者 文件是否为目录
if(!file.exists() || !file.isDirectory()){
return ;
}
//列出该目录下所有的文件对象
File[] files = file.listFiles();
//遍历数组
for(File f : files){
if(f.isDirectory()){
System.out.println(f.getPath()+" <Dir>");
showAlLFiles(f.getPath()); //继续调用该方法
}else{
System.out.println(f.getPath()+" ");
}
}
}
}
3.IO流
3.1.IO流概述
1. IO都是全大写 说明肯定是两个单词的首字母
I : inputstream 输入流 O : outputstream 输出流2. IO的作用:就是通过java代码 对文件中的内容进行操作。
输入: 读操作(读取文件的内容) 输出: 写操作(往文件中写内容)
所以有一话: 读进来 写出去
3. IO流的分类:(1)根据流的方向:
---输入流: 程序可以从中读取数据的流。
---输出流: 程序能向其中写入数据的流。
(2)根据流的单位:
---字节流: 以字节为单位传输数据的流
---字符流: 以字符为单位传输数据的流
(3)根据功能
---节点流: 直接和文件进行交互 ---四大基流
---处理流(过滤流): 不是直接作用在文件上。是对一个已存在流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。 ---包装流
四个基本的流: 其他的流都是在这四个流的基础上进行扩展的
字节输入流
字节输出流
字符输入流
字符输出流
3.2.字符流
3.2.1.Writer字符输出流
它是所有字符输出流的跟类。---FileWriter类
package com.qy151.test5;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* @author : wzh
* @date 2022/4/19 21:25:23
*/
public class Test7 {
public static void main(String[] args) throws Exception {
//字符输出流 -----指定对那个文件(路径)进行写操作
Writer writer = new FileWriter("D:/BBB/aaa.txt");
String str = "Hello AAA 我要学java";
writer.write(str);
writer.flush(); //刷新流
writer.close(); //关闭流资源
}
}
上面每次往内容中写内容时,就会把原来的内容覆盖了。如何追加内容
package com.qy151.test5;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* @author : wzh
* @date 2022/4/19 21:33:59
*/
public class Test8 {
public static void main(String[] args) throws Exception {
//字符输出流 ----指定对那个文件(路径)进行写操作
//true:表示允许追加内容到文件中
Writer writer = new FileWriter("D:/BBB/aaa.txt",true);
String str = "你好 我是新添加的内容 Hello Java";
writer.write(str);
writer.flush(); //刷新流
writer.close(); //关闭流资源
}
}
3.2.2.Reader字符输入流
它是所有字符输入流的根类 它的实现类有很多,我们使用FileReader实现类
package com.qy151.test5;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
/**
* @author : wzh
* @date 2022/4/19 21:39:59
*/
public class Test9 {
public static void main(String[] args) throws IOException {
//创建字符输入流对象,作用:就是读取aaa.txt里的内容
Reader reader = new FileReader("D:/BBB/aaa.txt");
int count = 0; //表示读取字符的个数
char[] chars = new char[10]; //每次读取到元素存入该数组中
while((count=reader.read(chars))!=-1){
String str = new String(chars,0,count);
System.out.print(str);
}
//但是这种效率会很慢,因为每次只读取一个字符串.
//那么我们可以一次读取多个字符 并存入一个字符数组中
// char[] chars = new char[2]; //每次读取2个字符放入该数组中
// int c = reader.read(chars); //每次读取2个字符放入chars数组中,返回读取的个数
// System.out.println(c);
// System.out.println(chars);
// String s = new String(chars,0,c); //把字符数组转换为字符串
// System.out.println(s);
//
// c = reader.read(chars);
// System.out.println(c);
// System.out.println(chars); //[H,e]--->[l,l]
// String s1 = new String(chars,0,c);
// System.out.println(s1);
}
}
3.2.3.使用字符输入和输出流完成文件内容的复制
要求:D:/BBB/d.txt 复制到 C:/AAA/d.txt.
//junit 单元测试 @Test 相当于每个方法都可以独立的运行等价于main函数。
//完成文件内容的复制功能
//junit 单元测试 @Test 相当于每个方法都可以独立的运行等价于main函数。
@Test
public void test1() throws Exception{
//1.创建一个字符输入流
FileReader fr = new FileReader("D:/BBB/d.txt");
//2.创建一个字符输出流
FileWriter fw = new FileWriter("C:/AAA/e.txt");
int c = 0;//读取到字符的个数
char[] chars = new char[5]; //每次读取的内容放入到该数组中
while((c=fr.read(chars))!=-1){
fw.write(chars,0,c); //写入chars 从0的位置开始,写c个
fw.flush(); //刷新流
}
fw.close(); //关闭流资源
fr.close();
}
大家思考:
咱们能不能复制一个电影,图片,压缩文件等,上面的字符流没法对图片和电影或压缩文件等进行操作.因为它只能对文本进行操作.因为视频图片等这些都属于二进制.
字节流与字符流的区别:
* 字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元;
* 字节流默认不使用缓冲区;字符流使用缓冲区
* 字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取 Unicode码元;
* 字符流通常处理文本数据,它支持写入及读取Unicode码元。
————————————————
版权声明:本文为CSDN博主「农村小白」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44538107/article/details/89923745
3.3.字节流
3.3.1.字节输出流-----OutputStream
它可以对任意文件进行操作,对文件进行输出操作。以字节为单位。 它是所有字节输出流的父类.
FileOutputStream
//测试字节输出流
@Test
public void testOutputStream() throws Exception{
OutputStream os = new FileOutputStream("D:/BBB/d.txt");
String str = "Hello World!!!";
//把字符串转换为字节数组
byte[] bytes = str.getBytes();
os.write(bytes);
os.flush(); //刷新流
os.close(); //关闭流资源
}
3.3.2.字节输入流-----InputStream
它可以对任意文件进行读操作,以字节为单位,它是所有字节输入流的父类,子类有FileInputStream.
//一次一次的读取
@Test
public void testInputStream() throws Exception{
InputStream is = new FileInputStream("D:/BBB/d.txt");
byte[] bytes = new byte[5];
int c = is.read(bytes); //一次读取五个字节 并把读取的内容放入字节数组bytes中 返回读取到的字节的个数
System.out.println(bytes+"-------------->个数:"+c);
c = is.read(bytes);
System.out.println(bytes+"-------------->个数:"+c);
c = is.read(bytes);
System.out.println(bytes+"-------------->个数:"+c);
}
//如果文件中内容非常大 使用循环来读取
@Test
public void testInputStream1() throws Exception{
InputStream is = new FileInputStream("D:/BBB/d.txt");
byte[] bytes = new byte[5];
int c = 0; //读取到的个数
while((c=is.read(bytes))!=-1){
String str = new String(bytes,0,c);
System.out.print(str);
}
is.close();
}
3.3.3.使用字节输入和输出完成文件的复制功能
@Test
public void testCopy() throws Exception{
//1.创建字节输入流 图片
InputStream is = new FileInputStream("D:/BBB/1.jpg");
//2.创建字节输出流
OutputStream os = new FileOutputStream("C:/AAA/1.jpg");
byte[] bytes = new byte[10];
int c = 0;
while((c=is.read(bytes))!=-1){
os.write(bytes,0,c);
}
is.close();
os.close();
}
3.4.缓存流
缓存流是在四大基础流[ InputStream OutputStream Writer Reader]之上 添加了一个缓存池功能.
BufferedInputStream BufferedOutputStream BufferedWriter BufferedReader 提高IO的效率,降低IO的次数.
3.4.1.字节缓存输出流 ---BufferedOutputStream
@Test
public void TestBuffer() throws Exception{
OutputStream os = new FileOutputStream("D:/BBB/d.txt");
BufferedOutputStream bos = new BufferedOutputStream(os); //缓存流要作用在基础流上
String str = "Hello World!!! 我要睡觉啊";
byte[] bytes = str.getBytes(); //把字符串转为字节
bos.write(bytes); //因为写的内容暂时放入缓存池中 并没有直接放入文件中,所有文件中没有内容
//bos.flush(); //刷新缓存池 ---- 把缓存池的内容输入到文件上
bos.close(); //关闭流 -----先刷新缓冲池 再关闭流资源
}
3.4.2. 字节缓存输入流 ----BufferedInputStream
public void testBufferedInputStream() throws IOException {
InputStream is = new FileInputStream("D:/BBB/a.txt");
BufferedInputStream bis = new BufferedInputStream(is);//缓存流要作用在基流上
int c = 0;
byte[] bytes = new byte[5];
while((c=bis.read(bytes))!=-1){
String str = new String(bytes,0,c);
System.out.print(str+" ");
}
}
3.4.3.使用字节缓存输出流和字节缓存输入流完成复制功能
//字节缓存输入流和字节缓存输出流完成复制
//Junit @Test单元测试 每个方法都可以独立运行 相当于main函数
@Test
public void testCopy2() throws IOException {
//创建字节缓存输入流
InputStream is = new FileInputStream("D:/BBB/a.txt");
BufferedInputStream bis = new BufferedInputStream(is);
//创建字节缓存输出流
OutputStream os = new FileOutputStream("D:/BBB/d.txt");
BufferedOutputStream bos = new BufferedOutputStream(os);
int c = 0;
byte[] bytes = new byte[10];
while((c=bis.read(bytes))!=-1){
bos.write(bytes,0,c);
bos.flush();
}
bos.close();
bis.close();
}
3.5.对象流 ----对Java对象进行IO操作
为什么需要对象流?
我们现在操作IO流的时候 都是将字符串读写操作 可不可以将Java对象在文件中进行读写呢?
可以的 Student student = new Student();对象
//因为运行的时候,所有的数据都是在运行内存中的 持久化 将运行内存的数据 保存到硬盘上 存档(写) 读档(读)
3.5.1.对象输出流 ------ObjectOutputStream
//public ObjectOutputStream(OutputStream out)throws IOException
@Test //存档 -----序列化:
public void testObjectStream() throws Exception{
OutputStream os = new FileOutputStream("D:/BBB/a.txt");
//对象输出流 ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(oos); //对象流在基流上使用
//使用对象输出流调用输出方法 输出的类的对象 该类必须实现Serializable 序列化接口
Role r = new Role("吕布","10级",1,"战四娘");
oos.writeObject(r);
oos.close();
}
3.5.2.对象输入流 ------ObjectInputSteam
@Test //读档: -----反序列化
public void testObjectStream() throws Exception{
InputStream is = new FileInputStream("D:/BBB/a.txt");
//对象输入流 -----ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(is);
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
//读取多个对象
@Test
public void testObjectInputStream() throws IOException, ClassNotFoundException {
InputStream is = new FileInputStream("D:/BBB/a.txt");
ObjectInputStream ois = new ObjectInputStream(is);
//readObject()读取到文件最后会有java.io.EOFException异常(读取不到对象),
// 进行try{}catch(){}捕捉即可
while(true) {
try {
Teacher o = (Teacher) ois.readObject();
System.out.println(o);
}catch(EOFException e){
System.out.println("读取完毕");
break;
}
}
ois.close();
}
1.序列化:把内存中的java对象存储到磁盘(网盘)的过程
-------java对象所属的类必须实现序列化接口:implements Serializable
2.反序列化:把磁盘中的内容读取到java对象内存中的过程
序列化:是对象转换成一个字节序列的过程,是一个写操作。
反序列化:一个字节序列转换成对象的过程,是一个读操作。
Serializable:序列化接口
如果想将对象序列化,那么对象的类型必须实现此接口。此接口内什么都没有,只是一个序列化标识。
3.5.3.总结
1. 通过字符流完成文件的复制---->它只能复制文本文件
2. 字节流:---字节输入流和字节输出流。
3. 字节流 我们也可以完成文件的复制功能---它可以复制任意类型的文件.
4. 缓存流--->它基本流的基础上 添加了一个缓存池
5. 对象流: ObjectInputStream ObjectOutputStream
序列化:把内存中的java对象存储到磁盘(网盘)的过程-------java对象所属的类必须实现序列化接口:implements Serializable
反序列化:把磁盘中的内容读取到java对象内存中的过程
因为文件里的文本内容无法确定,所以如果是文本内容,建议还是用字符流
完结!!!!!
感谢观看