JAVASE基础模块三十三(Scanner 扫描流 RandomAccessFile随机访问流 ObjectInputStream序列流 Properties集合流 SequenceInputStream顺序流)
Scanner 扫描流
-
概念
- 扫描器可以从实现readable接口的任何对象读取文本 如果对底层 readable 的 Readable.read方法的调用抛出 则扫描器认为已经到达了输入的结尾 底层 readable 最新抛出的
IOException
可以通过 方法获取
- 扫描器可以从实现readable接口的任何对象读取文本 如果对底层 readable 的 Readable.read方法的调用抛出 则扫描器认为已经到达了输入的结尾 底层 readable 最新抛出的
-
构造方法
- Scanner(File source) 构造一个新的 Scanner 它生成的值是从指定文件扫描的
- Scanner(InputStream source) 构造一个新的 Scanner 它生成的值是从指定的输入流扫描的
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Sc { public static void main(String[] args) throws FileNotFoundException { Scanner sc = new Scanner(new File("Ret.txt")); while (sc.hasNextLine()) { String s = sc.nextLine(); System.out.println(s); } } }
txt文件读取扫描结果: #\u4E00\u6811\u68A8\u82B1\u538B\u6D77\u68E0 #Fri Aug 14 16:01:11 CST 2020 12dw3=14fd56 12df3=14df56 12de3=14fd56 12da3=14fd56 12dq3=14fd56 Process finished with exit code 0
-
键盘录入的第二种方式 不使用scanner
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class LuRu { public static void main(String[] args) throws IOException { BufferedReader bu = new BufferedReader(new InputStreamReader(System.in)); while(true){ System.out.println("input"); String s = bu.readLine(); System.out.println(s); if("886".equals(s)){ break; } } } }
运行结果: input 123f 123f input 886 886 Process finished with exit code 0
随机访问流
-
随机访问流概述
- RandomAccessFile最大特点 能读能写
- RandomAccessFile类不属于流 是Object类的子类 但他融合了inputstream与outputstream的功能 支持随机访问文件的读取与写入
- 此类的实例支持对随机访问文件的读取和写入
- 随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组
-
文件指针
- 存在指向该隐含数组的光标或索引 称为文件指针 输入操作从文件指针开始读取字节 并随着对字节的读取而前移此文件指针
- 如果随机访问文件以读取/写入模式创建 则输出操作也可用
输出操作从文件指针开始写入字节 并随着对字节的写入而前移此文件指针 - 写入隐含数组的当前末尾之后的输出操作导致该数组扩展 该文件指针可以通过 getFilePointer 方法读取 并通过 seek 方法设置
import java.io.IOException; import java.io.RandomAccessFile; public class Zz { public static void main(String[] args) throws IOException { //writeData(); RandomAccessFile in = new RandomAccessFile("e.txt", "rw"); int i = in.readInt(); long filePointer = in.getFilePointer(); System.out.println("指针位置:"+filePointer); double v = in.readDouble(); filePointer = in.getFilePointer(); System.out.println("指针位置:"+filePointer); boolean b = in.readBoolean(); filePointer = in.getFilePointer(); System.out.println("指针位置:" + filePointer); String s = in.readUTF(); filePointer = in.getFilePointer(); System.out.println("指针位置:" + filePointer); //定位文件指针的位置 in.seek(12); b = in.readBoolean(); System.out.println(i); System.out.println(v); System.out.println(b); System.out.println(s); System.out.println(b); } private static void writeData() throws IOException { RandomAccessFile out = new RandomAccessFile("e.txt", "rw"); out.writeInt(200); out.writeDouble(32.2); out.writeBoolean(false); out.writeUTF("你好"); } }
运行结果: 指针位置:4 指针位置:12 指针位置:13 指针位置:21 200 32.2 false 你好 false 进程已结束,退出代码0
-
断点下载
import java.io.*; public class MyTest2 { public static void main(String[] args) throws IOException { RandomAccessFile in=null; RandomAccessFile out=null; try { in = new RandomAccessFile("mm.mp3", "rw"); out = new RandomAccessFile("dd.mp3", "rw"); //点了继续下载:1.先 判断之前的那个文件,在不在,如果不在 File file = new File("dd.mp3"); if (!file.exists()) { in.seek(0); out.seek(0); }else{ BufferedReader reader = new BufferedReader(new FileReader("config.txt")); String s = reader.readLine(); // System.out.println(s); long l = Long.parseLong(s); in.seek(l+1); out.seek(l+1); } int len=0; byte[] bytes = new byte[2]; int i=0; while ((len=in.read(bytes))!=-1){ out.write(bytes,0,len); //异常来模拟暂停下载 /* if(i++>=6000){ System.out.println(1/0); }*/ } in.close(); out.close(); } catch (Exception e) { e.printStackTrace(); long pointer = in.getFilePointer(); //System.out.println(pointer); PrintWriter printWriter = new PrintWriter("config.txt"); printWriter.println(pointer); printWriter.flush(); printWriter.close(); } } }
序列流
-
概述及特点
- 序列化 就是把对象通过流的方式存储到文件中
- 反序列化 就是把文件中存储的对象以流的方式还原成对象
- 将 Java 对象的基本数据类型和图形写入 OutputStream 可以使用 ObjectInputStream 读取(重构)对象
- 通过在流中使用文件可以实现对象的持久存储 如果流是网络套接字流 则可以在另一台主机上或另一个进程中重构对象
-
要求
-
Serializable 序列化接口
-
如果想要一个类的对象 能被序列化 要求该类实现这个标记接口
-
transient 排除序列化属性
-
private transient int age;
-
改变类属性时需要给定ID 不然会发生异常
private static final long serialVersionUID = 789456123L;
package com.westos.X3; import java.io.*; import java.util.ArrayList; public class XuLie { public static void main(String[] args) throws IOException, ClassNotFoundException { // Xie(); readxuliehua(); } private static void readxuliehua() throws IOException, ClassNotFoundException { ObjectInputStream ii = new ObjectInputStream(new FileInputStream("lo.txt")); ArrayList o = (ArrayList) ii.readObject(); System.out.println(o); System.out.println(o.get(3)); ii.close(); } private static void Xie() throws IOException { st ss = new st("ss", 15); st s1 = new st("ss", 15); st s2 = new st("ss", 15); st s3 = new st("ss", 15); st s4= new st("ss", 15); ArrayList<st> uu = new ArrayList<>(); uu.add(s4); uu.add(s3); uu.add(s2); uu.add(s1); uu.add(ss); ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("lo.txt")); oo.writeObject(uu); oo.close(); } } class st implements Serializable { private static final long serialVersionUID = 789456123L; private String name; private int age; // private transient int age; @Override public String toString() { return "st{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } public st(String name, int age) { this.name = name; this.age = age; } }
运行结果: [st{name='ss', age=15}, st{name='ss', age=15}, st{name='ss', age=15}, st{name='ss', age=15}, st{name='ss', age=15}] st{name='ss', age=15} 进程已结束,退出代码0
-
集合流
-
概述
- Properties 类表示了一个持久的属性集
- Properties 可保存在流中或从流中加载
- 属性列表中每个键及其对应值都是一个字符串 一个属性列表可包含另一个属性列表作为它的“默认值”;
- 如果未能在原有的属性列表中搜索到属性键 则搜索第二个属性列表
-
特点
- Properties 他的键和值的数据类型,已经默认为String
- 使用 Properties 来读取配置文件,配置文件有要求
- 一般配置文件的后缀名 .properties
- 配置文件中的键值 以 = 分割
-
方法
- getProperty(String key)
用指定的键在此属性列表中搜索属性
-
getProperty(String key)
用指定的键在此属性列表中搜索属性 -
getProperty(String key)
用指定的键在此属性列表中搜索属性 -
store(OutputStream out, String comments)
以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流 -
load(InputStream inStream)
从输入流中读取属性列表(键和元素对)
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class JiHeLiu {
public static void main(String[] args) throws IOException {
Properties pp = new Properties();
//设置
pp.setProperty("123", "1456");
String dt = pp.getProperty("123", "0");
System.out.println(dt);
Properties p = new Properties();
p.setProperty("12df3", "14df56");
p.setProperty("12da3", "14fd56");
p.setProperty("12dq3", "14fd56");
p.setProperty("12dw3", "14fd56");
p.setProperty("12de3", "14fd56");
p.store(new FileOutputStream("Ret.txt"), "一树梨花压海棠");
//读取
Properties ppp = new Properties();
ppp.load(new FileInputStream("Ret.txt"));
System.out.println(ppp);
//xie();
//duqu();
}
private static void duqu() throws IOException {
BufferedReader bb = new BufferedReader(new FileReader("pp.txt"));
HashMap<String, String> s1 = new HashMap<>();
while (true) {
String s = bb.readLine();
if (s != null) {
String[] sd = s.split("=");
s1.put(sd[0], sd[1]);
} else {
break;
}
}
Set<Map.Entry<String, String>> der = s1.entrySet();
for (Map.Entry<String, String> qw : der) {
System.out.println(qw.getKey() + " " + qw.getValue());
}
}
private static void xie() throws FileNotFoundException {
HashMap<String, String> ss = new HashMap<>();
ss.put("rtyrty", "456789");
ss.put("r55ty", "4555789");
PrintWriter pep = new PrintWriter(new FileOutputStream("pp.txt"), true);
Set<Map.Entry<String, String>> ee = ss.entrySet();
for (Map.Entry<String, String> se : ee) {
pep.println(se.getKey() + "=" + se.getValue());
}
pep.close();
}
}
运行结果:
1456
{12dw3=14fd56, 12df3=14df56, 12de3=14fd56, 12da3=14fd56, 12dq3=14fd56}
进程已结束,退出代码0
SequenceInputStream顺序流
-
概述
- SequenceInputStream表示其他输入流的逻辑串联
- 它从输入流的有序集合开始 并从第一个输入流开始读取 直到到达文件末尾 接着从第二个输入流读取 依次类推 直到到达包含的最后一个输入流的文件末尾为止
-
构造方法
- SequenceInputStream(Enumeration<? extends InputStream> e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数 - SequenceInputStream(InputStream s1, InputStream s2)
将按顺序读取这两个参数,先读取 s1,然后读取 s2,以提供从此 SequenceInputStream 读取的字节
import java.io.*; public class ShunXuLiu { public static void main(String[] args) throws IOException { FileInputStream f1 = new FileInputStream("Ret.txt"); FileInputStream f2 = new FileInputStream("pp.txt"); SequenceInputStream s = new SequenceInputStream(f1, f2); FileOutputStream ddd = new FileOutputStream("dert.txt"); int len=0; byte[] bytes = new byte[1024]; while ((len=s.read(bytes))!=-1){ ddd.write(bytes,0,len); ddd.flush(); } s.close(); ddd.close(); } }
原txt文件内容: #\u4E00\u6811\u68A8\u82B1\u538B\u6D77\u68E0 #Sat Aug 15 15:56:44 CST 2020 12dw3=14fd56 12df3=14df56 12de3=14fd56 12da3=14fd56 12dq3=14fd56 原txt文件内容: rtyrty=456789 r55ty=4555789 合并文件内容: #\u4E00\u6811\u68A8\u82B1\u538B\u6D77\u68E0 #Fri Aug 14 16:01:11 CST 2020 12dw3=14fd56 12df3=14df56 12de3=14fd56 12da3=14fd56 12dq3=14fd56 rtyrty=456789 r55ty=4555789
- SequenceInputStream(Enumeration<? extends InputStream> e)
-
三个文件的合并
public class MyTest { public static void main(String[] args) throws IOException { FileInputStream in1 = new FileInputStream("a.txt"); FileInputStream in2 = new FileInputStream("b.txt"); FileInputStream in3 = new FileInputStream("b.txt"); SequenceInputStream allIn = new SequenceInputStream(in1, in2); SequenceInputStream allIn2 = new SequenceInputStream(allIn, in3); FileOutputStream out = new FileOutputStream("ff.txt"); int len=0; byte[] bytes = new byte[1024]; while ((len=allIn.read(bytes))!=-1){ out.write(bytes,0,len); out.flush(); } allIn.close(); out.close(); } }