IO

IO流概述

可以将数据传输操作,看作一种数据的流动,按照流动的方向分为输入(Input)和输出(Output)
java中的IO操作主要指的是java.io包下的一些常用类的使用,通过这些常用类对数据进行读取(输入Input)和写出(输出Output)

IO流的分类

按照流的方向来分,可以分为:输入流和输出流
按照流动的数据类型来分,可以分为:字节流和字符流
计算机中的任何数据(文本、图片、视频、音乐等等)都是以二进制的形式存储的
在数据传输时也都是以二进制的形式存储的
后续的任何流,在传输时底层都是二进制
流在写完以后一定要关闭

字节流:一切皆字节

输入流:InputStream

常用方法:int read (byte[] b): 从输入流中读取一些字节数并将它们存储到缓冲区数组 b 。  int read (byte[] b, int off, int len): 从输入流 len最多 len字节的数据读入一个字节数组。  abstract int read():从输入流中读取下一个数据字节。  byte[] readAllBytes(): 从输入流中读取所有剩余字节。  int readNBytes (byte[] b, int off, int len): 从输入流中读取请求的字节数到给定的字节数组中。  byte[] readNBytes (int len): 从输入流中读取指定的字节数。  void mark (int readlimit) 标记此输入流中的当前位置。  void reset(): 将此流重新定位到上次在此输入流上调用 mark方法时的位置。 long transferTo (OutputStream out) 从该输入流中读取所有字节,并按读取顺序将字节写入给定的输出流。      void close(): 关闭此输入流并释放与该流关联的所有系统资源。  

常用子类:FileInputStream(实体类)文件输入流

构造方法:FileInputStream(File file): 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的 File对象 file命名。  FileInputStream (String name): 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的路径名 name命名。
常用方法:int available(): 返回可以从此输入流中读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。  void close(): 关闭此文件输入流并释放与该流关联的所有系统资源。  FileChannel getChannel(): 返回与此文件输入流关联的唯一FileChannel对象。  FileDescriptor getFD(): 返回 FileDescriptor对象,该对象表示与此 FileInputStream正在使用的文件系统中的实际文件的连接。  int read(): 从此输入流中读取一个字节的数据。  int read (byte[] b): 从此输入流 b.length最多 b.length字节的数据读 b.length字节数组。  int read (byte[] b, int off, int len): 从此输入流 len最多 len字节的数据读入一个字节数组。  long skip (long n): 跳过并从输入流中丢弃 n字节的数据。
​
注意:通过while (inputStream.read() != -1)这种方式来循环输出文件内容是不可行的,隔一个输出一个
​通过一组字节数组来获取文件内容,文件内容是进行覆盖操作,abcdefg,用一个长度为三的字节数组输出,输出结果为 abc def gef 最后一个是因为只有一个元素g了,覆盖了上一数组 def 就变成了 gef解决方案:byte[] bytes = new byte[3];int len = fis.read(bytes);sout(new String(bytes,0,len));使用重复输出时,数据读完后len == -1常用一组获得的方法

输出流:OutputStream(抽象类)

常用方法:void close():关闭此输出流并释放与此流关系的所有系统资源void flush():刷新此输出流并强制写出任何缓冲的输出字节static OutputStream nullOutputStream():返回一个新的OutputStream,它丢弃所有字节void write(byte[] b):将b.length字节从指定的字节数组写入此输出流void write(byte[] b,int off ,int len):将从偏移量off开始的指定字节数组汇总的len字节写入此输出流abstract void write(int b):将指定的字节写入此输出流

常用子类:FileOutputStream(实体类)文件输出流

构造方法:FileOutputStream (File file): 创建文件输出流以写入由指定的 File对象表示的文件。  FileOutputStream (File file, boolean append): 创建文件输出流以写入由指定的 File对象表示的文件。  FileOutputStream (String name): 创建文件输出流以写入具有指定名称的文件。  FileOutputStream (String name, boolean append): 创建文件输出流以写入具有指定名称的文件。 append参数表示是否是续写 新建对象时参数写的是true\false常用方法:void close():关闭此文件输出流并释放与此流关联的所有系统资源。  void write (byte[] b):将指定字节数组中的 b.length字节写入此文件输出流。  void write (byte[] b, int off, int len):将从偏移量 off开始的指定字节数组中的 len字节写入此文件输出流。    off是开始的下标。len是写出的长度void write (int b):将指定的字节写入此文件输出流。注意:流的所有操作都要在关闭(close())之前执行,在关闭后执行会报异常,而且关闭要尽可能早的关闭使用字节流输出一串字符串时,要先将字符串转换成byte,xx.getBytes();

字符流:

以字符为单位,解决了字节流字符乱码的问题

输入流:Reader

构造方法:protected  Reader(): 创建一个新的字符流阅读器,其关键部分将在阅读器本身上同步。  protected  Reader (Object lock): 创建一个新的字符流阅读器,其关键部分将在给定对象上同步。
常用方法:abstract void close(): 关闭流并释放与其关联的所有系统资源。  void mark (int readAheadLimit): 标记流中的当前位置。  boolean markSupported(): 判断此流是否支持mark()操作。  static Reader nullReader(): 返回不读取任何字符的新 Reader 。  int read(): 读一个字符。  int read (char[] cbuf): 将字符读入数组。  abstract int read (char[] cbuf, int off, int len): 将字符读入数组的一部分。  int read (CharBuffer target): 尝试将字符读入指定的字符缓冲区。  boolean ready(): 判断此流是否可以读取。  void reset(): 重置流。  long skip (long n): 跳过字符。  long transferTo (Writer out): 读取此阅读器中的所有字符,并按照读取的顺序将字符写入给定的编写器。
​

输出流:Writer

构造方法:protected  Writer(): 创建一个新的字符流编写器,其关键部分将在编写器本身上同步。  protected  Writer (Object lock): 创建一个新的字符流编写器,其关键部分将在给定对象上同步。
常用方法:Writer append (char c): 将指定的字符追加到此writer。  Writer append (CharSequence csq): 将指定的字符序列追加到此writer。  Writer append (CharSequence csq, int start, int end): 将指定字符序列的子序列追加到此writer。 abstract void close(): 关闭流,先冲洗它。  abstract void flush(): 刷新流。  static Writer nullWriter(): 返回一个新的 Writer ,它丢弃所有字符。  void write (char[] cbuf): 写一个字符数组。  abstract void write (char[] cbuf, int off, int len): 写一个字符数组的一部分。  void write (int c): 写一个字符。  void write (String str): 写一个字符串。  void write (String str, int off, int len): 写一个字符串的一部分。  append()方法返回的是调用append()方法的对象,所以append()方法可以套娃,xx.append().append()....;

转换流

将字节流 转换(装饰)为 字符流:使用了装饰者设计模式

InputStreamReader

构造方法:InputStreamReader(InputStream(要转换的字节输入流))

OutputStreamWriter

构造方法:OutputStreamWriter(OutputStream(要转换的字节输出流))

###

Print与BufferedReader

一种更好的字节流转换成字符流的方法

print

PrintStream:字节流
PrintWriter:字符流  记得最后要刷新流(flush) 或者 关闭(close)   操作方法:new PrintStream("地址")new PrintWriter("地址")FileOutputStream fos = new FileOutputStream("地址")new PrintStream(fos)FileWriter fw = new FileWriter("地址")new PrintWriter(fw)

BufferReader

缓存读取流,将字符输入流,转换为带有缓存 可以一次读取一行的缓存字符读取流
操作方法:FileReader fr = new FileReader("地址")new BufferReader(fr);

收集异常日志

try{String s =null;s.toString();
}catch(Exception e){e.printStackTrace();
}try{String s =null;s.toString();
}catch(Exception e){PrintWriter pw = new PrintWriter("地址");SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")pw.println(sdf);e.printStackTrace(pw);pw.close();
}

Properties

是使用键值对方式进行存储的
构造方法:Properties(): 创建一个没有默认值的空属性列表。常用方法:String getProperty (String key): 在此属性列表中搜索具有指定键的属性。  String getProperty (String key, String defaultValue): 在此属性列表中搜索具有指定键的属性。  void list (PrintStream out): 将此属性列表打印到指定的输出流。  void list (PrintWriter out): 将此属性列表打印到指定的输出流。  void load (InputStream inStream): 从输入字节流中读取属性列表(键和元素对)。  void load (Reader reader): 以简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。  void loadFromXML (InputStream in): 将指定输入流上的XML文档表示的所有属性加载到此属性表中。  Object setProperty (String key, String value): 调用 Hashtable方法 put 。void store (OutputStream out, String comments): 将此 Properties表中的此属性列表(键和元素对)以适合使用 load(InputStream)方法加载到 Properties表的格式写入输出流。  void store (Writer writer, String comments): 将此 Properties表中的此属性列表(键和元素对)以适合使用 load(Reader)方法的格式写入输出字符流。  void storeToXML (OutputStream os, String comment): 发出表示此表中包含的所有属性的XML文档。  void storeToXML (OutputStream os, String comment, String encoding): 使用指定的编码发出表示此表中包含的所有属性的XML文档。  void storeToXML (OutputStream os, String comment, Charset charset): 使用指定的编码发出表示此表中包含的所有属性的XML文档。  comment:输出到文件时的备注Set<String> stringPropertyNames(): 从此属性列表返回一组不可修改的键,其中键及其对应的值是字符串,如果尚未从主属性列表中找到相同名称的键,则包括默认属性列表中的不同键。

序列化与反序列化

能用,但不建议用,因为java官方说近几个版本会删除
使用序列化时,类和属性都必须实现序列化接口
存进去的一个ArrayList取出来也得是要个集合,不能

对象的序列化和反序列化实现

public class Student implements Serializable {private String stuNum;private String stuName;private List<String> teacherList;
}定义序列化和反序列化工具类
public class MySerializeUtil {//序列化public static void mySerialize(Object obj , String fileName) throws IOException {FileOutputStream ops = new FileOutputStream(fileName);ObjectOutputStream oos = new ObjectOutputStream(ops);oos.writeObject(obj);oos.close();}//反序列化public static Object myDeserialize (String fileName) throws IOException, ClassNotFoundException {FileInputStream fis = new FileInputStream(fileName);ObjectInputStream ois = new ObjectInputStream(fis);Object object = ois.readObject();return object;}}main方法测试
public static void main( String[] args ) throws IOException {ArrayList<String> teacher = new ArrayList<>();teacher.add("bdyjy");teacher.add("ssyy");Student student = new Student("20181271","szh",teacher);System.out.println("原始对象:" + student);String fileName = "stu.txt";try {MySerializeUtil.mySerialize(student,fileName);System.out.println("对象序列化完成");Object obj = MySerializeUtil.myDeserialize(fileName);System.out.println("对象反序列化完成");if (obj instanceof Student){Student NewStu = (Student) obj;System.out.println("反序列化后的对象:" + NewStu);}} catch (ClassNotFoundException e) {e.printStackTrace();}}执行结果:原始对象:Student{stuNum='20181271', stuName='szh', teacherList=[bdyjy, ssyy]}对象序列化完成对象反序列化完成反序列化后的对象:Student{stuNum='20181271', stuName='szh', teacherList=[bdyjy, ssyy]}同时 stu.txt 文件里面也有内容写入

部分属性的序列化

1.使用transient修饰符 : 使用该修饰符修饰的属性将不会被序列化
2.使用static修饰符 :static修饰符修饰的属性也不会参与序列化和反序列化。修改实体类,将实体类中不想序列化的属性添加static修饰词。
3.默认方法writeObject和readObject。private void writeObject(ObjectOutputStream objOut) throws IOException {System.out.println("writeObject-----------");objOut.writeObject(stuNum); objOut.writeObject(stuName); }private void readObject(ObjectInputStream objIn)throws IOException,ClassNotFoundException           { System.out.println("readObject-----------"); stuNum= (String) objIn.readObject(); stuName= (String) objIn.readObject(); }我们在添加的方法中只对stuNum和stuName属性做了序列化和反序列化的操作,因此只有这个两个属性可以被序列化和反序列化。注意:添加的两个方法必须是private void,否则不生效。

Externalizable实现Java序列化

刚刚我们说实现部分属性序列化的方式有多种,最后一种来啦!就是通过实现Eexternalizable接口。
Externalizable继承自Serializable,使用Externalizable接口需要实现readExternal方法和
writeExternal方法来实现序列化和反序列化。需要实现序列化和反序列化的类实现Externalizable接口,并重写里面的两个方法
@Override public void writeExternal(ObjectOutput out) throws IOException {out.writeObject(stuNum);out.writeObject(stuName);//out.writeObject(teacherList);}
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { stuNum= (String) in.readObject();stuName= (String) in.readObject();//teacherList= (List<String>) in.readObject();}Externalizable接口继承了Serializable接口,所以实现Externalizable接口也能实现序列化和反序列化。
Externalizable接口中定义了writeExternal和readExternal两个抽象方法,这两个方法其实对应
Serializable接口的writeObject和readObject方法。可以这样理解:Externalizable接口被设计出来的
目的就是为了抽象出writeObject和readObject这两个方法,但是目前这个接口使用的并不多。

序列化

Java序列化是指把Java对象转换为字节序列的过程,Java反序列化是指把字节序列恢复成Java对象的过程。通过序列化和反序列化实现网络传输、本地存储的目的。

Serializable实现Java序列化

要实现Java对象的序列化,只要将类实现标识接口--Serializable接口即可,不需要我们重写任何方法就可以实现序列化

Serializable VS Externalizable

区别 Serializable Externalizable
实现复杂度 实现简单,Java对其有内建支持 实现复杂,由开发人员自己完成
执行效率 所有对象由Java统一保存,性能较低 开发人员决定哪个对象保存,可能造成速度提升
保存信息 保存时占用空间大 部分存储,可能造成空间减少
使用频率 偏低

try-with-resources

JDK1.7之前  : 太麻烦,为了获取一个字符,写了一大段代码
FileReader fr = null;
try{fr = new FileReader("地址");int c = fr.read();sout((char)c);
}catch(IOExceprion e){e.printStackTrace();
}finally{try{fr.close();}catch(IOException e){e.printStackTrace();}
}JDK1.7时 : 耦合性太强,假如fr在前面就已经被定义,或者在后面还需调用的话,无法使用此方法
try(FileReader fr = new FileReader("地址")){int c = fr.read();sout((char)c);
}catch(IOException e){e.printStackTrace();
}JDK9进行优化  可自动关闭流。也不妨碍前后调用。需要关闭多个流,各个流之间用;隔开
FileReader fr = new FileREader("地址");
FileWriter fw = new FileWriter("地址");
try(fr;fw){int c = fr.read();sout((char)c);
}catch(IOException e){e.printStackTrace();
}

Java学习笔记-IO相关推荐

  1. JAVA学习笔记—IO流

    I/O 框架 流的概念 内存与存储设备之间传输数据的通道 水(相当于数据)-> 传输水的管道(相当于流)-> 脸盆(相当于内存) 生活用水 -> 流入 家庭废水 -> 流出 流 ...

  2. 【java学习笔记-io流 文件读写和键盘读写】带缓存的输入/输出流和数据输入/输出流

    文章目录 字节流类 带缓存的输入/输出流 BufferedReader与BufferedWriter类 下面的例子程序演示了read()方法,从控制台读取字符直到用户键入"q": ...

  3. Java学习笔记---IO操作

    一.文件的创建 ------------------------------------------------------- File类,表示磁盘上的文件或目录,可对文件或目录进行操作.    * ...

  4. java学习笔记IO之字节输入输出流

    IO字节输入输出流 OutputStream:字节输出流 该抽象类是所有字节输出流的超类: 定义了一些共性的成员方法: 1.写入一个字节 void write(int b);//b表示字节 2.写入字 ...

  5. 小陈java学习笔记IO

    文件拷贝 重点: 1.文件在读取的时候,就写到输出流的对象里,达到一边读一边写的效果 2.使用write()的时候,一定要规范使用方法,否则可能会输出无效 节点流和处理流 1.节点流可以从一个特定的数 ...

  6. Java学习笔记(7)——Java基础之IO多线程网络思维导图

    Java面向对象学习笔记之:包括IO(字节流,字符流,节点流,处理流).线程(线程创建,线程控制,线程同步).网络(TCP Scoket,  UDP Scoket)(全屏观看Java学习笔记(7)-- ...

  7. Java学习笔记(十)--控制台输入输出

    输入输出 一.控制台输入 在程序运行中要获取用户的输入数据来控制程序,我们要使用到 java.util 包中的 Scanner 类.当然 Java 中还可以使用其他的输入方式,但这里主要讲解 Scan ...

  8. java学习笔记16--I/O流和文件

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input  Output)流 IO流用来处理 ...

  9. java学习笔记8--接口总结

    接着前面的学习: java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3- ...

最新文章

  1. 什么时候需要在外壳变量周围花括号?
  2. Hibernate(一)__简介
  3. [云炬python3玩转机器学习] 5-9 scikit-learn中的回归问题
  4. php导出csv数据在浏览器中输出提供下载或保存到文件的示例
  5. tomcat配置多站点
  6. 零宽断言 python_正则表达式-零宽断言
  7. Elasticsearch性能监控(二)
  8. python爬虫结果是字节_入门爬虫?一文搞定!
  9. linux 切换pip路径_【Python基础】PIP 镜像源配置轻松搞定
  10. k8s-controller manager原理分析
  11. vmware windows linux udp通信,windows 下 udp socket
  12. Win10验证USB Audio MIC(三)
  13. python中while true的用法_python入门:while循环里面True和False的作用,真和假
  14. 【OFDM通信】基于块状导频的信道估计算法仿真含Matlab源码
  15. JVM-垃圾回收机制
  16. java继承和接口的区别_java中的接口与继承的区别
  17. 那些活在浪里的创业者最终被拍成了电影
  18. C++ delete指针需置空
  19. 阿里云服务器租用费用
  20. 阿里云的esc服务器介绍

热门文章

  1. 【计算机科学基础】元宇宙的最新技术、应用和挑战
  2. 《科研伦理与学术规范》 期末考试,题目文档汇总(免费分享 )
  3. 数据管理能力成熟度模型(DMM)
  4. 19 Three.js实现雾化效果
  5. 51单片机实现简易闹钟(包含闹钟功能)
  6. excel学习-数据透视图(插入+设置样式+加公司logo+设置logo大小+删除表中多余东西)
  7. JSP 和 JavaBean 来实现一个简易计算器
  8. 乔治亚大学招收计算机视觉/深度学习/机器人/自动驾驶博士生from 2023 spring
  9. Facebook加密项目Libra浮出水面,Visa和万事达卡「入伙」
  10. Python数据可视化 Pyecharts 制作 PictorialBar 象形柱状图