day22-序列流/内存流/对象操作流/打印流/随机流

22.01_IO流(序列流)(了解)

序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.

  • 整合两个: SequenceInputStream(InputStream, InputStream)
FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2); //整合2个输入流
FileOutputStream fos = new FileOutputStream("c.txt"); //输出流

int a ;
while((a = sis.read()) != -1) {
    fos.write(a);
}

sis.close();  //sis关闭的时候,会将内部的输入流都关闭掉
fos.close();

22.02_IO流(序列流整合多个)(了解)

  • 整合多个: SequenceInputStream(Enumeration)
Vector<FileInputStream> v = new Vector<>();
v.add(new FileInputStream("a.txt"));
v.add(new FileInputStream("b.txt"));
v.add(new FileInputStream("c.txt"));
// 利用枚举,将多个输入流整合成一个
SequenceInputStream sis = new SequenceInputStream(v.elements());
FileOutputStream fos = new FileOutputStream("d.txt");
int data ;
while( (data = sis.read()) != -1) {
    fos.write(data);
}

sis.close();
fos.close();

22.03_IO流(内存输出流)(掌握)

该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据

  • 2.使用方式
    • 创建对象: new ByteArrayOutputStream()
    • 写出数据: write(int), write(byte[])
    • 获取数据: toByteArray()
FileInputStream fis = new FileInputStream("a.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //相当于在内存中创建了可以增长的数组
int b ;
while( (b = fis.read()) != -1) {
    baos.write(b);  // 此时其实是写数据到了内存里面
}

byte[] arr = baos.toByteArray(); //将缓冲区的数组全部拿出来, 并赋值给arr数组
System.out.println(new String(arr));
System.out.println(baos.toString()); //使用平台默认码表将缓冲区内容转为字符串

fis.close();

22.04_IO流(内存输出流之面试题)(掌握)

  • 定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)
FileInputStream fis = new FileInputStream("a.txt");      //创建字节输入流,关联a.txt
ByteArrayOutputStream baos = new ByteArrayOutputStream();   //创建内存输出流
byte[] arr = new byte[5];      //创建字节数组,大小为5
int len;
while((len = fis.read(arr)) != -1) {        //将文件上的数据读到字节数组中
    baos.write(arr, 0, len);   //将字节数组的数据写到内存缓冲区中
}
System.out.println(baos);       //将内存缓冲区的内容转换为字符串打印
fis.close();

22.05_对象操作流ObjecOutputStream(了解)

该流可以将一个对象写出, 或者读取一个对象到程序中. 也就是执行了序列化反序列化的操作.

  • 写出: new ObjectOutputStream(OutputStream), writeObject()
//无论是字节输出流,还是字符输出流都不能直接写出对象

Person p1 = new Person("我啊", 20);
Person p2 = new Person("你啊", 56);
// 这个其实也是装饰模式
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));

oos.writeObject(p1);
oos.writeObject(p2);
oos.close();

22.06_对象操作流ObjectInputStream(了解)

  • 读取: new ObjectInputStream(InputStream), readObject()
// 读取对象(反序列化)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));

Person p1 = (Person) ois.readObject();  //可能有ClassNotFoundException
Person p2 = (Person) ois.readObject(); //当读取到文件末尾,继续读取,会出现EOFException

System.out.println(p1);
System.out.println(p2);
ois.close();

22.07_对象操作流优化(了解)

// 1.读写多个对象时,将对象添加到集合里,写出集合,就不用考试多少个对象问题
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("我啊", 20));
list.add(new Person("你啊", 56));

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(list);
oos.close();

// 2.读取多个对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
@SuppressWarnings("unchecked")
ArrayList<Person> aList = (ArrayList<Person>) ois.readObject(); 
for (Person person : aList) {   //泛型在运行期会被擦除,索引运行期相当于没有泛型
    System.out.println(person);
}
ois.close();

关于Java泛型的一点思考

其实学好、学扎实编程语言的基础,十分重要,对日后编程有十分有帮助。如果你掌握了编程语言的高级语法,基础十分扎实(内功深厚),那么你写出的代码,将比其他人写的代码有水平很多。
另外就是如果你又扎实深厚的基础,那么也能大大减少日后编程中犯低级错误。

ArrayList<Integer> l1 = new ArrayList<>();
l1.add(100);

ArrayList l2 = null;
l2 = l1;  //泛型擦除 ,证明Java泛型是伪泛型,JVM编译时,并没有核对泛型信息,绕过了类型检查
从反射也能说明Java泛型,只是编译时有效,运行后会去泛型化
l2.add("dftd");
//
System.out.println(l2.get(0).getClass());
System.out.println(l2.get(1).getClass());
System.out.println(l1.size());
Integer temp = l1.get(1);  //泛型擦除,带来的隐患,报错

22.08_IO流(加上id号)(了解)

  • 要写出的对象必须实现Serializable接口才能被序列化
  • 不用必须加id号
/**
 * serialVersionUID 序列化版本号,为了序列化时,如果增加了属性,或方法,反序列化之前的版本,能提示出问题所在。
 * 其实不加也行,因为加不加,在反序列老版本对象都会出现异常错误。
 */
private static final long serialVersionUID = 1L;

22.09_IO流(打印流的概述和特点)(掌握)

该流可以很方便的将对象的toString()结果输出, 并且自动加上换行, 而且可以使用自动刷出的模式

System.out就是一个PrintStream, 其默认向控制台输出信息

PrintStream ps = System.out;
ps.println("xxoo");
ps.println(97);  // 底层将 数字97 转为了字符串

ps.write(97);  //打印 a
ps.close();
----------------------分割线--------------------

PrintWriter pw2 = new PrintWriter(new FileOutputStream("a.txt"), true);
pw2.println(97);  // 自动刷出功能,只针对  println() 方法
pw2.write(97);  // 并不会写到文件里

pw2.close();  // 因为流操作都会要close,所以自定刷出其实没有什么卵用

// PrintStream 和 PrintWriter分别打印的是字节流和字符流
// 二者只操作数据目的,不操作 数据源

22.10_标准输入输出流概述和输出语句

  • System.inInputStream, 标准输入流, 默认可以从键盘输入读取字节数据
  • System.outPrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据
  • 2.修改标准输入输出流(了解)
System.setIn(new FileInputStream("a.txt")); //改变标准输入流
System.setOut(new PrintStream("b.txt"));  //改变标准输出流

InputStream is = System.in;  //此时已经指向文件了,而不是键盘了
PrintStream ps = System.out;  //此时不再指向控制台,而是b.txt

int data ;
while( (data = is.read()) != -1) {
    ps.write(data);
}
is.close();  // 因为关联的文件,所以要关闭输入流和输出流
ps.close();

22.11_IO流(修改标准输入输出流拷贝图片)(了解)

System.setIn(new FileInputStream("xxoo.jpg")); //改变标准输入流
System.setOut(new PrintStream("copy.jpg"));  //改变标准输出流
InputStream is = System.in;  
PrintStream ps = System.out;  

byte[] data = new byte[1024 * 10];
int len;
while( (len = is.read(data)) != -1) {
    ps.write(data, 0, len);
}
is.close();  
ps.close();

22.11_IO流(两种方式实现键盘录入)(了解)

// 2种键盘录入
// InputStreamReader转换流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
br.close();
System.out.println(str);

Scanner sc = new Scanner(System.in);  // 第二种键盘输入
String str2 = sc.nextLine();
sc.close();
System.out.println(str2);

22.12_随机访问流概述和读写数据)(了解)

  • RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStreamOutputStream的功能。
  • 支持对随机访问文件的读取和写入。
  • 这个seek()跳字节读取的功能,可以用于多线程下载和上传。
RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");

raf.write(97);  //写入 a

int x = raf.read();  // 读取 (发现读取的不是97,说明指针移到了下一个字节)
System.out.println(x);

raf.seek(10);  //当当前指针遇到10的位置
raf.write(120);

raf.close();

22.13_IO流(数据输入输出流)(了解)

  • DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
  • 例如按Long大小写出一个数字, 写出时该数据占8字节. 读取的时候也可以按照Long类型读取, 一次读取8个字节.
DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
dos.writeInt(997);  //写入真实的 997 ,
dos.writeInt(998);
dos.close();

DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
System.out.println(dis.readInt());  // 按照 int读取一个值
System.out.println(dis.readInt());
dis.close();

// 因为write(int a) 虽然接收是int,但是实际是byte类型的转换,实际写入时,不会超过byte的取值范围
// 00000000 00000000 00000011 11100101 int类型的997 
// 11100101 真实写入的值, write写入会去掉int的前24位,而11100101找不到对应的码表,就会是乱码
// 00000000 00000000 00000000 11100101 读取之后的int已经是 229了
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(997);   //结果发现写入之后是乱码的
fos.close();

22.14_Properties的概述和作为Map集合的使用(了解)

  • Properties 类表示了一个持久的属性集,本质是一个双列集合,因为键值都是字符串,所以没有泛型。
  • Properties 可保存在流中或从流中加载。
  • 属性列表中每个键及其对应值都是一个字符串。
Properties pp = new Properties();
pp.put("verson", "2.3.0");
System.out.println(pp);

22.15_Properties的特殊功能使用(了解)

  • Properties的特殊功能
Properties pp = new Properties();
pp.setProperty("verson", "3.2.0");  //向里面添加键值对
pp.setProperty("type", "android");

// 遍历 (强转是因为泛型问题)
Enumeration<String> enu = (Enumeration<String>) pp.propertyNames();
while(enu.hasMoreElements()){
        String key = enu.nextElement() ;
        System.out.println( key + "-->" + pp.get(key));  // 根据key,获取value
}

22.16_Properties的load()和store()功能(了解)

Properties pp = new Properties();
pp.load(new FileInputStream("config.list"));  //将文件上的键值对读取到集合中
System.out.println(pp);

// 修改配置
pp.setProperty("name", "Java EE");
// 写入配置文件
pp.store(new FileOutputStream("config.list"), "我是描述信息,可以为null");

END。
我是小侯爷。
在魔都艰苦奋斗,白天是上班族,晚上是知识服务工作者。
如果读完觉得有收获的话,记得关注和点赞哦。
非要打赏的话,我也是不会拒绝的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容