javaSE高级开发之文件I/O(下)

转换流

1.输入字节流—InputStreamReader类

InputStreamReader是Reader的子类,可以将一个字节输入流转为字符输入流。
构造方法:

InputStreamReader(InputStream in) 
创建一个使用默认字符集的InputStreamReader。  

InputStreamReader(InputStream in, Charset cs) 
创建一个使用给定字符集的InputStreamReader。  

InputStreamReader(InputStream in, CharsetDecoder dec) 
创建一个使用给定字符集解码器的InputStreamReader。  

InputStreamReader(InputStream in, String charsetName) 
创建一个使用命名字符集的InputStreamReader。 
 File file = new File("D:\\TL-BITE\\Test\\test1\\otptsmwriter.txt");
       if(!file.getParentFile().exists()){
           file.getParentFile().mkdirs();
       }
       try(
        OutputStream outputStream=new FileOutputStream(file);
        Writer writer=new OutputStreamWriter(outputStream)
        ){
           String msg="I 老虎 U! !!";
           writer.write(msg);

       }catch (IOException e){

       }

字符编码

GBK、GB2312:国标编码,GBK包含简体中文和繁体中文;GB2312只包含简体中文。
UNICODE编码:Java提供的16进制编码,可以描述世界上任意文字信息,若全部采用UNICODE编码,会造成网络传输负担。
ISO8859-1编码:国际通用编码
UTF编码:结合了UNICODE,ISO8859-1.

缓冲流

public BufferedReader(Reader in)

在读写数据时,让数据有缓冲区能减少系统实际对原始数据来源做存取的次数,因此使用缓冲区的流(即缓冲流),一般比没有缓冲区的流效率更高,包括BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
1.BufferedReader类
是Reader的子类,Reader类的方法read()每次都从数据源读入一个字符,为了提高效率,使用BufferedReader来配合其他字节流。BufferedReader提高readLine()可以分行读取文本。

 File file=new File("D:\\TL-BITE\\Test\\write.txt");
        Reader read=null;
        String str="";
        BufferedReader bin=null;
        try{
           read=new FileReader(file);
           
           //BufferedReader需配合其他字节流
           bin=new BufferedReader(read);
           str=bin.readLine();

        }catch (IOException e){

        }
        System.out.print(str);

2.BufferedWriter类
BufferedWriter是Writer的子类,BufferedWriter类主要改变的是重写了flush()方法,该方法可以确保缓冲区里的数据确实被写到输出流,BufferedWriter提供了缓冲区,能更有效率的写出字符数据流。

public BufferedWriter(Writer out)
  File file=new File("D:\\TL-BITE\\Test\\buffwrite.txt");
        FileWriter fw=null;
        BufferedWriter bw=null;
        String[] str={"锲而不舍","朽木不折"};
        try{
            fw=new FileWriter(file);
            bw=new BufferedWriter(fw);
            for(int i=0;i<str.length;i++){
                bw.write(str[i]);
                bw.newLine();//写一个结尾\n,以达到换行的目的
            }
                bw.close();
                fw.close();
        }catch (IOException e){
            e.printStackTrace();
        }

内存操作流

内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除。因此需要进行IO处理,但是又不希望产生文件。这种情况下就可以使用内存作为操作终端。

1.ByteArrayInputStream类–内存输入流

ByteArrayInputStream是一个把字节数组作为源的输入流实现,可以将数据写入内存中。ByteArrayInputStream继承了InputStream类的read()方法后,没有抛出异常。

		byte[] b=new byte[]{'a','c','b','g'};
        ByteArrayInputStream bis = new ByteArrayInputStream(b, 0, b.length);
        int temp=bis.read();
        while (temp!=-1){
            System.out.println((char)temp+"\t");
            temp=bis.read();
        }
        try{
            bis.close();//是没有任何操作的空方法
        }catch (IOException e){
            e.printStackTrace();
        }

1.ByteArrayOutputStream类–内存输出流

ByteArrayOutputStream类是将一个字节数组作为源的输出实现,可以将内存中的数据输出。

 byte[] b={'A','C','F','G','H'};
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write(b,0,b.length);
        //输出缓冲区的字节数目
        System.out.println("缓冲区的字节数组"+bos.size());
        byte[] bout=bos.toByteArray();
        for(int i=0;i<bout.length;i++){
            System.out.println((char)bout[i]+"\t");
        }

打印流

打印流解决的是OutputStream的缺陷,属于OutputStream功能的加强版。OutputStream处理的只能是字节数组;对int,double等类型的操作不方便。
打印流可以方便的将各种不同类型的数据打印输出到另一个输出流.PrintStream流可以配合不同的输出流,用来输出数据到各个目的地,如文件,数组等.
构造方法:

public PrintStream(File file)
public PrintStream(OutputStream out)
public PrintStream(OutputStream out,boolean autoFlush)

常用方法:
1.使用指定格式字符串和参数,将格式化字符串写入输出流

public PrintStream format(Locale 1,String format,Object args)

2.打印String,然后终止改行

public void print(String s)

3.使用指定格式的字符串和参数,将格式化的字符串写入此输出流

public PrintStream printf((Locale 1,String format,Object args)

4.打印该行,然后终止该行

public void pintln(String s)
 		 FileOutputStream fos=new FileOutputStream("D:\\TL-BITE\\Test\\write.txt");
        PrintStream ps = new PrintStream(fos);
        ps.println(12);
        ps.print(false);
        ps.print("nihao");
        ps.close();
      

格式化输出:

 //printf为格式化输出
        //字符串:%s
        //整数:%d
        //浮点数:%f,  %.3f表示是含三位小数位的浮点数

//在格式前添加整数代表右对齐,添加负数代表左对齐
        System.out.printf("姓名:%4s,年龄:%-2d,身高:%.3f","长得三",23,1.83);
        System.out.printf("姓名:%4s,年龄:%-2d,身高:%.3f", "张三", 28, 168.7D);
	
	 //利用String类的format方法,效果相同
        String str=String.format("姓名:%4s,年龄:%-2d,身高:%.3f", "张三", 28, 168.7D);
        System.out.println(str);

输出结果:
在这里插入图片描述

对象序列化

对象序列化是指将对象状态转化为可保持状态或传输格式(二进制流/字节序列)的过程,即将对象写入输出流;与对象序列化相反的是对象反序列化,是指由输入流将这种二进制流读入,重新恢复为原来的对象。将序列化和反序列化过程结合起来,可以轻松的进行存储和传输数据,使对象可以脱离程序的运行而独立存在。
若某个对象能支持序列化,必须让他实现Serializable接口,Serializable接口仅是一个标记接口,无任何实现方法。
可以参与序列化的成员:属性、类名
不能被序列化的内容:所有的方法、static关键字,transient关键字修饰的属性。

如果要想实现序列化与反序列化的对象操作,在java.io包中提供有两个处理类:ObjectOutputStream、 ObjectInputStream

//将需要序列化的类实现Serializable 接口,Serializable 接口没有任何实例方法
class Person implements Serializable {
    private String name;
    private int age;
    private String school;


    public Person(String name, int age, String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }

    public  void  tell() {
        System.out.println("名字" + name + "年龄" + age + "学校" + school);
    }
}

public class SerializableTest {
    public static File file = new File("D:\\TL-BITE\\Test\\print.txt");
    //序列化实例对象
    public static void serOutTest(Object obj) {
	//将序列化对象写入文件
        try (ObjectOutputStream obo = new ObjectOutputStream(new FileOutputStream(file))) {
            obo.writeObject(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //反序列化
    public static void serInTest() {
    
    //从文件中读取序列化对象
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
        //将序列化对象(Object类)强转为Person类
            Person p1=(Person)ois.readObject();
            Person对象调用Person类的普通方法
            p1.tell();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
        public static void main(String[] args) {
        //给实现序列化的方法传入对象
        serOutTest(new Person("张三", 23, "清华大学"));
        ////调用实现反序列化的方法
        serInTest();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42962924/article/details/84894050