导航

Java IO流

Posted on 2017-08-07 18:37  耍流氓的兔兔  阅读(159)  评论(0编辑  收藏  举报
IO流
  处理设备之间的数据传输
  按照方向分:输入流,输出流(相对于内存)
  按照操作的数据分:字节流,字符流
  按照角色分:节点流,处理流

  字节流:
    可以处理任何类型的数据,音频,视频,图片,文本
    编码:ASCII,ISO8859-1(欧洲编码),GBK,UTF-8
    以Stream结尾
    字节输入流父类:InputStream
    字节输出流父类:OutputStream
  字符流:
    基于字节流,在字节流的基础上融入了编码
    专门处理文本的
    字符输入流父类:Reader
    字符输出流父类:Writer
    根据设备选取对应的子类
  节点流:    
    向一个特定的IO设备读写数据的流     
    程序直接连接到实际的程序源,和实际的输入输出节点连接
  
  处理流:     
    对一个已存在的流进行连接或封装,通过封装后的流来实现读写功能
 

Writer:

  1 创建文件输出流对象,并绑定文件
    文件不存在会自动创建
    文件存在会被覆盖
  2 使用文件输出流对象向文件写入数据
    write()
     此时没有写入到文件,写入到流中,流内部有一个字节数组,因为要查表
    flush()把流中的数据刷到文件中
      刷完之后可以继续写入
  3 关闭输入流,同时会刷新流中的数据到文件中
    close()

  文件续写:
 
    FileWriter(fileName, isAppend)//是否在fileName中追加数据     System.getProperty("line.separator");//获得系统换行的关键词

Reader:  

   1 创建文件输入流对象,并绑定文件
    被读取的文件必须事先存在
  2 读取
    read()读取单个字符
      一次读一个,返回字符编码
      读到文件末尾,返回-1
  3 关流
  文件复制:
    读取被复制的文件     把读出来的数据写入到一个新的文件

缓冲流:

缓冲流:
  缓冲流不具备读或写的功能
  只是提高了数据读或写效率
  使用缓冲流必须结合读流或写流
  将被提高效率的写入流对象作为参数传递给缓冲流的构造方法

BufferedWriter:
  
write():写入到缓冲流的内部缓冲区 newLine():添加一个行分隔符,跨平台的写入换行的功能 BufferedReader:   readLine():一次读取一行   不包含最后的换行符 String line = null; while((line = br.readLine()) != null) {   System.out.println(line); }

装饰设计模式:

基于已经存在的功能提供增强功能
解决某一类问题最便捷的方式

装饰设计模式的好处:
  1 简化了原有体系
  2 装饰类还属于原体系
  eg: 
    BufferedReader
    LineNumberReader
FileWriter:    writer()
FileReader:    int read()    int read(char[])

BufferedWriter:    newLine()
BufferedReader:    readLine()

InputStream:

getBytes():编码
available():返回文件总大小
  文件小时创建的数组和文件大小相同,可以只读一次,不需要循环
  文件过大时不适合

FileInputStream fis = new FileInputStream("ss.txt");
//创建一个长度为1024的容器
byte[] arr = new byte[fis.available()];
//实际读取的字节数
int num = 0;
while((num = fis.read(arr)) != -1)
{
  System.out.print(new String(arr, 0, num));
}    

OutputStream:

System.in:标准的输入
InputStream in = System.in;
  和键盘设备关联在一起的字节输入流对象
int num = in.read();//阻塞式方法 System.out:标准的输出

转换流:

指定编码
  InputStreamReader:将字节流转成字符流
  OutputStreamWriter:

System.setIn():改变标准的输入
System.setOut():改变标准的输出

File:

把文件或文件夹封装成对象的方式

文件过滤器:

FilenameFilter接口:
  重写accept(File dir, String name)方法
  对指定的dir进行迭代

Properties:

是一个map集合
存储的是属性
属性名和属性值必须都是字符串类型
所以没有使用泛型

可以和流使用的集合

Properties pro = System.getProperties();

//System.out.prinln(p);

pro.list(System.out);

打印流:

字节打印流:printStream
  可以使用OutputStream的功能,增加了打印功能
  可以操作的目的:
    字符串类型的文件名
    File类型的文件
    字节输出流

字符打印流:printWriter
  可以使用Writer的基本功能,增加了打印功能
  可以操作的目的:
    字符串类型的文件名
    File类型的文件
    字节输出流(可以自动刷新)
    字符输出流(可以自动刷新)

合并流:(序列流)

SequenceInputStream 

序列化和反序列化:(对象流)

序列化:存储对象
  ObjectOutputStream:
  标记接口:Serializable
    实现该接口无需实现任何方法,它只是表明该类的实例是可序列化的
  序列化的时候同时生成一个serialVersionUID来标记进行序列化的类
反序列化:读取对象
  ObjectInputStream:
  ClassNotFoundException异常:
    找不到序列化对象的类
  InvalisClassException异常:
    即类的serialVersionUID不同
    建议自己声明serialVersionUID

transient:瞬态
修饰的成员不参与序列化

如果文件中有若干个对象,使用对象读取流ois.readObject()时如何判读到结尾?
  

  1.将若干对象装入一个容器,然后将容器送入一个对象写入即可,读取时,只要读取一个对象即可
 
  2.可以直接使用EOFException来判断结束
    public static void main(String[] args) throws IOException, ClassNotFoundException
    {
        CompareByAge com = new CompareByAge(); 
        
        TreeSet<Person> set = new TreeSet<>(com);
        
        set.add(new Person("张三",90));
        set.add(new Person("李四",19));
        set.add(new Person("王五",93));
        set.add(new Person("赵六",92));
        set.add(new Person("分期",19));
        
        Iterator<Person> ite = set.iterator();
        while(ite.hasNext())
        {
            System.out.println(ite.next());
        }
        
        writeToFile(set);
    }

 

    public static void writeToFile(TreeSet<Person> set) throws IOException, ClassNotFoundException
    {
        //使用对象流将集合写入test.txt文件中
        FileOutputStream fos = new FileOutputStream(new File("D:\\Test\\test.txt"));
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        
        Iterator<Person> ite = set.iterator();
        while(ite.hasNext())
        {    
            oos.writeObject(ite.next());
        }
        oos.close();
        
        FileInputStream fis = new FileInputStream(new File("D:\\Test\\test.txt"));
        ObjectInputStream ois = new ObjectInputStream(fis);
        
        try{
            while(true)
            {
                Person person = (Person)ois.readObject();
                System.out.println("******:"+person);
            }
        }catch(EOFException e)
        {
            //已从流中读完
        }finally
        {
            ois.close();
        }        
    }

 

RandomAccessFile:

随机访问文件
  不属于io体系,只能访问文件
  内部既有字节输入流,也有字节输出流(既可以读也可以写)
  内部有一个字节数组,使用指针操作该数组,从而实现的随机访问

数据流:

操作基本数据类型:
  DataOutputStream:
  DataInputStream:

内存流:

ByteArrayOutputStream:
  向内存中写
ByteAarrayInputStream:
  从内存中读
  内存流不需要close()

编码和解码:

编码:
byte[] getBytes():
  使用平台的默认字符集将此String编码为byte序列,并将结果存入一个新的byte数组中
byte[] getBytes(CharSet chaeser):
  使用给定的charset将此String编码到byte序列,并将结果存储到新的byte数组中

解码:
String(byte[] bytes):
  通过平台的默认字符集解码指定的byte数组,构造一个新的String
String(byte[] bytes, Charset charset):
  通过指定的charset解码指定的byte数组,构造一个新的String

编码编对了,解码肯定能解对
编码编错了,不能解对了