Java IO流 、 Properties 、 枚举

来源:互联网 发布:域名证书在线生成 编辑:程序博客网 时间:2024/06/06 10:58

一、概述

  • IO流流动的是数据 --- 用于传输数据的API。
  • InputStream\OutputStream   ---   输入输出流
  • 根据流的传输方向分类 : 
    • 当数据从外部流入程序时  : 输入流
    • 当数据从程序流向外部时 : 输出流
  • 根据流的传输形式分类: 
    • 字节流
    • 字符流
  • 不同形式交汇,得到四种基本操作流的类  , 四个基本流都是抽象类       输入流      输出流    字符流          Reader      Writer    字节流      InputStream            OutputStream     
  • 数据的来源: 硬盘、网络、内存、输入设备
  • 字符输入流示例:
    public class FileWriterDemo1 {public static void main(String[] args) throws Exception {// 无论这个文件是否存在,都会创建一个新的文件 ,不存在则创建,存在则覆盖FileWriter writer = new FileWriter("E:\\a.txt");// 写出数据// java在底层对字符流设计了一个缓冲区,数据并不是直接写到目的地而是先写到了缓冲区中// 等缓冲区满了之后才会将缓冲区中的数据一次性的放到目的地中。// 由于缓冲区没有满而代码已经结束,所以数据就死在了缓冲区中writer.write("def");// 冲刷缓冲区// writer.flush();// 关闭流对象// 流在关闭之前会自动的冲刷缓冲区,以防有数据死在缓冲区中writer.close();// 流在关闭之后依然存在,依然在占用内存writer = null;System.out.println(writer);}}

  • 字符输出流示例:
    public class FileReaderDemo2 {public static void main(String[] args) throws Exception {FileReader reader = new FileReader("E:\\a.txt");// 创建一个字符数组作为缓冲区char[] cs = new char[5];// 定义一个变量来记录每次读取到字符个数int len = -1;// 读取数据,将数据读取到字符数组中while ((len = reader.read(cs)) != -1) {System.out.println(new String(cs, 0, len));}// 关流reader.close();}}

  • 字节输入流示例:
    public class FileInputStreamDemo {public static void main(String[] args) throws Exception {FileInputStream fin = new FileInputStream("E:\\a.txt");// 创建一个字节数组作为缓冲区byte[] bs = new byte[3];// 定义一个变量来记录每次读取的字节个数int len = -1;while ((len = fin.read(bs)) != -1) {System.out.println(new String(bs, 0, len));}fin.close();}}

  • 字节输出流示例:
    public class FileOutputStreamDemo {public static void main(String[] args) throws Exception {FileOutputStream writer = new FileOutputStream("E:\\c.txt");// 没有缓冲区writer.write("abc".getBytes());// 关流writer.close();}}

二、流的异常处理

  • 第一步:流对象外置定义  内置初始化
  • 第二步:防止流对象关闭时出现空指针异常 ,关闭前 对流对象判空
  • 第三步:如果关流失败,则强制释放  ;如果关流成功,则释放流对象 ,释放内存
  • 第四步:防止关流失败 ,在关流之前手动冲刷缓冲区
  • 示例:
    package cn.tedu.io.file;import java.io.FileWriter;import java.io.IOException;public class FileWriterDemo2 {public static void main(String[] args) {// 流对象要外置定义,在外置定义的时候需要把这个流对象置为nullFileWriter writer = null;try {// 内置初始化writer = new FileWriter("E:\\b.txt");writer.write("abcdefg");// 为了防止关流失败导致一部分数据的丢失,因此需要提前进行flush来保证数据的完整性writer.flush();} catch (Exception e) {e.printStackTrace();} finally {// 需要判断流对象是否初始化成功if (writer != null) {try {writer.close();} catch (IOException e) {e.printStackTrace();} finally {// 如果关流失败则强制回收流对象以释放文件// 如果关流成功则用于释放这个流对象占用的内存writer = null;}}}}}

  • 练习: 剪切文件
    public class CutFileDemo {public static void main(String[] args) throws Exception {// 创建一个file对象指向源文件File oldFile = new File("E:\\a.txt");// 创建一个输入流指向源文件FileReader reader = new FileReader(oldFile);// 创建一个输出流来指向新文件FileWriter writer = new FileWriter("D:\\a.txt");// 创建一个字符数组作为缓冲区char[] cs = new char[10];// 定义一个变量记录每次读取到字符个数int len = -1;// 读取数据while ((len = reader.read(cs)) != -1) {// 将读取到数据写出writer.write(cs, 0, len);}// 关流reader.close();writer.close();// 删除源文件oldFile.delete();}}


三、缓冲流

  • BufferedReader :从字符输入流中读取数据 , 提供一个缓冲区 , 允许按行读取
  • BufferWriter : newLine() 产生新的一行。
  • 字符输入缓冲流示例:
    public class BufferedReaderDemo {public static void main(String[] args) throws Exception {// 实际上读取数据的流是FileReader, BufferedReader的作用是为这个流提供了一个缓冲区BufferedReader reader = new BufferedReader(new FileReader("E:\\a.txt"));// 按行读取数据String line = null;while((line = reader.readLine()) != null){System.out.println(line);}// 关流---从里向外依次关闭// Stream Already closed.reader.close();}}

四、字节流

  • 可以用字节流来读取任意文件  ,如: 视频 、音频

五、转换流

  • 将字节转换为字符示例: 
    public class InputStreamReaderDemo {public static void main(String[] args) throws Exception {// 实际上读取数据的FileInputStream,转换流将字节转化为字符InputStreamReader ir = new InputStreamReader(new FileInputStream("E:\\d.txt"), "utf-8");// 数据是以字符形式来返回的char[] cs = new char[4];int len = -1;while ((len = ir.read(cs)) != -1) {System.out.println(new String(cs, 0, len));}ir.close();}}

  • 将字符转换为字节示例:
    public class OutputStreamWriterDemo {public static void main(String[] args) throws Exception {// 在底层实际上传输数据的是FileOutputStream,转换流提供的操作是将字符转化为字节// 当没有指定转换编码的时候,默认使用的是系统平台码OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream("E:\\d.txt"), "utf-8");// 写出数据ow.write("转换");// 关流ow.close();}}

  • 练习: 改变文件的编码
    public class ChangeEncodeExer {public static void main(String[] args) throws Exception {// 创建一个file对象指向源文件File file = new File("F:\\java基础增强.txt");// 创建一个file对象指向临时文件File temp = new File("F:\\temp.txt");// 创建一个输入流来读取源文件BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));// 创建一个输出流将读取的内容写到临时文件中// BufferedWriter bw = new BufferedWriter(new FileWriter(temp));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(temp)));// 定义一个变量来记录读取的每行数据String msg = null;// 读取数据while ((msg = br.readLine()) != null) {// 将读取到的数据写出bw.write(msg);// 换行bw.newLine();}// 关流br.close();bw.close();// 删除源文件file.delete();// 重命名新文件temp.renameTo(file);}}

六、系统流\标准流

  • 系统流示例:
    public class SystemDemo {public static void main(String[] args) throws Exception {// 系统流都是字节流int i = System.in.read();// 在使用的时候没有任何差别,只是在输出结果上有颜色的差别// 如果是正常的结果使用out来输出打印,如果是错误的结果会使用err来输出打印System.out.println(i);System.err.println(i);System.out.println(new char[]{'a','d'});System.out.println(new int[]{'a','d'});}}

  • 练习: 从控制台读取内容后输出
    public class GetLineExer {public static void main(String[] args) throws Exception {// 从控制台获取---System.in// 获取一行数据---BufferedReader// System.in是一个字节,BufferedReader需要一个字符流---字节转化成字符---InputStreamReaderBufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println(br.readLine());br.close();// br = new BufferedReader(new InputStreamReader(System.in));// System.out.println(br.readLine());// br.close();}}

七、打印流


八、 合并流

  • 示例:
    public class SequenceInputStreamDemo {public static void main(String[] args) throws Exception {// 创建输入流分别对应的文件FileInputStream in1 = new FileInputStream("E:\\a.txt");FileInputStream in2 = new FileInputStream("E:\\c.txt");FileInputStream in3 = new FileInputStream("E:\\d.txt");// 创建一个Vector集合Vector<InputStream> vec = new Vector<InputStream>();vec.add(in1);vec.add(in2);vec.add(in3);// 转化为一个EnumerationEnumeration<InputStream> e = vec.elements();// 创建合并流对象SequenceInputStream sis = new SequenceInputStream(e);// 读取数据byte[] bs = new byte[10];int len = -1;// 在合并的时候没有办法控制文件的编码while ((len = sis.read(bs)) != -1) {System.out.println(new String(bs, 0, len));}// 关流sis.close();}}

九、序列化流\反序列化流

  • 示例:
    public class Person implements Serializable {// 版本号---用版本号来标识一个类。// 当一个对象反序列化回来的时候,会自动的比较对象中的版本号和当前类中的版本号是否一致、// 如果一致Java才认为这个对象是本类的对象,才允许反序列化// 如果没有手动指定版本号,JVM在编译的时候会根据当前类中的方法和属性自动计算一个版本号// private static final long serialVersionUID = 329L;private static final long serialVersionUID = 6920415629894220824L;private String name;private int age;private char gender;private double heigh;// 被transient修饰的属性不能被序列化private transient double weight;public double getHeigh() {return heigh;}public void setHeigh(double heigh) {this.heigh = heigh;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}// public static boolean alive;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class SerialDemo {public static void main(String[] args) throws Exception {// 准备要序列化的对象Person p = new Person();p.setName("酸菜鱼");p.setAge(16);p.setWeight(190);// p.alive = true;// 创建一个用于序列化的流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\p.data"));// 将对象序列化出去oos.writeObject(p);// 关流oos.close();}}public class DeserialDemo {public static void main(String[] args) throws Exception {// 创建反序列化流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\p.data"));// 反序列化对象Person p = (Person) ois.readObject();// 关流ois.close();System.out.println(p.getName());System.out.println(p.getAge());// 如果一个属性没有序列化出去,那么反序列化回来的时候会给这个属性一个默认值System.out.println(p.getWeight());}}

  • 序列化加密示例:
    public class 加密例子 {Key key;public void serial(Person p) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,IllegalBlockSizeException, IOException {// 需要找制作钥匙的对象// 在此的规则指的加密算法---对称加密,非对称加密KeyGenerator generator = KeyGenerator.getInstance("DESede");// 产生钥匙key = generator.generateKey();// 产生锁Cipher cipher = Cipher.getInstance("DESede");// 将锁和钥匙配对// 第一个参数表示钥匙和锁的配对模式cipher.init(Cipher.ENCRYPT_MODE, key);// 找盒子SealedObject so = new SealedObject(p, cipher);// 将盒子序列化出去ObjectOutputStream ois = new ObjectOutputStream(new FileOutputStream("p.data"));ois.writeObject(so);ois.close();}public Person deSerial() throws FileNotFoundException, IOException, ClassNotFoundException, InvalidKeyException, NoSuchAlgorithmException{// 创建反序列化流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("p.data"));// 反序列化盒子SealedObject so = (SealedObject) ois.readObject();// 关流ois.close();// 将对象从盒子中取出return (Person) so.getObject(key);}public static void main(String[] args) throws Exception {加密例子 demo = new 加密例子();Person p = new Person();p.setName("张三疯");p.setAge(500);p.setGender('男');demo.serial(p);}}

十、 Properties

  • 示例:
    public class PropertiesDemo1 {public static void main(String[] args) throws Exception {// 创建properties对象Properties prop = new Properties();// 添加键值对prop.setProperty("key", "value");prop.setProperty("second", "value");// 持久化这个映射---必须存储到properties文件中// 第二个参数表示给properties文件添加一个注释---用于解释当前properties文件的作用prop.store(new FileOutputStream("c.properties"), "this is a demo .");}}

  • public class PropertiesDemo2 {public static void main(String[] args) throws Exception {Properties prop = new Properties();// 反序列化prop.load(new FileInputStream("c.properties"));System.out.println(prop.getProperty("key"));System.out.println(prop.getProperty("second","ok"));// 如果键不存在,则返回一个null// 如果键不存在,则返回指定的值---第二个参数System.out.println(prop.getProperty("键", "non"));}}


十一、 枚举

  • 示例1:
    public class EnumDemo {@SuppressWarnings("unused")public static void main(String[] args) {Season s = Season.Autumn;}}class Season {// 不允许在类外随意创建对象private Season() {}static final Season Spring = new Season();static final Season Summer = new Season();static final Season Autumn = new Season();static final Season Winter = new Season();}

  • 示例2:
    public class EnumDemo2 {public static void main(String[] args) {Level l = Level.B;// l.print();switch (l) {case A:System.out.println("ok");break;case B:System.out.println("B~~~");break;default:break;}}}enum Level {// 默认构造函数是私有的而且只能是私有的// 每个枚举常量之间用 , 隔开,最后一个枚举常量之后最好加上 ; 表示结束// public static final Level A = new Level();// 枚举常量必须定义在枚举类的首行A(90) {@Overridepublic void print() {System.out.println("优秀");}},B(80) {@Overridepublic void print() {System.out.println("良好");}},C(70) {@Overridepublic void print() {System.out.println("中等");}},D(60) {@Overridepublic void print() {System.out.println("及格");}},E(0) {@Overridepublic void print() {System.out.println("不及格");}};private Level(double score) {this.score = score;}private Level() {}private double score;public static double average;public double getScore() {return score;}public static void set(double sum) {System.out.println(sum / average);}public void setScore(double score) {this.score = score;}public abstract void print();}

原创粉丝点击