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

2017-02-14  本文已影响71人  苦笑男神

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

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

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流(序列流整合多个)(了解)

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流(内存输出流)(掌握)

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

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流(内存输出流之面试题)(掌握)

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(了解)

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

//无论是字节输出流,还是字符输出流都不能直接写出对象

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(了解)

// 读取对象(反序列化)
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号)(了解)

/**
 * 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.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 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流(数据输入输出流)(了解)

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 pp = new Properties();
pp.put("verson", "2.3.0");
System.out.println(pp);

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

上一篇 下一篇

猜你喜欢

热点阅读