java IO学习笔记

JAVA I/O

一、流的分类

  1. 按流向分

    • 输入流:将数据从存储设备读入到内存中
    • 输出流:将数据从内存中存到存储设备上
  2. 按单位分

    • 字节流:以字节为单位,可以读写所有数据

      • InputStream:字节输入流,常用有的方法:

        int read()从输入流读取数据的下一个字节。
        int read(byte[] b)从输入流读取一些字节数,并将它们存储到缓冲区 b
        int read(byte[] b, int off, int len)从输入流读取最多 len字节的数据到一个字节数组。
        void close()关闭此输入流并释放与流相关联的任何系统资源。
      • OutputStream:字节输出流,常用有的方法:

        voidwrite(byte[] b)b.length字节从指定的字节数组写入此输出流。
        void write(byte[] b, int off, int len)从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
        voidwrite(int b)将指定的字节写入此输出流。
        void close()关闭此输出流并释放与此流相关联的任何系统资源。
      • 文件字节流:FileInputStream/FileOutputStream

        一个字节的读取方式:

         /*创建文件字节流对象;传入参数为目标文件的路径*/
                FileInputStream fis = new FileInputStream("C:\\Users\\18255\\Desktop\\test.txt");
        
                //1.逐个字节读取
                int data =0;
                while((data=fis.read()) != -1){    //当返回值为-1时,表示已经读完
                    System.out.print(((char)data));
                }
        
                fis.close();
        

        多个字节读取方式:

                /*创建文件字节输入流对象;传入参数为目标文件的路径*/
                FileInputStream fis = new FileInputStream("C:\\Users\\18255\\Desktop\\test.txt");
        
                //多个字节读取
                byte buf [] = new byte[5];
                int count=0;
                while((count = fis.read(buf)) != -1) {
                    System.out.print(new String(buf,0,count));
                }
        
                fis.close();
        

        写入:

           /*创建文件字节输出流对象;传入参数为目标文件的路径*/
        		FileOutputStream fos = new FileOutputStream("C:\\Users\\18255\\Desktop\\testOut.txt");
        	   
                //传入的为字节
                fos.write('a');
                fos.write(100);
                String str = "helloWorld";
                fos.write(str.getBytes());
        
                fos.close();
                System.out.println("success");
        
      • 字节缓冲流:BufferedInputStream/BufferedOutputStream

            public static void main(String[] args) throws Exception {
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\18255\\Desktop\\test1.txt"));
        
                for(int i=0; i<10; i++){
                    bos.write("test\r\n".getBytes());
                }
                bos.flush();  //使用flush将数据写入硬盘
                bos.close();
        
            }
        
      • 对象流:ObjectInputStream/ObjectOutputStream

        读取(反序列化):

        	   ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\18255\\Desktop\\testObject.txt"));
        
                user user = (user)ois.readObject();
                System.out.println(user);
        

        写入(序列化):

        	   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\18255\\Desktop\\testObject.txt"));
        
                user user = new user(1,"san","nan");
                oos.writeObject(user);
                oos.close();
                System.out.println("success");
        

        **被序列化的对象必须实现Serializable接口;**此外该类内部必须定义serialVersionUID

        //例如:
        private static final long serialVersionUID = 155552L;
        

        如果不添加UID则当序列化,修改类的结构,再反序列化将出错

        **此外:**内部的所有属性都要可序列化(包括自定义类),默认基本数据类型可序列化;

        不能序列化static、transient修饰的成员变量

    • 字符流:以字符为单位,只能读写文本数据

      • Reader

        int read()读一个字符
        int read(char[] cbuf)将字符读入数组。
        abstract intread(char[] cbuf, int off, int len)`将字符读入数组的一部分。
        int read(CharBuffer target)尝试将字符读入指定的字符缓冲区。
      • Writer

      void write(char[] cbuf)写入一个字符数组。
      abstract void write(char[] cbuf, int off, int len)写入字符数组的一部分。
      void write(int c)写一个字符
      void write(String str)写一个字符串
      void write(String str, int off, int len)写一个字符串的一部分。
    • 文件字符流:FileReader/FileWriter

      文件字符输入流:

              FileReader fr = new FileReader("C:\\Users\\18255\\Desktop\\test.txt");
      
              char [] c = new char[2];
              int count =0;
              while((count = fr.read(c)) != -1){
                  System.out.println(new String(c,0,count));
              }
              fr.close();
      

      文件字符输出流:

              FileWriter fw = new FileWriter("C:\\Users\\18255\\Desktop\\test1.txt");
      
              for(int i=0; i<10; i++){
                  fw.write("你好");
                  fw.flush();
              }
              fw.close();
      

    • 字符缓冲流:BufferedReader/BufferedWriter

      字符缓冲输入流

              BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\18255\\Desktop\\test.txt"));
      		/*
              //方式一
              char [] buf = new char[1024];
              int count = 0;
              while((count = br.read(buf)) != -1){
                  System.out.println(new String(buf,0,count));
              }
              */
      
              //方式二
              String line = null;
              while((line = br.readLine()) != null){
                  System.out.print(line);
              }
      
              br.close();
      

      字符文件输出流

              BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\18255\\Desktop\\test1.txt"));
      
              for(int i=0; i<10; i++){
                  bw.write("this is the test~ ");
                  bw.newLine();  //自动写入换行
                  bw.flush();
              }
      
              bw.close();
              System.out.println("success");
      
  3. 按功能分

    • 节点流:具有实际的传输数据的读写功能
    • 过滤流:在节点流的基础上进行增强功能

二、其他

  • 打印流:可以保存原有的数据样式(PrintWriter)

    	    PrintWriter pw = new PrintWriter("C:\\Users\\18255\\Desktop\\test1.txt");
    
            pw.println("你好");
            pw.println('a');
            pw.println(0.3222);
            pw.println(true);
            pw.close();
    

    与PrintStream类似,但是PrintStream为字节流

  • 转换流:InputStreamReader/OutputStreamWriter

    可以将字节流转换为字符流;可设置字符的编码方式

    • InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符
    • OutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset
        public static void main(String[] args) throws Exception{
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\18255\\Desktop\\test1.txt"),"GBK");
            for(int i=0; i<10; i++){
                osw.write("这是转换流的测试\r\n");
                osw.flush();
            }
    
            osw.close();
            System.out.println("success");
            System.out.println("------------------------------------");
    
            InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\18255\\Desktop\\test1.txt"),"GBK");
            char [] buf = new char[1024];
            int count =0;
            while((count = isr.read(buf)) != -1){
                System.out.println(new String(buf,0,count));
            }
            isr.close();
        }
    

三、RandomAccessFile 随机存取文件流

直接继承于Object类;

实现了DataInPut、DataInOut,即可以作输入流,又可以作输出流

RandomAccessFile(File file, String mode) 需要传入file和mode

参数作用
r只读方式打开
rw读写模式
rwd读写模式;同步文件内容的更新
rws同步文件内容和元数据的更新
public static void main(String[] args)  {
        RandomAccessFile r = null;
        RandomAccessFile rw = null;

        try{
            r = new RandomAccessFile(new File("C:\\Users\\18255\\Desktop\\log.txt"), "r");
            rw = new RandomAccessFile(new File("C:\\Users\\18255\\Desktop\\raf.txt"), "rw");
            byte arr[] = new byte[100];
            int len = 0;
            while((len = r.read(arr)) != -1){
                rw.write(arr,0,len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (r != null){
                try {
                    r.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            if (rw != null){
                try {
                    rw.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

如果作为输出流,写出的文件不存在时,会创建文件;

如果文件已存在,则默认从头开始覆盖源文件内容;

使用seek(int pos)可以指定从pos索引处开始覆盖

四、file类

概念:文件和目录路径名的抽象表示。

文件操作:

    public static void main(String[] args) throws Exception{
        separator();
        //FileOpe();
        directoryOpe();
    }

    /*分隔符*/
    public static void  separator(){
        System.out.println("路劲分隔符:"+ File.pathSeparator);  //为环境变量的分隔符
        System.out.println("名称分隔符:"+ File.separator);    //为文件目录的分隔符
    }

    /*文件操作*/
    public static void FileOpe() throws Exception{
        //1.创建文件
        File file = new File("C:\\Users\\18255\\Desktop\\fileTest.docx");   //创建文件对象
        //System.out.println(file.toString());   //打印文件路劲
        if(!file.exists()){    //判断文件是否村在,如果不存在则创建
            boolean newFile = file.createNewFile();
            System.out.println("文件创建成功");
        }

        //2.删除文件
        //2.1直接删除
        //file.delete();

        //2.2使用jvm退出时删除
        //file.deleteOnExit();

        //3.获取文件信息
        System.out.println("获取文件名称"+file.getName());
        System.out.println("获取绝对路径"+file.getAbsolutePath());
        System.out.println("获取父目录路径:"+file.getParent());
        System.out.println(file.getUsableSpace());
        System.out.println("获取文件长度:"+file.length());

        //4.判断
        System.out.println("是否可写"+file.canWrite());
        System.out.println("是否是文件"+file.isFile());
        System.out.println("是否是隐藏"+file.isHidden());
    }

    public static void directoryOpe(){
        //1.创建文件夹
        File dir = new File("C:\\Users\\18255\\Desktop\\NewDir\\aa\\cc");
        if(!dir.exists()){
            //dir.mkdir();  //是能创建单但目录
            dir.mkdirs();   //可以创建多级目录
            System.out.println("文件夹创建成功");
        }

        //2.删除文件夹
        //2.1.直接删除
        //System.out.println("删除结果"+dir.delete());   //只能删除最低级的目录,且该目录必须为空

        //2.2jvm删除
        //file.deleteOnExit();


        //3.获取文件夹信息,基本同上(没有长度等)

        //4.判断
        System.out.println("是否是文件夹:"+dir.isDirectory());

        //5.遍历文件夹
        File file = new File("C:\\Users\\18255\\Desktop\\python");
        String[] list = file.list();
        for (String s : list) {
            System.out.println(s);
        }
    }

递归遍历和删除文件夹

    public static void main(String[] args) {
        //listDir(new File("C:\\Users\\18255\\Desktop\\NewDir"));   //目标文件夹
        deleteDir(new File("C:\\Users\\18255\\Desktop\\NewDir"));   //目标文件夹
    }

    /*递归遍历文件夹*/
    public static void listDir(File f){
        File[] files = f.listFiles();    //遍历文件夹,获得内容文件数组
        System.out.println(f.getAbsolutePath());   //打印问价路径
        if (files != null && files.length>0){   //如果数组不为空
            for (File file: files) {
                if (file.isDirectory()){    //判断该问价是否为文件夹,若果是进入递归;如果不是,打印文件的绝对路径
                    listDir(file);
                }else{
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }


    /*递归删除文件夹*/
    public static void deleteDir(File f){
        File[] files = f.listFiles();    //遍历文件夹,获得内容文件数组
        if (files != null && files.length>0){   //如果数组不为空
            for (File file: files) {
                if (file.isDirectory()){    //判断该问价是否为文件夹,若果是进入递归;如果不是,打印文件的绝对路径
                    deleteDir(file);
                }else{
                    System.out.println("删除文件:"+file.delete());
                }
            }
        }
        f.delete();
    }


NIO.2

jdk7发布

实例

一、复制文件(使用字节流方式)

    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("C:\\Users\\18255\\Desktop\\zxy.png");
        FileOutputStream fos = new FileOutputStream("C:\\Users\\18255\\Desktop\\zxyCopy.png");

        int inCount = 0;
        byte buf [] = new byte[1024];
        while((inCount=fis.read(buf)) != -1){         //读取1k字节数据存入缓存
            fos.write(buf,0,inCount);                 //将实际读到的字节数的数据写入文件
        }
        fis.close();
        fos.close();
        System.out.println("success");
    }

二、复制文件(使用字符流方式)

只能是文本文件,图片等二进制文件不能存储

public static void main(String[] args) throws Exception {
        //创建流
        FileReader fr = new FileReader("C:\\Users\\18255\\Desktop\\test.txt");
        FileWriter fw = new FileWriter("C:\\Users\\18255\\Desktop\\test1.txt");

        //循环读取1k数据进入数组,并将数据写入硬盘
        int count = 0;
        char [] c= new char[1024];
        while((count = fr.read(c)) != -1){
            fw.write(c,0,count);
            fw.flush();
        }
    
        //关闭流
        fr.close();
        fw.close();
        System.out.println("复制完毕");
    }

三、RandomAccessFile 实现插入数据

在文件索引为5的位置处插入“this is test"

public static void main(String[] args) {
        RandomAccessFile r = null;
        RandomAccessFile rw = null;

        try {
             r = new RandomAccessFile(new File("C:\\Users\\18264\\Desktop\\log1.txt"), "r");
             rw = new RandomAccessFile(new File("C:\\Users\\18264\\Desktop\\log1.txt"), "rw");
            StringBuilder stringBuilder = new StringBuilder((int) new File("C:\\Users\\18264\\Desktop\\log1.txt").length());
            byte [] buf = new byte[20];
            r.seek(5);    //将光标定位置索引为5处
            int len = 0;
            while((len = r.read(buf)) != -1){
                stringBuilder.append(new String(buf,0,len));    //将索引为5以后的数据读取并存放到StringBuilder中
            }
            rw.seek(5);         //将写出流的光标定位在索引为5处
            rw.write("this is test".getBytes());   //写入数据并覆盖原来的数据
            rw.write(stringBuilder.toString().getBytes());    //将读取到的数据写入文件中,实现插入操作
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(r != null){
                try {
                    r.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(rw != null){
                    try {
                        rw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

四、 读取文件中的行数

   public static void main(String[] args) {
        int count =0;
        File file = new File("D:\\idea\\WorkSpace\\Mybatis01\\src");
        int files= getLines(file);
        System.out.println(files);
    }

    public static int getLines(File f){
        int line = 0;
        if(f.isDirectory()){           //判断传入的是否是文件夹
            File[] files = f.listFiles();    //如果是,则获得该文件夹下的所有file
            if(files != null && files.length >=0){
                for (File file: files) {     //遍历文件夹下的fiel
                    if(file.isFile()){       //如果是文件类型
                        BufferedReader br1 = null;
                        try {
                            br1 = new BufferedReader(new FileReader(file.getAbsolutePath()));  //获取文件绝对路径并创建流
                            while(true){
                                String s = br1.readLine();           //读取问价中的行数,直到读取完毕返回null
                                if(s == null){
                                    break;
                                }else{
                                    line++;
                                }
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }finally {
                            try {
                                br1.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }else{                     //如果是文件夹类型,则使用递归,遍历该文件夹下的内容
                        int dirs = getLines(file);
                        line += dirs;
                    }
                }
            }
        }else{                        //如果传入的不是文件夹,则直接读取
            BufferedReader br2 = null;
            try {
                br2 = new BufferedReader(new FileReader(f.getAbsolutePath()));
                while(true){
                    String s = br2.readLine();
                    if(s == null){
                        break;
                    }else{
                        line++;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    br2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return line;    //返回该file的行数
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值