java基础——IO流

IO流  


一、IO

IO流是处理设备之间数据的传输
常用的流对象有直接操作文件的流对象以及带缓冲的流对象

根据处理数据不同分为:
字节流:对于图片或是视频等非纯文本文件的操作只能用字节流。

字符流:字符流其实就是字节流+编码机制。当对文件的操作是用字符流

1.字节流:

    字节流不存在缓冲区
InputStream:读操作
OutputStream:写操作
FileInputStream:FileOutputStream中不存在缓冲区,直接将数据写入到目的地
FileInputStream中的available()方法:获取和流相关联的文件的“剩余”字节数

2.字符流:
Reader,常用FileReader纯文本读操作
     Writer,常用FileWriter 对纯文本写操作
    注意:字符流不能对图片和音频复制,因为当字符流读取数据时,字符流会查默认的编码表,如果编码表中没有查到具体的数据,就会用其他的数据替代。就会出现数据错乱。只有当操作操作数据是文本时建议使用。

FileReader:对文件的读操作
定义数组的长度一般为1024的整数倍
    FileWriter:对文件的写操作
    1)可以对文件进行续写new FileWriter("aa.txt",true);
    2)new FileWriter("a.txt");当要创建的文件已经存在,就会产生覆盖 

    3.缓冲区:(装饰设计模式)
        1.缓冲区可以提高读写效率,但是缓冲区对象的建立首先得将流初始化进来
        2.用到缓冲区一定要flush();
        3.缓冲区是提高流的操作效率而存在的,内部提供了数组。对数组缓冲。但是最终的操作还是流来完成的,所以 关闭缓冲区,其实就是关闭流。其内部调用的是close()方法
BufferedReader:读操作的缓冲区
BufferedWriter:写操作的缓冲区,每读一行要调用newLine()flush()方法

示例:

import java.io.*

import java.io.FileReader

import java.io.IOException

import java.io.BufferedReader

public class Test{ 

public static void main(String...args) throws IOException

Reader r = new FileReader("C:\\1.Java"); 

/* 

为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数

*/ 

BufferedReader br =  new BufferedReader(r); 

for(String line = null;(line=br.readLine())!=null;){ 

System.out.print(line); 

System.out.println(); 

 } 

     } 

 

装饰设计模式:当对类的功能进行增强时,称为对该类的装饰,具备灵活性。
        例如:现在要用A接口的一个方法,但是需要把A接口所有的方法实现才可以,以后如果再次用到A接口,其他的方法同样繁琐。这样我们就先定义一个类B实现A接口,但是B类的方法全部为空,以后直接继承B类即可

    4.转换流:
      InputStreamReader:字节流通向字符流的桥梁
      OutputStreamWriter:字符流通向字节流的桥梁
      转换流可以设置编码表,不设置就是本机默认的编码表。如果是指定编码表,就要将编码表作为字符串传入构造函数中

     例如:BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream

("aa.jpg")));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream

("bb.jpg")));

    5. LineNumberReader:带有行号

readLine():底层其实就是调用了read()方法,一次读一个字符,并把该字符临时存储,当读到换行符的时候就将存储的数据作为字符串返回,输入流和输出流其实都是需要缓冲区来先存放读取的数据,再通过写缓冲区的数据来实现。

    6.打印流:PrintWriterPrintStream
只操作写,而且PrintWriter不抛异常

    7.管道流:PipedlnputStreamPipedOutputStream
1) 输入输出可以直接进行连接
2) 先读后写会出现死锁,所以建议多线程

    8.序列流: SequenceInputStream
对多个流进行合并,实现数据的合并

    9.文件切割:RandomAccessFile
1)随机访问文件,自身具备读写方法
2)该对象操作的数据时字节数据,其中封装了读取流和写入流;      

3)提供getFilePointer方法获取指针位置,有seek设置指针位置

raf.write(65);将一个整数的最低四个字节写出。
raf.seek(8);从指针索引位8开始进行写入,完成数据的随机写入

对已有数据修改,移动指针,seek()方法可以应用对于多线程对于大数据的写入,同时写入,给每个线程分配一个起始索引位,可以多线程随机写入

10.对象的持久化ObjectStream
就是将对象中封装数据保存到持久化的设备比如硬盘;
Serializable接口,序列化。有相对于的SerializableUID,即序列号,通过类成员数据签名完成

       没有方法的接口称之为标记接口
       对象中静态数据时不会被持久化的,它不在堆内存中
       非静态数据不想被持久化:进行transient修饰

       指定固定的序列号public static final long serialVersionUID = 42L

  11.操作基本数据类型的IO:DateInputStreamDateOutputStream
 注意:ByteArrayOutputstream:关闭它无效,因为该对象根本没有调用底层资源。不抛出异常。可以通过toByArray()或者toString()获取数据

    关闭流必须在finally中进行操作,而且在关闭之前判断流是否存在,否则会出现空指针异常。另外关闭流的时候也会抛出异常,每一个流的关闭都单独执行
    对文件进行读写的时候,可能文件路径错误,所以会出现异常

    flush()close()
flush():刷新缓冲区,流依然存在,并可以继续使用
close():先刷新缓冲区,其实就是调用一次flush(),然后关闭调用底层资源,将资源释放

 

二、装饰设计模式

     装饰设计模式的出现是为了增强功能

     装饰设计模式通常不单独存在,都是通过构造函数接收被装饰的对象,基于被装饰对象的功能,对外界提供增强的功能。它可以对一组类进行功能的增强

和继承的区别:
继承会让体系变得臃肿,但是装饰则显得更为灵活

IO流中很多体系用到装饰设计模式,例如Writer

    1、当想要对已有对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有的功能,并提供加强功能,那么该自定义类称为装饰类。

    2、装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的功能,提供更强的功能。

(可以理解为打扮,比如自己如果要去面试之前,咱们要把自己打扮一下,把自己搞上点新鲜的衣服,但是最后还是一个人,只是身上多个点东西,这就是装饰)

三、IO流体系

 

Reader 

|--InputStreamReader 

|--FileReader 

|--BufferedReader 

|--LineNumberReader 

|--CharArrayReader 

|--StringReader 

|--PipedReader 

Writer 

|--OutputStreamWriter 

|--FileWriter 

|--BufferedWriter 

|--CharArrayWriter 

|--StringWriter 

|--PrintWriter 

|--PipedWriter 

File

InputStream 

|--FilerInputStream 

|--LineNumberInputStream 

|--BufferedInputStream 

|--DataInputStream 

|--FileInputStream 

|--ByteArrayInputStream 

|--PipedInputStream 

|--ObjectInputStream 

|--SequenceInputStream 

OutputStream 

|--FilerOutputStream 

|--PrintOutputStream 

|--BufferedOutputStream 

|--DataOutputStream 

|--FileOutputStream 

|--ByteArrayOutputStream 

|--PipedOutputStream 

|--ObjectOutputStream 

RandomAccessFile 

 

接口 

Serializable 

 

四、File

       可以是文件对象,也可以是文件夹对象
       File f=new File("c:\\a.txt");把指定文件封装成File对象
       File f=new File("c:\\","a.txt");
             
       File dir=new File("c:\\a.txt");        
       File f=new File(dir,"a.txt");

       1.程序跨平台
       File f=new File("c:"+File.separator+"a.txt");目录分隔符

    2.创建
         File f=new File("f.txt");
         boolean b=f.createNewFile(); 如果这个文件不存在创建,存在就不创建;但是如果是输出流创

建文件,就会直接覆盖,如果构造函数true,不会覆盖,可以续写抛异常     

         File f=new File("abc");     
         f.mkdir();创建你目录
         f.mkdirs();创建多级目录

    3. 删除
         File f=new File("f.txt");
         f.delete();直接删除,不经过回收站
            删除文件夹,如果文件夹中有内容,应该先将内容清空
         void deleOnExit()告诉JVM,程序退出,一定要把该文件删除

    4.判断
          isFile();文件
          isDirectory();目录
          isAbsolute(); 绝对路径
          exists();判断File封装的对象是否存在    
          canExecute();判断文件是否执行
          File f=new File(path);
          Runtime r=Runtime.getRuntime();
          if(f.canExecute()) r.exec(path); 

     注意:File f=new File("xx.txt");格式为xx.txt不一定是文件,也可能是文件夹。

    5.获取
                getPath();相对路径
                getAbsolutePath();绝对路径
                getParent();父目录
                getName();文件名
                length();返回该文件字节数,只对文件而言,文件夹没有
                lastModified();最后一次修改的时间
                   服务器配置文件就是的,设一条线程,隔几秒监控是否改变

                File f1=new File("qq.txt");
                File f2=new File("ww.txt");

  6.重命名 f1.renameTo(f2);f的文件名改成ff的文件名,
可以进行文件的移动(剪切+全命名)

  7.文件列表
              File[] roots=File.listRoots();获取系统可用盘符
              for(File root: roots){}

              File dir=new File("c:\\");获取当前目录下得文件夹和文件的名称
                                      包括隐藏文件,如果是文件的话,就返回null 
              String [] names=dir.list();
              String[] list();只获取名称
              File[] listFiles();获取当前目录下文件或文件夹的对象

      8.获取mp3文件
               实现FilenameFilter接口,accept方法 return name.endWith(".mp3");
               return new File(dir,name).isFile() && name.endsWith(".mp3");
                   首先必须是文件


            获取指定目录下所有的文件和文件夹,包括子目录中的内容:递归


五、字符编码

         ASCII用一个字节7位表示
         GB2312中文编码表,六千多字
         GBK中文编码表升级,两万多字,中文两个字节,最高位都是1
         Unicode国际标准码,Java使用的Unicode
         UTF-8最多用三个字节表示一个字符

         编码:字符串——>字节数组
         解码:字节数组——>字符串

         例如:abc你好cd
            对字符串进行字节个数截取,如果出现半个中文,舍弃
                  1.判断最后一个被截取的字节是不是负数
                  2.如果是负数,继续往前判断,连续负数的个数
                  3.如果是偶数,说明没半个中文,不用舍弃
                  4.如果是奇数,说明出现半个中文,舍弃最后一个字节
                
        gbk一个中文两个字节,有的字节可能正数
        gb2312一个中文两个字节都是负数

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值