1.Stream流 1.1体验Stream流 案例需求:按照下面的要求完成集合的创建和遍历
创建一个集合,存储多个字符串元素
把集合中所有以”张”开头的元素存储到一个新的集合
把”张”开头的集合中的长度为3的元素存储到一个新的集合
遍历上一步得到的集合
原始方式示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class StreamDemo { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); ArrayList<String> zhangList = new ArrayList <String>(); for (String s : list) { if (s.startsWith("张" )) { zhangList.add(s); } } ArrayList<String> threeList = new ArrayList <String>(); for (String s : zhangList) { if (s.length() == 3 ) { threeList.add(s); } } for (String s : threeList) { System.out.println(s); } System.out.println("--------" ); } }
使用Stream流示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class StreamDemo { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); list.stream().filter(s -> s.startsWith("张" )).filter(s -> s.length() == 3 ).forEach(System.out::println); } }
Stream流的好处:
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
Stream流把真正的函数式编程风格引入到Java中
代码简洁
1.2 Stream流的常见生成方式 Stream流的思想
Stream流的三类方法
1、获取Stream流
2、中间方法
流水线上的操作
一次操作完毕之后,还可以继续进行其他操作
3、终结方法
一个Stream流只能有一个终结方法
是流水线上的最后一个操作
4、生成Stream流的方式
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class StreamDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); Stream<String> listStream = list.stream(); Set<String> set = new HashSet <String>(); Stream<String> setStream = set.stream(); Map<String,Integer> map = new HashMap <String, Integer>(); Stream<String> keyStream = map.keySet().stream(); Stream<Integer> valueStream = map.values().stream(); Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream(); String[] strArray = {"hello" ,"world" ,"java" }; Stream<String> strArrayStream = Arrays.stream(strArray); Stream<String> strArrayStream2 = Stream.of("hello" , "world" , "java" ); Stream<Integer> intStream = Stream.of(10 , 20 , 30 ); } }
1.3 Stream流中间操作方法 概念:中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作
常见方法:
1 2 3 4 5 6 7 8 9 cStream<T> filter (Predicate predicate) Stream<T> limit (long maxSize) Stream<T> skip (long n) static <T> Stream<T> concat (Stream a, Stream b) Stream<T> distinct ()
filter代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class StreamDemo01 { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); list.stream().filter(s -> s.startsWith("张" )).forEach(System.out::println); System.out.println("--------" ); list.stream().filter(s -> s.length() == 3 ).forEach(System.out::println); System.out.println("--------" ); list.stream().filter(s -> s.startsWith("张" )).filter(s -> s.length() == 3 ).forEach(System.out::println); } }
limit&skip代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class StreamDemo02 { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); list.stream().limit(3 ).forEach(System.out::println); System.out.println("--------" ); list.stream().skip(3 ).forEach(System.out::println); System.out.println("--------" ); list.stream().skip(2 ).limit(2 ).forEach(System.out::println); } }
concat&distinct代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class StreamDemo03 { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); Stream<String> s1 = list.stream().limit(4 ); Stream<String> s2 = list.stream().skip(2 ); Stream.concat(s1,s2).distinct().forEach(System.out::println); } }
1.4 Stream流终结操作方法 概念:终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作
常见方法:
1 2 3 void forEach (Consumer action) long count ()
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class StreamDemo { public static void main (String[] args) { ArrayList<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); list.add("张敏" ); list.add("张无忌" ); long count = list.stream().filter(s -> s.startsWith("张" )).count(); System.out.println(count); } }
1.5 Stream流的收集操作 概念:对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中
常用方法:
1 R collect (Collector collector)
工具类Collectors提供了具体的收集方式:
1 2 3 4 5 public static <T> Collector toList () public static <T> Collector toSet () public static Collector toMap (Function keyMapper,Function valueMapper)
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 public class CollectDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("林青霞" ); list.add("张曼玉" ); list.add("王祖贤" ); list.add("柳岩" ); Set<Integer> set = new HashSet <Integer>(); set.add(10 ); set.add(20 ); set.add(30 ); set.add(33 ); set.add(35 ); String[] strArray = {"林青霞,30" , "张曼玉,35" , "王祖贤,33" , "柳岩,25" }; Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split("," )[1 ]) > 28 ); Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split("," )[0 ], s -> Integer.parseInt(s.split("," )[1 ]))); Set<String> keySet = map.keySet(); for (String key : keySet) { Integer value = map.get(key); System.out.println(key + "," + value); } } }
1.6 Stream流综合练习 案例需求:现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
男演员只要名字为3个字的前三人
女演员只要姓林的,并且不要第一个
把过滤后的男演员姓名和女演员姓名合并到一起
把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
代码实现:
演员类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Actor { private String name; public Actor (String name) { this .name = name; } public String getName () { return name; } public void setName (String name) { this .name = name; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class StreamTest { public static void main (String[] args) { ArrayList<String> manList = new ArrayList <String>(); manList.add("周润发" ); manList.add("成龙" ); manList.add("刘德华" ); manList.add("吴京" ); manList.add("周星驰" ); manList.add("李连杰" ); ArrayList<String> womanList = new ArrayList <String>(); womanList.add("林心如" ); womanList.add("张曼玉" ); womanList.add("林青霞" ); womanList.add("柳岩" ); womanList.add("林志玲" ); womanList.add("王祖贤" ); Stream.concat(manList.stream().filter(s -> s.length() == 3 ).limit(3 ), womanList.stream().filter(s -> s.startsWith("林" )).skip(1 )).map(Actor::new ). forEach(p -> System.out.println(p.getName())); } }
2.File类 2.1 File类概述和构造方法 File类介绍:
它是文件和目录路径名的抽象表示
文件和目录是可以通过File封装成对象的
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的
File类的构造方法:
1 2 3 4 5 File(String pathname) File(String parent, String child) File(File parent, String child)
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class FileDemo01 { public static void main (String[] args) { File f1 = new File ("E:\\itcast\\java.txt" ); System.out.println(f1); File f2 = new File ("E:\\itcast" ,"java.txt" ); System.out.println(f2); File f3 = new File ("E:\\itcast" ); File f4 = new File (f3,"java.txt" ); System.out.println(f4); } }
2.2 绝对路径和相对路径 绝对路径:是一个完整的路径,从盘符开始
相对路径:是一个简化的路径,相对当前项目下的路径
示例代码:
1 2 3 4 5 6 7 8 9 10 public class FileDemo02 { public static void main (String[] args) { File file1 = new File ("D:\\itheima\\a.txt" ); File file2 = new File ("a.txt" ); File file3 = new File ("模块名\\a.txt" ); } }
2.3 File类创建功能 方法分类:
1 2 3 4 5 public boolean createNewFile () public boolean mkdir () public boolean mkdirs ()
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class FileDemo02 { public static void main (String[] args) throws IOException { File f1 = new File ("E:\\itcast\\java.txt" ); System.out.println(f1.createNewFile()); System.out.println("--------" ); File f2 = new File ("E:\\itcast\\JavaSE" ); System.out.println(f2.mkdir()); System.out.println("--------" ); File f3 = new File ("E:\\itcast\\JavaWEB\\HTML" ); System.out.println(f3.mkdirs()); System.out.println("--------" ); File f4 = new File ("E:\\itcast\\javase.txt" ); System.out.println(f4.createNewFile()); } }
2.4 File类删除功能 方法分类:
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class FileDemo03 { public static void main (String[] args) throws IOException { File f1 = new File ("myFile\\java.txt" ); System.out.println(f1.delete()); System.out.println("--------" ); File f2 = new File ("myFile\\itcast" ); System.out.println(f2.delete()); System.out.println("--------" ); File f3 = new File ("myFile\\itcast" ); File f4 = new File ("myFile\\itcast\\java.txt" ); System.out.println(f4.delete()); System.out.println(f3.delete()); } }
2.5 File类判断和获取功能 判断功能:
1 2 3 4 5 public boolean isDirectory () public boolean isFile () public boolean exists ()
获取功能:
1 2 3 4 5 6 7 public String getAbsolutePath () public String getPath () public String getName () public File[] listFiles()
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class FileDemo04 { public static void main (String[] args) { File f = new File ("myFile\\java.txt" ); System.out.println(f.isDirectory()); System.out.println(f.isFile()); System.out.println(f.exists()); System.out.println(f.getAbsolutePath()); System.out.println(f.getPath()); System.out.println(f.getName()); System.out.println("--------" ); File f2 = new File ("E:\\itcast" ); File[] fileArray = f2.listFiles(); for (File file : fileArray) { if (file.isFile()) { System.out.println(file.getName()); } } } }
3.字节流 3.1 IO流概述和分类 IO流介绍:
IO:输入/输出(Input/Output)
流:是一种抽象概念,是对数据传输的总称.也就是说数据在设备间的传输称为流,流的本质是数据传输
IO流就是用来处理设备间数据传输问题的.常见的应用: 文件复制; 文件上传; 文件下载
IO流的分类:
IO流的使用场景:
如果操作的是纯文本文件,优先使用字符流
如果操作的是图片、视频、音频等二进制文件,优先使用字节流
如果不确定文件类型,优先使用字节流.字节流是万能的流
3.2 字节流写数据 字节流抽象基类:
InputStream
:这个抽象类是表示字节输入流的所有类的超类
OutputStream
:这个抽象类是表示字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类名的后缀
字节输出流:
FileOutputStream(String name)
:创建文件输出流以指定的名称写入文件
使用字节输出流写数据的步骤
创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
调用字节输出流对象的写数据方法
释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class FileOutputStreamDemo01 { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("myByteStream\\fos.txt" ); fos.write(97 ); fos.close(); } }
3.3 字节流写数据的三种方式 写数据的方法分类:
1 2 3 4 5 void write (int b) void write (byte [] b) void write (byte [] b, int off, int len)
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class FileOutputStreamDemo02 { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("myByteStream\\fos.txt" ); byte [] bys = "abcde" .getBytes(); fos.write(bys,1 ,3 ); fos.close(); } }
3.4 字节流写数据的两个小问题 字节流写数据如何实现换行:
windows:\r\n
linux:\n
mac:\r
字节流写数据如何实现追加写入:
public FileOutputStream(String name,boolean append)
创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class FileOutputStreamDemo03 { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream ("myByteStream\\fos.txt" ,true ); for (int i = 0 ; i < 10 ; i++) { fos.write("hello" .getBytes()); fos.write("\r\n" .getBytes()); } fos.close(); } }
3.5 字节流写数据加异常处理 异常处理格式:
try-catch-finally
1 2 3 4 5 6 7 try { 可能出现异常的代码; }catch (异常类名 变量名){ 异常的处理代码; }finally { 执行所有清除操作; }
finally特点
被finally控制的语句一定会执行,除非JVM退出
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class FileOutputStreamDemo04 { public static void main (String[] args) { FileOutputStream fos = null ; try { fos = new FileOutputStream ("myByteStream\\fos.txt" ); fos.write("hello" .getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null ) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.6字节流读数据(一次读一个字节数据) 字节输入流:
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
字节输入流读取数据的步骤:
创建字节输入流对象
调用字节输入流对象的读数据方法
释放资源
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class FileInputStreamDemo01 { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream ("myByteStream\\fos.txt" ); int by; while ((by=fis.read())!=-1 ) { System.out.print((char )by); } fis.close(); } }
3.7 字节流复制文件 案例需求:
把“E:\itcast\窗里窗外.txt”复制到模块目录下的“窗里窗外.txt” (文件可以是任意文件)
实现步骤:
复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
数据源:E:\itcast\窗里窗外.txt — 读数据 — InputStream — FileInputStream
目的地:myByteStream\窗里窗外.txt — 写数据 — OutputStream — FileOutputStream
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class CopyTxtDemo { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream ("E:\\itcast\\窗里窗外.txt" ); FileOutputStream fos = new FileOutputStream ("myByteStream\\窗里窗外.txt" ); int by; while ((by=fis.read())!=-1 ) { fos.write(by); } fos.close(); fis.close(); } }
3.8 字节流读数据(一次读一个字节数组数据) 一次读一个字节数组的方法:
public int read(byte[] b):从输入流读取最多b.length个字节的数据
返回的是读入缓冲区的总字节数,也就是实际的读取字节个数
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class FileInputStreamDemo02 { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream ("myByteStream\\fos.txt" ); byte [] bys = new byte [1024 ]; int len; while ((len=fis.read(bys))!=-1 ) { System.out.print(new String (bys,0 ,len)); } fis.close(); } }
3.9 字节流复制文件 案例需求:
把“E:\itcast\mn.jpg”复制到模块目录下的“mn.jpg” (文件可以是任意文件去)
实现步骤:
根据数据源创建字节输入流对象
根据目的地创建字节输出流对象
读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
释放资源
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class CopyJpgDemo { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream ("E:\\itcast\\mn.jpg" ); FileOutputStream fos = new FileOutputStream ("myByteStream\\mn.jpg" ); byte [] bys = new byte [1024 ]; int len; while ((len=fis.read(bys))!=-1 ) { fos.write(bys,0 ,len); } fos.close(); fis.close(); } }
4.字节缓冲流 4.1 字节缓冲流构造方法 字节缓冲流介绍
lBufferOutputStream
:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
lBufferedInputStream
:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
构造方法:
1 2 3 BufferedOutputStream(OutputStream out) BufferedInputStream(InputStream in)
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class BufferStreamDemo { public static void main (String[] args) throws IOException { BufferedOutputStream bos = new BufferedOutputStream (new FileOutputStream ("myByteStream\\bos.txt" )); bos.write("hello\r\n" .getBytes()); bos.write("world\r\n" .getBytes()); bos.close(); BufferedInputStream bis = new BufferedInputStream (new FileInputStream ("myByteStream\\bos.txt" )); byte [] bys = new byte [1024 ]; int len; while ((len=bis.read(bys))!=-1 ) { System.out.print(new String (bys,0 ,len)); } bis.close(); } }
4.2 字节缓冲流复制视频 案例需求:把“E:\itcast\字节流复制图片.avi”复制到模块目录下的“字节流复制图片.avi”
实现步骤:
根据数据源创建字节输入流对象
根据目的地创建字节输出流对象
读写数据,复制视频
释放资源
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class CopyAviDemo { public static void main (String[] args) throws IOException { method2(); } public static void method2 () throws IOException { BufferedInputStream bis = new BufferedInputStream (new FileInputStream ("E:\\itcast\\字节流复制图片.avi" )); BufferedOutputStream bos = new BufferedOutputStream (new FileOutputStream ("myByteStream\\字节流复制图片.avi" )); byte [] bys = new byte [1024 ]; int len; while ((len=bis.read(bys))!=-1 ) { bos.write(bys,0 ,len); } bos.close(); bis.close(); } public static void method1 () throws IOException { BufferedInputStream bis = new BufferedInputStream (new FileInputStream ("E:\\itcast\\字节流复制图片.avi" )); BufferedOutputStream bos = new BufferedOutputStream (new FileOutputStream ("myByteStream\\字节流复制图片.avi" )); int by; while ((by=bis.read())!=-1 ) { bos.write(by); } bos.close(); bis.close(); } }
5.字符流 5.1 为什么会出现字符流
字符流的介绍
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
中文的字节存储方式
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
5.2 编码表
5.3 字符串中的编码解码问题 相关方法:
1 2 3 4 5 6 7 byte [] getBytes() byte [] getBytes(String charsetName) String(byte [] bytes) String(byte [] bytes, String charsetName)
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class StringDemo { public static void main (String[] args) throws UnsupportedEncodingException { String s = "中国" ; byte [] bys = s.getBytes("GBK" ); System.out.println(Arrays.toString(bys)); String ss = new String (bys,"GBK" ); System.out.println(ss); } }
5.4 字符流写数据 介绍:
Writer
: 用于写入字符流的抽象父类
FileWriter:
用于写入字符流的常用子类
构造方法:
1 2 3 4 5 6 7 FileWriter(File file) FileWriter(File file, boolean append) FileWriter(String fileName) FileWriter(String fileName, boolean append)
成员方法:
1 2 3 4 5 6 7 8 9 void write (int c) void write (char [] cbuf) void write (char [] cbuf, int off, int len) void write (String str) void write (String str, int off, int len)
刷新和关闭的方法:
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class OutputStreamWriterDemo { public static void main (String[] args) throws IOException { FileWriter fw = new FileWriter ("myCharStream\\a.txt" ); char [] chs = {'a' , 'b' , 'c' , 'd' , 'e' }; fw.write("abcde" , 1 , 3 ); fw.close(); } }
5.5 字符流读数据 介绍:
Reader
: 用于读取字符流的抽象父类
FileReader
: 用于读取字符流的常用子类
构造方法:
1 2 3 FileReader(File file) FileReader(String fileName)
成员方法:
1 2 3 int read () int read (char [] cbuf)
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class InputStreamReaderDemo { public static void main (String[] args) throws IOException { FileReader fr = new FileReader ("myCharStream\\b.txt" ); char [] chs = new char [1024 ]; int len; while ((len = fr.read(chs)) != -1 ) { System.out.print(new String (chs, 0 , len)); } fr.close(); } }
5.6 字符流用户注册案例 案例需求:将键盘录入的用户名和密码保存到本地实现永久化存储
实现步骤:
获取用户输入的用户名和密码
将用户输入的用户名和密码写入到本地文件中
关流,释放资源
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class CharStreamDemo8 { public static void main (String[] args) throws IOException { Scanner sc = new Scanner (System.in); System.out.println("请录入用户名" ); String username = sc.next(); System.out.println("请录入密码" ); String password = sc.next(); FileWriter fw = new FileWriter ("charstream\\a.txt" ); fw.write(username); fw.write("\r\n" ); fw.write(password); fw.flush(); fw.close(); } }
5.7 字符缓冲流 字符缓冲流介绍:
构造方法:
1 2 3 4 BufferedWriter(Writer out) BufferedReader(Reader in)
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class BufferedStreamDemo01 { public static void main (String[] args) throws IOException { BufferedWriter bw = new BufferedWriter (new FileWriter ("myCharStream\\bw.txt" )); bw.write("hello\r\n" ); bw.write("world\r\n" ); bw.close(); BufferedReader br = new BufferedReader (new FileReader ("myCharStream\\bw.txt" )); char [] chs = new char [1024 ]; int len; while ((len=br.read(chs))!=-1 ) { System.out.print(new String (chs,0 ,len)); } br.close(); } }
5.8 字符缓冲流特有功能 方法介绍:
1 2 3 4 5 void newLine () String readLine ()
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class BufferedStreamDemo02 { public static void main (String[] args) throws IOException { BufferedWriter bw = new BufferedWriter (new FileWriter ("myCharStream\\bw.txt" )); for (int i = 0 ; i < 10 ; i++) { bw.write("hello" + i); bw.newLine(); bw.flush(); } bw.close(); BufferedReader br = new BufferedReader (new FileReader ("myCharStream\\bw.txt" )); String line; while ((line=br.readLine())!=null ) { System.out.println(line); } br.close(); } }
5.9 字符缓冲流操作文件中数据排序案例 案例需求:使用字符缓冲流读取文件中的数据,排序后再次写到本地文件
实现步骤:
将文件中的数据读取到程序中
对读取到的数据进行处理
将处理后的数据添加到集合中
对集合中的数据进行排序
将排序后的集合中的数据写入到文件中
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class CharStreamDemo14 { public static void main (String[] args) throws IOException { BufferedReader br = new BufferedReader (new FileReader ("charstream\\sort.txt" )); String line = br.readLine(); System.out.println("读取到的数据为" + line); br.close(); String[] split = line.split(" " ); int [] arr = new int [split.length]; for (int i = 0 ; i < split.length; i++) { String smallStr = split[i]; int number = Integer.parseInt(smallStr); arr[i] = number; } Arrays.sort(arr); System.out.println(Arrays.toString(arr)); BufferedWriter bw = new BufferedWriter (new FileWriter ("charstream\\sort.txt" )); for (int i = 0 ; i < arr.length; i++) { bw.write(arr[i] + " " ); bw.flush(); } bw.close(); } }
5.10 IO流小结
6.转换流 6.1 字符流中和编码解码问题相关的两个类
InputStreamReader
:是从字节流到字符流的桥梁,父类是Reader
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamWriter
:是从字符流到字节流的桥梁,父类是Writer
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
6.2 转换流读写数据 构造方法:
1 2 3 4 5 6 7 InputStreamReader(InputStream in) InputStreamReader(InputStream in,String chatset) OutputStreamWriter(OutputStream out) OutputStreamWriter(OutputStream out,String charset)
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class ConversionStreamDemo { public static void main (String[] args) throws IOException { OutputStreamWriter osw = new OutputStreamWriter (new FileOutputStream ("myCharStream\\osw.txt" ),"GBK" ); osw.write("中国" ); osw.close(); InputStreamReader isr = new InputStreamReader (new FileInputStream ("myCharStream\\osw.txt" ),"GBK" ); int ch; while ((ch=isr.read())!=-1 ) { System.out.print((char )ch); } isr.close(); } }
7.对象操作流 7.1 对象序列化流 对象序列化介绍:
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
对象序列化流: ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream
。 可以使用ObjectInputStream
读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
构造方法:
1 ObjectOutputStream(OutputStream out)
序列化对象的方法:
1 void writeObject (Object obj)
示例代码:
学生类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class Student implements Serializable { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } 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; } @Override public String toString () { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}' ; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class ObjectOutputStreamDemo { public static void main (String[] args) throws IOException { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("myOtherStream\\oos.txt" )); Student s = new Student ("佟丽娅" ,30 ); oos.writeObject(s); oos.close(); } }
注意事项:
一个对象要想被序列化,该对象所属的类必须必须实现Serializable
接口
Serializable
是一个标记接口,实现该接口,不需要重写任何方法
7.2 对象反序列化流 对象反序列化流: ObjectInputStream
ObjectInputStream
反序列化先前使用ObjectOutputStream
编写的原始数据和对象
构造方法:
1 ObjectInputStream(InputStream in)
反序列化对象的方法:
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class ObjectInputStreamDemo { public static void main (String[] args) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("myOtherStream\\oos.txt" )); Object obj = ois.readObject(); Student s = (Student) obj; System.out.println(s.getName() + "," + s.getAge()); ois.close(); } }
7.3 serialVersionUID&transient serialVersionUID:
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
transient:
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
示例代码:
学生类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Student implements Serializable { private static final long serialVersionUID = 42L ; private String name; private transient int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } 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; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ObjectStreamDemo { public static void main (String[] args) throws IOException, ClassNotFoundException { read(); } private static void read () throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("myOtherStream\\oos.txt" )); Object obj = ois.readObject(); Student s = (Student) obj; System.out.println(s.getName() + "," + s.getAge()); ois.close(); } private static void write () throws IOException { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("myOtherStream\\oos.txt" )); Student s = new Student ("佟丽娅" , 30 ); oos.writeObject(s); oos.close(); } }
7.4 对象操作流练习 案例需求:创建多个学生类对象写到文件中,再次读取到内存中
实现步骤:
创建序列化流对象
创建多个学生对象
将学生对象添加到集合中
将集合对象序列化到文件中
创建反序列化流对象
将文件中的对象数据,读取到内存中
代码实现:
学生类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Student implements Serializable { private static final long serialVersionUID = 2L ; private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } 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; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Demo03 { public static void main (String[] args) throws Exception { ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("myCode\\oos.txt" )); Object obj = ois.readObject(); ArrayList<Student> arrayList = (ArrayList<Student>)obj; ois.close(); for (Student s : arrayList) { System.out.println(s.getName() + "," + s.getAge()); } } }
8.Properties集合 8.1 Properties作为Map集合的使用 Properties介绍:
是一个Map体系的集合类
Properties可以保存到流中或从流中加载
属性列表中的每个键及其对应的值都是一个字符串
Properties基本使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class PropertiesDemo01 { public static void main (String[] args) { Properties prop = new Properties (); prop.put("itheima001" , "佟丽娅" ); prop.put("itheima002" , "赵丽颖" ); prop.put("itheima003" , "刘诗诗" ); Set<Object> keySet = prop.keySet(); for (Object key : keySet) { Object value = prop.get(key); System.out.println(key + "," + value); } } }
8.2 Properties作为Map集合的特有方法 特有方法:
1 2 3 4 5 6 7 8 Object setProperty (String key, String value) String getProperty (String key) Set<String> stringPropertyNames ()
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class PropertiesDemo02 { public static void main (String[] args) { Properties prop = new Properties (); prop.setProperty("itheima001" , "佟丽娅" ); prop.setProperty("itheima002" , "赵丽颖" ); prop.setProperty("itheima003" , "刘诗诗" ); Set<String> names = prop.stringPropertyNames(); for (String key : names) { String value = prop.getProperty(key); System.out.println(key + "," + value); } } }
8.3 Properties和IO流相结合的方法 和IO流结合的方法:
1 2 3 4 void load (Reader reader) void store (Writer writer, String comments)
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class PropertiesDemo03 { public static void main (String[] args) throws IOException { myLoad(); } private static void myLoad () throws IOException { Properties prop = new Properties (); FileReader fr = new FileReader ("myOtherStream\\fw.txt" ); prop.load(fr); fr.close(); System.out.println(prop); } private static void myStore () throws IOException { Properties prop = new Properties (); prop.setProperty("itheima001" ,"佟丽娅" ); prop.setProperty("itheima002" ,"赵丽颖" ); prop.setProperty("itheima003" ,"刘诗诗" ); FileWriter fw = new FileWriter ("myOtherStream\\fw.txt" ); prop.store(fw,null ); fw.close(); } }
8.4 Properties集合练习 案例需求:在Properties文件中手动写上姓名和年龄,读取到集合中,将该数据封装成学生对象,写到本地文件
实现步骤:
创建Properties集合,将本地文件中的数据加载到集合中
获取集合中的键值对数据,封装到学生对象中
创建序列化流对象,将学生对象序列化到本地文件中
代码实现:
学生类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Student implements Serializable { private static final long serialVersionUID = 1L ; private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } 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; } @Override public String toString () { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}' ; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Test { public static void main (String[] args) throws IOException { Properties prop = new Properties (); FileReader fr = new FileReader ("prop.properties" ); prop.load(fr); fr.close(); String name = prop.getProperty("name" ); int age = Integer.parseInt(prop.getProperty("age" )); Student s = new Student (name,age); ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("a.txt" )); oos.writeObject(s); oos.close(); } }
Author:
不久之
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY ?