IO流

来源:互联网 发布:藏刀不能在淘宝卖 编辑:程序博客网 时间:2024/05/01 09:29
预习:
IO流(input,output,输入输出流):
IO流用来处理设备之间的数据传输
输入输出相对于设备而言    内存------------->写出 硬盘   内存  读入<----------硬盘
将外围设备中的数据读取到内存中:输入
将内存的数据写入到外围设备中:输出
流按操作数据分为两种:字节流和字符流
字符流的由来:
其实就是:字节流读取文字字节数据后,不直接操作而是先查看指定的编码表。获取对应的文字,再对这个文字进行操作。简单说:字节流+编码表
字节流的两个顶层父类:
1、InputStream  2、OutputStream
字符流的另两个顶层父类:(操作文字数据,优先考虑字符流)
1、Reader  2、Writer


FileWriter   fw =new  FileWriter(" demo.txt");如果文件不存在,则会自动创建,如果文件存在,则会被覆盖
fw.write( " adadd");其实数据写入到了临时缓冲区中
fw.flush();//进行刷新,将数据直接写到目的地中
细节问题:
  1、windows中的换行是\r\n  也可以直接调用系统的:System.getProperty("line.separator");
  2、***如果构造函数中加入true可以实现对文件进行续写FileWriter
---------------------------------------------------------------------------------------


1、java.io.file代表文件或文件夹
   pathSeparator,pathSeparatorChar:分号
   separator,separatorChar
               windows:反斜杠\\,还可以使用/
               linux:/
   例如:c:\\eclipse\\notic.html
   为了实现跨平台,路径分隔符可以使用pathSeparator
   常用方法:
   getAbsolutePath();//获得绝对路径        exists();//判断文件或文件夹是否存在
   getName();//获得文件或目录的名称        isFile(); isDirectory();//判断是否为文件或文件夹
   mkdir();mkdirs();先判断文件夹是否存在,不存在创建   createNewFile();
   使用list();listFiles();遍历文件夹下的文件
   第一种给list();listFiles();加过滤器的方式:定义一个过滤器去实现FilenameFilter接口
   第二种给list();listFiles();加过滤器的方式:定义一个过滤器去实现FileFilter接口
   注意:调用list方法的file对象封装的必须是文件夹名,而不能是文件名
   练习:使用递归算法遍历某个文件夹下的内容
2、流的分类
a:流向:以程序为基准
   输入流:从文件到程序,程序读取文件
   输出流:从程序到文件,程序写文件
b:按数据传输的单位
   字节流:
   字符流:
c:功能:
   节点流:直接连接数据源和程序
   处理流:套接在其他流之上,可以获得更强大的功能
3、四个抽象类
字节流
字符流
4、FileInputStream:文件字节输入流
   read():读取下一个字节,如果到达文件末尾,返回值为-1,定义一个变量来接收读取到的值
   read(byte[]b):读取最多b.length个字节,返回值为读取到的数的末尾,如果读到文件的末尾返回值为   -1。将读取到的值写入了byte数组中,定义一个变量来接收数组中数据的个数
   read是阻塞式方法,如果没有数据会一直等
   FileOutputStream:文件字节输出流
   write(byte b):写一个字节
   write(byte[]b):写一个byte数组
   write(byte[] b,off,len):写byte数组一部分


5、FileReader:文件字符输入流
   FileWriter:文件字符输出流
   write:将数据写入内存缓冲区,并不是直接写入文件
   解决办法:
   a:flush:刷新缓冲区,将缓冲区的数据写入文件
   b:close:关闭连接之前先刷新缓冲区,将数据写入到文件中
6、标准输入输出流,执行控制台(这个对象对于系统而言就一个,所以流不能关,关了就用不了了。随着系统的消失而消失,随着系统的出现而出现)
System.in
        返回值为InputStream  InputStream is=System.in;//相当于程序和控制台连接
        System.setIn(InputStream);重置标准输入流
System.out
        返回值为PrintStream ,所有打印的方法都在该类中
        System.setOut(PrintStream对象)重置标准输出流,指向文件
windows下,每行结尾是\r(回车,13)\n(换行,10)   mac:\n   linux:\r


预习:
缓冲区:
为了提高效率。使用了缓冲区 
关闭缓冲区,其实关闭的就是被缓冲的流对象
换行:System.getProperty("line.separator");
根据回车符来判断到底有几行
字符流缓冲区特有方法:BufferedWriter:newLine();   BufferedReader:readLine();
readLine()的原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲(这个容器可以是StringBuilder,因为StringBuilder的长度是可变的并且最终返回的是字符串)并判断换行标记。将标记前的缓存数据变成字符串返回
缓冲原理:
其实就是从源中获取一批数据装进缓冲区中,在从缓冲区中不断的取出一个个的数据


缓冲区中无非就是封装了一个数组,并对外提供了更多的方法对数组进行访问,其实这些方法操作的都是数组的角标
*****装饰设计模式:动态的给对象添加一些功能
     对一组对象的功能进行增强时,就可以使用该模式进行问题的解决(一个类的出现为了增强另        一个类的功能而出现)
     装饰和继承都能实现一样特点:进行功能的扩展增强。那么有什么区别?
     只为提高功能进行的继承,导致继承体系越来越臃肿。不够灵活
     装饰比继承灵活。
     特点:装饰类和被装饰类都必须所属同一个接口或者父类
     另:装饰类:LineNumberReader提供了getLineNumber();和setLineNumber();


--------------------------------------------------------------------------------------------------------------------------------------------------
1、转换流
          InputStreamReader:将字节流转换成字符流,是字节流通向字符流的桥梁
          OutPutStreamWriter:将字符流转换成字节流
2、数据流
         DataInputStream
                      -------readDouble  readInt   readBoolean  readUTF
         DataOutputStream
                      --------writeUTF(" ");写字符串
         注意:读取顺序要一致
3、缓冲流
      BufferedInputStream
      BufferedOutputStream
      默认缓冲区大小8K
      常用于读写图片等非文本文件


      BufferedReader
              ------------ readLine 读取一行文本 不包含行终止符。到达文件末尾返回null
     BufferedWriter
               ------------新增行分隔符,换行,回车
=========================================================================================


扩展:(1)生成【m,n】之间的随机数(int)(Math.random()*(n-m+1)+m)
      (2)Random r=new Random(); r.nextInt(n-m+1)+m;
       Math.random( );生成的是[0,1)之间的数


=========================================================================================
1、内存流
   ByteArrayInputStream
        指向内存中的byte数组
   ByteArrayOutputStream 
         baos.toByteArray();创建一个新数组,复制原数组的数据
2、对象流:读取引用型数据
   也可以读写基本数据类型是因为基本数据类型进行了自动的装箱
   ObjectInputStream :对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化
   ObjectOutputStream :对对象进行序列化
java.io.Serializable,只是一个标记接口,实现该接口的类,可以进行序列化(将对象保存到存储介质上)和反序列化(从存储介质上读取对象)
如果读写的是对象,就要实现Serializable接口


3、transient,暂时的,修饰成员变量,透明的
          对于一些敏感的数据(银行卡,密码),在进行序列化,或网络传输时,不应该让其他人          知道,在序列化对象时,该属性不应该进行序列化时,就将该属性定义为transient
4、使用transient修饰的成员变量真的不能被序列化吗?
   不一定,需要看实现哪一个接口
   如果实现java.io.Serializable,所有的属性将自动进行序列化
   transient修饰的属性不被序列化
   如果实现java.io.Externalizable,没有任何属性可以进行自动序列化,需要重写readExternal和writeExternal方法进行手工序列化,属性是否使用transient修饰无关


5、RandomAccessFile:
   特点:
   (1)既能读,又能写
   (2)该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素
   (3)可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置
   (4)其实该对象就是将字节输出流和输入流进行了封装
   (5)该对象的源或者目的只能是文件。通过构造函数就可以看出(如果文件不存在,就创建;如果存在,不创建)
   构造函数第二个参数用来指定流的模式
   seek方法将文件指针移动到指定位置,0为文件起始位置
   skipBytes(int b);//跳过指定的字节数
   writeUTF(String str);//把两个字节从文件的当前文件指针写入到此文件,并给定要跟随的字节数
6、管道流:一般与多线程一起使用,不然会死锁线程,read是阻塞式方法,并且只能读取管道输出流中的数据,所以没有数据时,会一直等待
   PipedInputStream:
   pipedOutputStream:
   这两个流通过connect方法连接起来


总结:
流的选择:
a、明确源和目的,进行读写操作
b、读写的文件是否是文本文件(是:字符流;不是:字节流)
c、所涉及到的设备


综合练习题:
有三个学生,每人两门课程,从键盘获得数据(学生姓名,两门课成绩),格式:张三,90,80
将学生的信息和总分写入文件 (要求;按照总分从高到底排序)




   
0 0
原创粉丝点击