Java基础--IO流04(IO流中的其他流,编码)

来源:互联网 发布:软件行业资质认证 编辑:程序博客网 时间:2024/05/22 05:19

操作对象的流

ObjectOutputStream

  1. 被操作的对象需要实现Serializable(标记接口),该类可以将Java对象的基本数据类型和图形写入OutputStream,可以使用ObjectInputStream读取对象,通过在流中使用文件可以实现对象的持久存储;
  2. 构造函数:ObjectOutputStream(OutputStream out);
  3. 常用方法:
    write×××(××× obj);
    ×××:基本数据类型或Object;
  4. 注意:
    write(int val)与writeInt(int val)的区别:前者仅读一个int的最低8位,后者写入一个32位的int值;

ObjectInputStream

ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化;
1. 构造函数:
ObjectInpuStream(InputStream in)
2. 常用方法:
××× read×××();×××基本数据类型或Object;
3. 注意:static修饰的成员变量不能被序列化;
4. transient关键字;对于非static修饰的成员如果不想被序列化可用该关键字修饰;

import java.io.*;class ObjectStreamDemo {    public static void main(String[] args) throws Exception{        //writeObj();        readObj();    }    public static void readObj()throws Exception{        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));        Person p = (Person)ois.readObject();        System.out.println(p);        ois.close();    }    public static void writeObj()throws IOException{        ObjectOutputStream oos =             new ObjectOutputStream(new FileOutputStream("obj.txt"));        oos.writeObject(new Person("lisi0",399,"kr"));        oos.close();    }}
import java.io.*;class Person implements Serializable{    public static final long serialVersionUID = 42L;//自定义序列号ID    private String name;    transient int age;//非静态成员如果不想被序列化,可以用关键字transient修饰;    static String country = "cn";//静态成员不能被序列化。    Person(String name,int age,String country){        this.name = name;        this.age = age;        this.country = country;    }    public String toString(){        return name+":"+age+":"+country;    }}

管道流

输入输出可以之间进行连接,通过结合线程使用;

PipedOutputStream

  1. 构造函数:
    • PipedOutputStream();可以将PipedOutputStream连接到PipedInputStream来创建通信管道。PipedOutputStream作为发送端;
    • PipedOutputStream(PipedInputStream snk);参数中需传入一个管道输入流;
    • 若是空参数的构造函数则需要通过connect()方法来获取一个管道输入流,用法:
      connect(PipedInputStream snk);

PipedInputStream

  1. 概述:管道输入流应连接到管道输出流,管道输入流提供要写入管道输出流的所有数据字节,通常数据由某个线程从PipedInpuStream对象读取,并由其他线程将其写入到相应的PipedOutputStream,若为单线程容易死锁线程;
  2. 构造函数:
    • PipedInpuStream(PipedOutputStream src);构造函数无参可用connect(PipedOutputStream src)使此管道输入流连接到管道输出流
import java.io.*;class Read implements Runnable{    private PipedInputStream in;    Read(PipedInputStream in){        this.in = in;    }    public void run(){        try{            byte[] buf = new byte[1024];            System.out.println("读取前。。没有数据阻塞");            int len = in.read(buf);            System.out.println("读到数据。。阻塞结束");            String s= new String(buf,0,len);            System.out.println(s);            in.close();        }catch (IOException e){            throw new RuntimeException("管道读取流失败");        }    }}class Write implements Runnable{    private PipedOutputStream out;    Write(PipedOutputStream out){        this.out = out;    }    public void run(){        try{            System.out.println("开始写入数据,等待6秒后。");            Thread.sleep(6000);            out.write("piped lai la".getBytes());            out.close();        }catch (Exception e){            throw new RuntimeException("管道输出流失败");        }    }}class  PipedStreamDemo{    public static void main(String[] args) throws IOException{        PipedInputStream in = new PipedInputStream();        PipedOutputStream out = new PipedOutputStream();        in.connect(out);        Read r = new Read(in);        Write w = new Write(out);        new Thread(r).start();        new Thread(w).start();    }}

RandomAccessFile

  1. 随机访问文件,自身具备读写的方法;
    通过skipBytes(int x);seek(int x);来达到随机访问;
    此类的实例支持对随机访问文件的读取和写入;
  2. 特点:

    • 该类不算是IO体系中的子类而是直接继承Object;但他是IO包中的成员,因为它具备读和写的功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置;
    • 其实完成读写的原理就是内部封装了字节输入流和输出流,通过构造函数可以看出,该类只能操作文件,而且操作文件还有模式:只读(r);读写(rw)等;
    • 如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常;
    • 如果模式为只读rw,操作的文件不存在,会自动创建,如果存在则不会覆盖;
  3. 构造方法:

    • RandomAccessFile(File file,String mode);
    • RandomAccessFile(String name,String mode);
      file-指定文件;
      name-系统文件名;
      mode-访问模式;
  4. 该类常用方法:

    • gerFilePointer();返回此文件的当前偏移量;
    • length();返回此文件的长度;
    • read();该功能与InputStream一样;
    • read×××;×××-基本数据类型;
    • readLine();读一行;
    • seek(long pos);设置指针偏移量;
    • setLength(long newLength);设置文件长度;
    • write(byte[] b)/(byte[] b,int off,int len)/(int b)该方法与OutputStream方法一样;
    • write×××(××× ~);×××基本数据类型;
    • skipBytes(int n);跳过指定的字节数;

注:该类的常用方式:通过seek()偏移指针,结合多线程实现分段数据同时读写,实际应用:迅雷下载;

class RandomAccessFileDemo {    public static void main(String[] args) throws IOException{        //writeFile_2();        //readFile();        //System.out.println(Integer.toBinaryString(258));    }    public static void readFile()throws IOException{        RandomAccessFile raf = new RandomAccessFile("ran.txt","r");         //调整对象中指针。        //raf.seek(8*1);        //跳过指定的字节数        raf.skipBytes(8);        byte[] buf = new byte[4];        raf.read(buf);        String name = new String(buf);        int age = raf.readInt();        System.out.println("name="+name);        System.out.println("age="+age);        raf.close();    }    public static void writeFile_2()throws IOException{        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");        raf.seek(8*0);        raf.write("周期".getBytes());        raf.writeInt(103);        raf.close();    }    public static void writeFile()throws IOException{        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");        raf.write("李四".getBytes());        raf.writeInt(97);        raf.write("王五".getBytes());        raf.writeInt(99);        raf.close();    }}

操作基本数据类型流

DataInputStream

  1. 构造函数:
    • DataInputStream(InputStream in)使用指定的底层输入流,创建一个DataInputStream;
  2. 常用方法:
    • read(byte[] b)/(byte[] b,int off,int len)
    • read×××();×××基本数据类型;
    • skipBytes(int n);
    • readUTF();读取一个有UTF-8修改版格式编码的字符串;
    • readUTF(DataInput in);从in中读取由writeUTF写入的数据;

DataOutputStream

  1. 构造方法:
    • DataOutputStream(OutputStream out);创建一个新的数据输出流,将数据写入指定基础输出流;
  2. 常用方法:
    • write(byte[] b,int off,int len);
    • write(int b);
    • write×××(×××~);×××-基本数据类型;
    • writeChars(String s);将字符串按字符顺序写入基础输出流;
    • flush();
    • size();返回到目前为止写入此数据输出流的字节数;
    • writeUTF(String str);以与机器无关方式使UTF-8修改版编码将一个字符串写入基础输出流。

注:writeUTF();写的数据,只能用readUTF()方法读;
注:写入的不同的类型的数据时,读取也要按该顺序读取,否则会出现乱码,因为不同的数据类型的长度不同;

import java.io.*;class DataStreamDemo {    public static void main(String[] args) throws IOException{        //writeData();        //readData();        //writeUTFDemo();//      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");//      osw.write("你好");//      osw.close();//      readUTFDemo();    }    public static void readUTFDemo()throws IOException{        DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));        String s = dis.readUTF();        System.out.println(s);        dis.close();    }    public static void writeUTFDemo()throws IOException{        DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));        dos.writeUTF("你好");        dos.close();    }    public static void readData()throws IOException{        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));        int num = dis.readInt();        boolean b = dis.readBoolean();        double d = dis.readDouble();        System.out.println("num="+num);        System.out.println("b="+b);        System.out.println("d="+d);        dis.close();    }    public static void writeData()throws IOException{        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));        dos.writeInt(234);        dos.writeBoolean(true);        dos.writeDouble(9887.543);        dos.close();        ObjectOutputStream oos = null;        oos.writeObject(new O());       }}

操作字节数组

ByteArrayInputStream

  1. 构造函数:
    • ByteArrayInputStream(byte[] buf);
    • ByteArrayInputStream(byte[] buf,int offset,int length);创建ByteArrayInputStream,使用buf作为其缓冲区数组;
  2. 常用方法:
    • available();返回可从输入流读取的剩余字节数;
    • read();
    • read(byte[] b,int off,int len);

ByteArrayOutputStream

  1. 构造函数:
    • ByteArrayOutputStream();创建一个新的byte数组输出流;
    • ByteArrayOutputStream(int size);创建一个新的byte数组输出流,它具有指定大小的缓冲区容量(内部封装缓冲数组);
  2. 常用方法:
    • size();返回缓冲区的当前大小;
    • toByteArray();创建一个新分配的byte数组;
    • toString();使用平台默认字符集,将缓冲区内容转换为字符串;
    • write(int b);
    • write(byte[] b,int off,int len);
    • writeTo(OutputStream out);将此byte数组输出流的全部内容写入到指定的输出流参数中;
import java.io.*;class ByteArrayStream {    public static void main(String[] args) {        //数据源。        ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());        //数据目的        ByteArrayOutputStream bos = new ByteArrayOutputStream();        int by = 0;        while((by=bis.read())!=-1){            bos.write(by);        }        System.out.println(bos.size());        System.out.println(bos.toString());    //  bos.writeTo(new FileOutputStream("a.txt"));    }}

操作字符数组

如果操作的数据都是字符则使用字符数组的流;该流使用方式与操作字节数组一样;

CharArrayReader

  1. 构造函数:
    • CharArrayReader(char[] buf);
    • CharArrayReader(char[] buf,int offset,int length);
  2. 常用方法:
    • read();读取单个字符;
    • read(char[] b,int off,int len);将字符读入数组的某一部分;

CharArrayWriter

  1. 构造函数:
    • CharArrayWriter();创建一个新的CharArrayWriter;
    • CharArrayWriter(int initialSize);创建一个指定大小的CharArrayWriter;
  2. 常用方法:
    • append(char c);将指定字符添加到此writer;
    • flush();刷新流到缓冲区;
    • size();返回缓冲区的当前大小;
    • toCharArray();返回输入数据的副本;
    • toString();将输入数据转换为你字符串;
    • write(char[] c,int off,int len);将字符写入缓冲区;
    • write(int c);将一个字符写入缓冲区;
    • write(String str,int off,int len);将字符串某一部分写入缓冲区;
    • writeTo(Write out);将缓冲区的内容写入另一个字符流;

操作字符串

StringReader

  1. 构造函数:
    • StringReader(String s);其源为一个字符串的字符流,创建一个新字符串,reader;
  2. 常用方法:
    • read();读取单个字符;
    • read(char[] cbuf,int off,int len);将字符读入数组的某一个部分;

StringWrite

  1. 构造函数:

    • StringWrite();使用默认初始化字符串缓冲区大小创建一个新的字符串writer;
    • StringWrite(int initialSize);使用指定初始字符串缓冲区大小创建一个新字符串 writer;
  2. 常用方法:

    • append(char c)/(CharSequence csq);将指定字符(或字符序列)添加到此 writer
    • flush();刷新该流的缓冲;
    • getBuffer();返回该字符串缓冲区本身;
    • toString();以字符串的形式返回该缓冲区的当前值;
    • write(char[] cbuf,int off,int len);写入字符数组的某一部分;
    • write(int c);写入单个字符;
    • write(String str);写入一个字符串;
    • write(String str,int off,int len);写入字符串的某一部分;

编码表

  1. 可以指定编码的流:转换流,打印流;
  2. 最常用:
    • InputStreamReader
    • OutputStreamWriter
  3. 只能打印,不能读取:
    • PrintStream
    • PrintWriter

常见编码表

  1. ASCII:美国标准信息交换码,用一个字节的7位可以表示;
  2. ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示;
  3. GB2312:中文编码表;
  4. GBK:中文编码表升级;
  5. Unicode:国际标准码;
  6. UTF-8:最多三个字节表示一个字符;

编码

字符串变成字符数组
String——byte[]:str.getBytes(String charsetName);字符串String方法;charsetName-指定编码表的字符串名称;

解码

byte[]——String:new String(byte[],charsetName);
注:如果中文字符串用“GBK”编码,用“ISO8859-1”解码,会出现乱码(因为不识别),将解码后的乱码再用“ISO8859-1”编码回去,则与“GBK”编码相同(因为不识别,编码未被改变,再用“GBK”解码,则结果为原中文字符串,如果该字符用“UTF-8”去解码,再编码,则编码将发生变化与原“GBK”编码不同,用“GBK”去解码时,结果不是原中文字符串,因为“UTF-8”页识别中文,用“UTF-8”解码再编码后,将按照“UTF-8”编码表中的字符对原解出的乱码进行编码,则结果发生变化,所以只有不识别中文的编码表才能进行解码再编码后,结果不变);
这里写图片描述

import java.util.*;class  EncodeDemo{    public static void main(String[] args)throws Exception {        String s = "哈哈";        byte[] b1 = s.getBytes("GBK");        System.out.println(Arrays.toString(b1));        String s1 = new String(b1,"utf-8");        System.out.println("s1="+s1);        //对s1进行iso8859-1编码。        byte[] b2 = s1.getBytes("utf-8");        System.out.println(Arrays.toString(b2));        String s2 = new String(b2,"gbk");        System.out.println("s2="+s2);    }}import java.io.*;class EncodeStream {    public static void main(String[] args) throws IOException {            //writeText();            readText();    }    public static void readText()throws IOException {        InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");        char[] buf = new char[10];        int len = isr.read(buf);        String str = new String(buf,0,len);        System.out.println(str);        isr.close();    }    public static void writeText()throws IOException {        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");        osw.write("你好");        osw.close();    }}
0 0
原创粉丝点击