• 文件(2)--IO流


    IO


    输入流和输出流

    Java中的IO流根据功能划分为:输入流和输出流。输入流:用于读取数据。输出流:用于写出数据。输入输出的参照方向是根据我们的程序的。

    字节流和字符流

    Java中的IO流根据处理的单位划分为:字节流和字符流。字节流:以字节为单位读写数据。字符流:以字符为单位读写数据。

    高级流和低级流

    Java中的IO流还分为:高级流和低级流。高级流:不能独立存在,必须基于另一个流工作。低级流:数据有明确的来源或者去向

    字节流和字符流


    字节流

    InputStream:抽象类,是所有字节输入流的父类。

    OutputStream:抽象类,是所有字节输出流的父类。

    字符流

    Reader与Writer 带有缓冲区。

    Reader:抽象类,所有字符输入流的父类,不能实例化

    Writer:抽象类,所有字符输出流的父类,不能实例化

    字符流处理单位为字符:一次处理一个字符unicode。字符流本质上还是读写字节。

    FISFOS


    用于读写文件的流。FileInputStream:文件字节输入流,是低级流。FileOutputStream:文件字节输出流,是低级流。

    FileOutputStream

    构造器:

    FileOutputStream(String name) 根据文件名创建用于写该文件的输出流。

    FileOutputStream(File file)

    FileOutputStream(File file, boolean append) append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处。

    如果文件不存在,会自动创建该文件。

    方法:

    void write(int   d)写一个字节,写给定的int值的”低八位”

    void write(byte[] d)将给定的字节数组中的所有字节一次性写出

    void write(byte[] d, int start,int len)从下标start开始,写len个字节。

    FileOutputStream

    构造器:

    FileOutputStream(File file)

    FileOutputStream(String name)当前目录是相对于根目录下的

    FileOutputStream(String name, boolean append)

    方法:

    int read() 读取1个字节,8位

    int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入 b 中

    int read(byte[] b, int off, int len)

    从输入流中将最多 len 个字节的数据读入一个 byte 数组中。从off处开始放

    long skip(long n) 从输入流中跳过并丢弃 n 个字节的数据。

    public class TestFile {
        public static void main(String[] args) throws Exception {
            OutputStream out = null;
            try{
                out = new FileOutputStream("test.txt");
                out.write(1);
                out.write('A');
                byte[] bytes = "大家好".getBytes("utf-8");
                out.write(bytes.length);
                out.write(bytes);
            }
            catch(Exception e){
            }
            finally{
                if(out != null){
                    try{
                        out.close();
                    }
                    catch(IOException e){
                    }
                }
            }
        }
    }

    public class TestFile {
        public static void main(String[] args) throws Exception {
            InputStream in = null;
            try{
                in = new FileInputStream("test.txt");
                System.out.println(in.read());// 1
                System.out.println((char)in.read());// 'A'
                int len = in.read();
                byte[] bytes = new byte[len];
                in.read(bytes);
                String str = new String(bytes, "utf-8");
                System.out.println(str);
            }
            catch(Exception e){
            }
            finally{
                if(in != null){
                    try{
                        in.close();
                    }
                    catch(IOException e){
                    }
                }
            }
        }
    }

    复制文件

    public class TestFile {
        public static void main(String[] args) throws Exception {
            FileInputStream fis = new FileInputStream("E:\代码整体规范.pptx");
            FileOutputStream fos = new FileOutputStream("E:\代码整体规范222.pptx");
            byte[] buffer = new byte[1024 * 10];// 10k
            int len = -1;
            while((len = fis.read(buffer)) != -1){
                fos.write(buffer, 0, len);
            }
            fis.close();
            fos.close();
        }
    }

    BISBOS


    BufferedInputStream:缓冲字节输入流

    BufferedOutputStream:缓冲字节输出流

    缓冲流的功能:内部维护一个缓冲区,用于减少读写次数,提高读写效率。

    BufferedOutputStream

    原理:BufferedOutputStream内部有一个缓冲区,大小8192k,每次调用write方法的时候,它首先把数据放入缓冲区中,等缓冲区存满后,调用方法out.write(buf,0,count)把缓冲区中的内容写出。这样提高的写的效率,不是一个字节一个字节的写。

    构造器:

    BufferedOutputStream(OutputStream out) 

    BufferedOutputStream(OutputStream out, int size) size:指定缓冲区大小

    方法:

    void flush() 刷新此缓冲的输出流。

    void write(byte[] b, int off, int len)

    void write(int b) 

       BufferedInputStream

    原理:

    BufferedInputStream内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快,所以BufferedInputStream的效率很高!

    构造器:

    BufferedInputStream(InputStream in)

    BufferedInputStream(InputStream in, int size) size指的是缓冲区大小

    方法:

    read()

    int read(byte[] b, int off, int len)

    复制文件

    public class TestFile {
        public static void main(String[] args) throws Exception {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.zip"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b"));
            int d = -1;
            // bis和bos内部都维护了一个缓冲数组,(8192)
            while((d = bis.read()) != -1){// read方法一次性读取多个字节放入缓冲区中
                bos.write(d);// 把读到的字节放入缓冲数组中,数组装满了,再一次性写出
            }
            bis.close();
            bos.close();
        }
    }

    flush方法

    public class TestFile {
        public static void main(String[] args) throws Exception {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
            bos.write("大家好".getBytes("utf-8"));
            // 没有真正写出,而是放入缓冲区中.等缓冲区满了才写出
            bos.flush();// 把缓冲数组中的数据全部写出。
            bos.close();// 先调用flush()方法后再关闭。所以最后一定要关闭,否则可能会丢数据
            // 一般有缓冲区的flush方法有效,没有缓冲区的flush方法没有任何作用
        }
    }

    DISDOS


    方便读写基本数据类型,但是效率不高,和RandomaccessFile的功能相似。

    DataInputStream:可以方便的读取基本类型数据

    DataOutputStream:可以方便的写出基本类型数据

    DataOutputStream

    构造器:DataOutputStream(OutputStream out),传入低级流,如FileOutputStream

    方法:

      size()   返回即到目前为止写入此数据输出流的字节数。

      void write(byte[] b, int off, int len)

      void write(int b) 将指定字节(参数 b 的八个低位)写入基础输出流。

      void writeBoolean(boolean v)

      void writeChar(int v)

      void writeDouble(double v)

      void writeFloat(float v)

      void writeInt(int v)

      void writeLong(long v)

      void writeShort(int v)

      void writeUTF(String str)

       DataInputStream

    构造器:

    DataInputStream(InputStream in) ,传入低级流,如FileInputStream

    方法:

     int read(byte[] b)

     int read(byte[] b, int off, int len) 

     boolean readBoolean()

     char readChar()

     double readDouble()

     float readFloat()

     int readInt()

     long readLong()

     short readShort()

     String readUTF()

     int skipBytes(int n)

    DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
    dos.writeInt(1000);
    dos.writeLong(34l);
    dos.writeDouble(2.34);
    dos.writeUTF("你好");
    dos.close();

    DataInputStream dis=new DataInputStream(new FileInputStream("dos.txt"));
    System.out.println(dis.readInt());
    System.out.println(dis.readLong());
    System.out.println(dis.readDouble());
    System.out.println(dis.readUTF());
    dis.close();

    高级流的组合使用

    我们既要可以方便的写出基本数据类型,又要写的效率高,那么我们可以联合使用DOS、BOS

    FileOutputStream fos = new FileOutputStream("a.txt");
    // 首先,为了提高些效率,包装为缓冲流。
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    // 为了方便的写出基本类型数据,包转为DOS
    DataOutputStream dos = new DataOutputStream(bos);
    // dos既可以方便的写出基本类型数据,又提高了效率
    dos.writeInt(1234);
    dos.close();

    ISROSW


    InputStreamReader: 字符输入流  OutputStreamWriter:字符输出流

    OutputStreamWriter

    构造器:

    OutputStreamWriter(OutputStream out) ,使用默认字符编码,平台默认的编码 window默认是gbk,liunx默认是utf-8

    OutputStreamWriter(OutputStream out, String charsetName) 使用指定字符编码 

    方法:

    void  write(int c)               写入单个字符,即c的低16位

    void  write(char[] cbuf)             一次性将给定的字符数组中的所有字符写出

    void  write(char[] cbuf, int off, int len) 从start处开始连续将len字符写出

    void  write(String str)

    void  write(String str, int off, int len) 写入字符串的某一部分。   

    String getEncoding()            返回此流使用的字符编码的名称。

    InputStreamReader

    构造器:

    InputStreamReader(InputStream in)

    InputStreamReader(InputStream in, String charsetName)

    方法:

    String getEncoding()   返回此流使用的字符编码的名称。

    int read()     读取单个字符。以int值形式返回,该int值”低16位”有效。如果是utf-8编码方案,会一个一个匹配,先读一个字符如果是英文字符,进行编码。不是英文字符则再读一个字符,中文字符占3个字符, 会一次性读取3个字符,把它按照utf-8解码成字符,再以unicode编码存在char中。

    int read(char[] c)  一次最多尝试读取给定数组的length个字符,并存入数组返回值为实际读取到的字符

    int read(char[] cbuf, int offset, int length)

    OutputStreamWriter osw=new OutputStreamWriter(System.out);//写到控制台
    osw.write(123);
    osw.write(new char[]{'A','B'});
    osw.write("大家好!");
    System.out.println(osw.getEncoding());
    osw.close();

    InputStreamReader reader=new InputStreamReader(new FileInputStream("b.txt"));
    int c=-1;
    while((c=reader.read())!=-1){
           char chs=(char)c;
           System.out.print(chs);
    }
    reader.close();

    从控制台读

    InputStreamReader reader=new InputStreamReader(System.in);
    char[] chs=new char[3];
    reader.read(chs);//阻塞方法,如果控制台没有数据会等待控制台输入
    System.out.println(Arrays.toString(chs));
    reader.close();

    复制”文本文件”

    只能复制文本文件,不是什么文件都能复制的

    InputStreamReader reader=new InputStreamReader(new FileInputStream("src"+File.separator+"demo"+File.separator+"Demo01.java"));
    OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("E:\a.java"));
    char[] chs=new char[1024*10];
    int len=-1;
    while((len=reader.read(chs))!=-1){
        writer.write(chs, 0, len);
    }
    reader.close();
    writer.close();

    BRBW


    BufferedReader:缓冲字符输入流

    BufferedWriter:缓冲字符输出流

    可以实现按行读取。

    BufferedWriter

    构造器:

    BufferedWriter(Writer out) 传入一个字符流

    BufferedWriter(Writer out, int size)传入一个字符流,size指的是缓冲区大小

    方法:

     void flush()

     void newLine() 写入一个行分隔符。

     void write(int c) 写入单个字符。

     void write(char[] chs)

     void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。

     void write(String str)

     void write(String s, int off, int len) 写入字符串的某一部分。

    BufferedReader

    构造器:

    BufferedReader(Reader in)

    BufferedReader(Reader in, int sz)

    方法:

     int read() 读取单个字符。

     int read(char[] chs)

     int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。

     String readLine() 读取一个文本行。

    案例

    BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8"));
    writer.write("你好!");
    writer.newLine();
    writer.write("你好!");
    writer.newLine();
    writer.close();

    BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
    String str=null;
    while((str=reader.readLine())!=null){
        System.out.println(str);
    }
    reader.close();

    或者

    BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
    char[] chs=new char[5];
    int len=-1;
    while((len=reader.read(chs))!=-1){
        System.out.print(new String(chs));
    }
    reader.close();

    复制文件

    BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("src/demo/Demo01.java"),"gbk"));
    BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\a.java"),"gbk"));
    String line=null;
    while((line=reader.readLine())!=null){
        writer.write(line);
        writer.newLine();
    }
    reader.close();
    writer.close();

    读取控制台中的数据,复制到文本文件中

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")));
    String str=null;
    while(true){
        str=reader.readLine();
        if(str!=null&&str.equals("bye")){
            break;
        }
        writer.write(str);
        writer.newLine();
    }
    reader.close();
    writer.close();

    FileWriterFileReader


    可以直接读写文本文件的字符流。比较方便。但是使用FileWriter和FileReader就默认使用了当前系统默认的字符集进行读写。不能自己设置字符集,所以用的不是太多。

    FileWriter extends OutputStreamWriter

    构造器:

    FileWriter(File file)

    FileWriter(File file, boolean append)

    FileWriter(String fileName)

    FileWriter(String fileName, boolean append)

    构造方法实现

    public FileWriter(String fileName) throws IOException {
        super(new FileOutputStream(fileName));
    }
    //即new FileWriter(“a.txt”)完全相当于new OutputStreamWriter(new FileOutputStream(a.txt))

    方法:全部继承于OutputStreamWriter。

    FileReader extends InputStreamReader

    构造器:

    FileReader(File file)

    FileReader(String fileName)

    public FileReader(String fileName) throws FileNotFoundException {
        super(new FileInputStream(fileName));
    }
    //即new FileReader(“a.txt”)完全相当于new InputStreamReader(new FileInputSteam(“a.txt”))

    方法:全部继承于InputStreamReader

    FileWriter writer=new FileWriter("a.txt");
    writer.write("你好");
    //变成缓冲字符流
    BufferedWriter br=new BufferedWriter(writer);
    br.write("%%%");
    br.close();

    FileReader reader=new FileReader("a.txt");
    int c=-1;
    while((c=reader.read())!=-1){
        System.out.println((char)c);
    }
    reader.close();

    PrintWriter


    缓冲字符输出流。在写文件时,可以指定字符集,比较方便。

    构造器:

    PrintWriter(File file)                          

    PrintWriter(File file, String charset)    

    PrintWriter(String fileName)

    PrintWriter(String fileName, String charset)

    PrintWriter(OutputStream out)           

    PrintWriter(OutputStream out, boolean autoFlush) 自动刷新

    创建带有自动刷新的缓冲字符输出流,每当调用"pringln()"注意是带有ln方法。就会在写操作后自动调用flush()方法,即自动刷新

    PrintWriter(Writer out)

    PrintWriter(Writer out, boolean autoFlush)

    //该构造器既能指定字符集也能指定自动刷新

    方法:

    void print();输出,不带换行符,和System.out.print()差不多

    void println() 带换行符

    void write(char[] buf)

    void write(char[] buf, int off, int len)

    void write(int c)

    void write(String s)

    void write(String s, int off, int len)

    案例

    PrintWriter pw=new PrintWriter("p.txt","utf-8");
    pw.println(true);
    pw.println(1234567);
    pw.println("你好!");
    //注意,写入文件中的是字符串,true,1234567,你好
    pw.close();

    Serializable接口


    public interface Serializable类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。

    序列化接口没有方法或字段,仅用于标识可序列化的语义。

    transient关键字

    transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象呗串行化的时候,transient型的便利的值不包括再串行化的表示中,然而非transient型的变量是被包括进去的。

    Transient修饰的属性可以通过其它手段进行序列化,可以参考ArrayList源码,ArrayList中底层数组是用transient修饰,但是进行了序列化。因为重写了readObject和writeObject方法。

    OOSOIS


    将Object对象转换为byte序列,就是序列化,反之叫反序列化。

    ObjectOutputStream:对象输出流

    ObjectInputStream:对象输入流

    ObjectOutputStream

    构造器:ObjectOutputStream(OutputStream out)

    方法:void writeObject(Object obj) 线程安全的方法

    ObjectInputStream

    构造器:ObjectInputStream(InputStream in) 

    方法:readObject()   线程安全的方法

    public class Person implements Serializable {
        private String name;
        private int age;
        private int sex;
        private transient String info;
        private List<String> otherInfo;     
        //...get/set方法 equals方法 hashcode方法
    }

    读写

    public class Test {
        public static void main(String[] args) throws Exception {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("a.txt"));
            List<String> list = new ArrayList<String>();
            list.add("一");
            list.add("二");
            list.add("三");
            Person p = new Person("zhansgan", 22, 1, "男", list);
            // 将p的name、age、sex、otherInfo值转换成二进制写入文件
            // 比如name=zhangsan, 取’z’二进制为:1111010写入只有在写字符串时才有编码格式问题
            out.writeObject(p);
            out.close();
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("a.txt"));
            Person p1 = (Person)in.readObject();
            System.out.println(p1);// info值是null,没有被序列化
            System.out.println(p1.equals(p));
            in.close();
        }
    }
  • 相关阅读:
    进程间通信的方式——信号、管道、消息队列、共享内存
    exit()与_exit()的区别(转)
    [Google Codejam] Round 1A 2016
    使用shell脚本自定义实现选择登录ssh
    PHP的反射机制【转载】
    PHP set_error_handler()函数的使用【转载】
    PHP错误异常处理详解【转载】
    php的memcache和memcached扩展区别【转载】
    .htaccess重写URL讲解
    PHP数据库扩展mysqli的函数试题
  • 原文地址:https://www.cnblogs.com/qin-derella/p/6647285.html
Copyright © 2020-2023  润新知