学习心得
心情
还是关于IO流,也就是输入输出,感觉这几天现在才算了解一下计算机传输文件时候都做了什么,很神奇。
掌握情况:还行
IO流:(输入输出流)
File类不能操作文件
1.按照流向分:
输入流:从硬盘上读取数据到内存(读)
输出流:从内存写出数据到硬盘(写)
一个文件在传输过程中,经历了多次拷贝。IO本身效率低
零拷贝!!。Nio附加题!!
2.按照操作单元分
字节流:是一个字节一个字节的操作,二进制操作,操作任意类型的文件,万能。
字符流:一个字符一个字符的操作,一个字符两个字节,主要用来处理文本文件。
.txt/ .java/.py。。。。。。
3.按照角色划分
节点流:直接操作一个特定的IO设备
处理流:在节点流的基础上,做进一步的处理
Java中的输入流、输出流常用的流:
|
字节输入流 |
字节输出流 |
字符输入流 |
字符输出流 |
|
|
抽象基类 |
InputStream |
OutputStream |
Reader |
Writer |
|
访问文件 (节点流) |
FileInputStream |
FileOutputStream |
FileReader |
FileWriter |
|
缓冲流 (处理流) |
BufferedInputStream |
BufferedOutputStream |
BufferedReader |
BufferedWriter |
|
操作对象 |
ObjectInputStream |
ObjectOutputStream |
字节输入流:
1.创建一个FileInputStream对象
2.定义一个标记,用来控制输入流的读取
3.循环读取,如果读取到了-1,说明读取到了文件末尾,循环结束
4.关闭资源。
注意:我们发现一个流读完了就没有了,不能再读了
当一个流读完之后就会默认调用mark 和 reset 方法来进行记录和重置。这个流就已经重置到上一次读取完的位置。所以不能再读了。并不是关闭了流。
字节输出流:
FileOutputStream构造器:
boolean append 参数:如果传入true,则表示在原有基础上追加,不覆盖。如果传入false,或者不传,覆盖原有内容。
写的操作:目标文件如果不存在,就会新建
字符处理流: (用的最多)
缓冲流:只能处理纯文本文件:
.txt,.java,.html,.css.........
利用缓冲字符流来写一个文件的复制
import java.io.*; import java.util.Objects; public class Ch04 { @Test public void test01(){ // File file = new File("D:\\IDEJR\\TryPlay\\aaa.txt"); FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { fileInputStream = new FileInputStream("D:\\IDEJR\\TryPlay\\aaa.txt"); fileOutputStream = new FileOutputStream("D:\\IDEJR\\TryPlay\\houhou\\aaa.txt"); byte [] bytes= new byte[1024]; int len; while ((len = fileInputStream.read(bytes)) !=-1){ fileOutputStream.write(bytes,0,len); } } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } finally { try { if (Objects.isNull(fileInputStream)){ fileOutputStream.close(); } } catch (IOException e) { throw new RuntimeException(e); } } }
或者
public class Ch01 { public static void main(String[] args) { BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { bufferedReader = new BufferedReader(new FileReader("D:\\IDEJR\\TryPlay\\aaa.txt")); bufferedWriter = new BufferedWriter(new FileWriter("D:\\IDEJR\\TryPlay\\bbb.txt")); String str; while((str = bufferedReader.readLine()) != null){ bufferedWriter.write(str); bufferedWriter.newLine(); } System.out.println("文件复制成功!!!"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtil.closeIO(bufferedReader,bufferedWriter); } }
可以看出复制成功!!!

序列化和反序列化,操作对象
序列化:将对象写入IO流中,将内存模型的对象变成字节数字。可以进行存储和传输。
反序列化:从IO流中恢复对象,将存储在硬盘上或者从网络上接收的数据恢复成对象模型。
使用场景:所有可在网络上传输的对象都必须是可序列化的。否则会报错,所有保存在硬盘上的对象也必须是可序列化的。
序列化版本号:
反序列化必须拥有 class 文件,但随着项目的升级,class 文件也会升级,序列化保证升级前后的兼容性。
java 序列化提供了一个版本号
版本号是可以自由指定,如果不指定,JVM会根据类信息自己计算一个版本号,所以无法匹配,则报错!!!
不指定版本号,还有一个隐患,不利于JVM的移值,可能 class 文件没有改,但是不同的JVM计算规则不一样,导致无法反序列化。
如果只修改了方法,反序列化不受影响,无需修改版本号。
修改了静态变量 static ,瞬态变量 transient ,反序列化也不受影响,无需修改版本号。
public class Ch02 { @Test public void test02() { ObjectInputStream objectInputStream = null; // 先锁定一个文件 try { objectInputStream = new ObjectInputStream(new FileInputStream("D:/user.txt")); User user = (User) objectInputStream.readObject(); System.out.println("对象读取成功:" + user); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } finally { IOUtil.closeIO(objectInputStream,null); } } @Test public void test01() { ObjectOutputStream objectOutputStream = null; // 先锁定一个文件 try { objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/user.txt")); User user = new User("张三",25,1); objectOutputStream.writeObject(user); System.out.println("对象写出成功..."); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { IOUtil.closeIO(null,objectOutputStream); }
总结:
- 1.所有需要网络传输的对象都需要实现序列化接口
- 2.对象的类名,实例变量都会被序列化;方法,类变量,transient变量不会被序列化
- 3.如果想让某个变量不被序列化,可以用transienrt修饰
- 4.序列化对象引用类型成员变量,也必须是可序列化的,否则会报错
- 5.反序列化时必须有系列化对象的 class 文件
- 6.如果同一个对象被序列化多次,只有第一次序列化为二进制流,以后都只是保存系列化的版本号。
- 7.建议所有的可序列化的类加上版本号,方便项目升级。
我们最终会把所有的.class文件打包,把这个包部署到服务器上
java是程序员写的,程序员看的
. java不会参与打包,不会出现到服务器上
我们的 . properties 属性文件不会参与编译,一旦数据库升级,改变此文件即可,否则要改变源码,耗费资源。

浙公网安备 33010602011771号
你点我就回上面去了ヾ(≧O≦)〃嗷~