欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一篇文章带你深入了解javaIO基础

程序员文章站 2022-03-10 07:58:54
目录一.认识io1.io的分类2.io的方式3.io读写的方式4.io的特性3.文件操作的api使用三.io流一.认识io1.io的分类(1)bio:同步阻塞io(2)nio:同步非阻塞io(3)ai...

一.认识io

1.io的分类

(1)bio:同步阻塞io

(2)nio:同步非阻塞io

(3)aio:异步阻塞io

注意: 这里主要介绍bio

2.io的方式

io本质就是对数据的操作

(1)网络io

(2)本地io

3.io读写的方式

一篇文章带你深入了解javaIO基础

4.io的特性

(1)本质上属于数据传输

(2)涉及两个设备间的传输方向(一般,自己写java程序的时候,只关注自己程序的一方)

(3)数据流

一篇文章带你深入了解javaIO基础

(4)java进程的io操作,对进程的影响:

  • 1.阻塞io 会导致进程在运行态和阻塞态之间转变,由操作系统完成后序的io操作
  • 2.java进程,在内核态和用户态之间切换:性能会收到影响(下降)

(5)io缓冲流

一篇文章带你深入了解javaIO基础

不使用缓冲流:java程序每次都从主机内存读写数据,每次都直接读取数据/发送数据。write()/read()

使用/不使用缓冲区的区别:

例如:循环10000次,每次write1个字节数据到本地文件

不使用缓冲区:每次循环都是io操作,都涉及进程状态由运行态变为阻塞态,由用户态变为内核态(10000次影响)

使用缓冲区:每次write复制数据到缓冲区,flush才算io操作(一定要记得)(一次影响)性能更好

二.文件操作

1.文件的构成

(1)文件的头信息(metadata)

(2)文件的内容

注意: java.io.file 不是对文件的内容操作,知识对文件本身或者头信息操作

2.文件的创建

一篇文章带你深入了解javaIO基础

new操作时的注意事项:

  • 1.既可以指定文件,也可以指定文件夹
  • 2.通过路径创建file:可以使用绝对路径/相对路径
  • 3.不管路径上是否存在这个文件/文件夹,java都可以创建得到一个file对象(但是对这个file操作时,可能会抛出异常)

3.文件操作的api使用

一篇文章带你深入了解javaIO基础

文件操作示例:遍历某个目录下,所有的子文件/子文件夹

  public static void main(string[] args) {
        file file=new file("c:\\users\\26905\\desktop\\javacode");
        list<file> list=listdir(file);
//        for (int i = 0; i <list.size() ; i++) {
//            system.out.println(list.get(i));
//        }
        //jdk1.8集合框架使用stream操作,可以使用lambda表达式打印
        list.stream().foreach(system.out::println);
    }

方法一: 效率不高

public static list<file> listdir(file dir){
        list<file> list=new arraylist<>();
        if(dir.isfile()){
            list.add(dir);//效率不太好的地方,如果是文件,返回的list只存放一个元素
        }else {
            file[] children=dir.listfiles();
            for(file file:children){
                list<file> files=listdir(file);
                list.addall(files);
            }
        }
        return list;
    }

方法二: 效率较高

 public static list<file>  listdir2(file dir){
        list<file> list=new arraylist<>();
        if(dir.isdirectory()){
            //获取目录下一级的子文件和子文件夹
            file[] children=dir.listfiles();
            if(children!=null){
                for(file file:children){
                    if(file.isdirectory()){
                        //如果子文件还是文件夹,递归调用
                        list.addall(listdir2(file));
                    }else{
                        list.add(file);
                    }
                }
            }
        }
        return list;
    }

三.io流

1.流的分类

一篇文章带你深入了解javaIO基础

一篇文章带你深入了解javaIO基础

一篇文章带你深入了解javaIO基础

2.流的创建

一篇文章带你深入了解javaIO基础

3.流的使用

一篇文章带你深入了解javaIO基础

<1>输入流

import java.io.*;
public class  fileinput {
    /**
     * 字节文件:c:\users\26905\desktop\画图笔记\javaweb\json和ajax简单介绍.png
     * 字符文件:c:\users\26905\desktop\论文,ppt,作业,笔记,图片等\java笔记.txt
     * @param args
     */
    public static void main(string[] args) throws ioexception {
        //图片文件,以二进制的方式操作
        file file1=new file("c:\\users\\26905\\desktop\\画图笔记\\javaweb\\json和ajax简单介绍");
        file file =new file("c:\\users\\26905\\desktop\\论文,ppt,作业,笔记,图片等\\比特草稿本.txt");

        //1.文件输入字节流
        fileinputstream fis=new fileinputstream(file);
        //不知道文件有多 大,先定义一个一定大小的字节数组,然后不停读入,每次刷新以下就好
        byte[] bytes=new byte[1024*8];
        //输入流读取的固定写法:读取到一个字节/字符数组,定义read的返回值变量,while
        int len=0;
        //len表示读入字节的长度
        //如果不等于-1,说明读取未结束
        while ((len=fis.read(bytes)) !=-1){
            //读取到的长度,数组可能读满,也可能没有读满
            //当次读取,一般使用数组[0,len]表示读取内容
            //字节数组转字符串
            string str=new string(bytes,0,len);
           // system.out.println(str);
        }
        //一般来说,输入输出流使用完,一定要关闭,关闭的关系是反向关系
        //例如:创建的时候是从里往外创建,则关闭的时候就是从外往内关闭
        fis.close();

        //2.文件的字符输入流
        filereader fr=new filereader(file);
        char []chars=new char[1024];
        int lenfr=0;
        while ((lenfr=fr.read(chars))!=-1){
             string strfr=new string(chars,0,lenfr);
            //system.out.println(strfr);
        }
        fr.close();

        //3.缓冲流:缓冲字节输入,缓冲字符输入
        fileinputstream fis=new fileinputstream(file);//文件字节输入流
        //字节流转字符流一定要经过字节字符转换流来转换,并且还可以指定编码
        inputstreamreader isr=new inputstreamreader(fis);
        //缓冲流
        bufferedreader br=new bufferedreader(isr);
        string str;
        //读取,当字符串为空时,结束
        while ((str=br.readline()) !=null){
            system.out.println(str);
        }
        br.close();
        isr.close();
        fis.close();
    }
}

<2>输出流

import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.printwriter;
public class fileoutput {
    public static void main(string[] args) throws ioexception {
        /**
         * d:\java代码\1.txt
         */
        //路径上没有该文件,new file不会报错,但是在操作输出流会抛出filenotfoundexception
        file file2=new file("d:\\java代码\\1.txt");
        //把a-z换行输出到某个文件,需要考虑文件是否存在的问题
        if(!file2.exists()){
            file2.createnewfile();
        }
        //new filewriter()  文件的不带缓冲的字符输出
        //new filewriter()  文件的不带缓冲的字节输出
        //new bufferedwriter() 带缓冲的字符输出
        //new printwriter()    打印输出流

        //缓冲的字符输出
//        bufferedwriter bw=new bufferedwriter(new filewriter(file2));
//        bw.write("\n");

        //打印输出流
        //printwriter pw=new printwriter(new filewriter(file));
        printwriter pw =new printwriter(new fileoutputstream(file2));
        //快速打印a-z
        for (int i = 'a'; i <='z' ; i++) {
            pw.println((char)i);
        }
        pw.flush();
    }
}

<3>实例:文件的复制

import java.io.file;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
public class filecopy {
    public static void main(string[] args) throws ioexception {
        //文件复制
        file input=new file("d:\\java代码\\1.txt");
        file output=new file("d:\\java代码\\2.txt");
        if(!output.exists()){
            output.createnewfile();
        }
        //定义输入输出流
        //输入流
        fileinputstream fis=new fileinputstream(input);
        // 输出流
        fileoutputstream fos=new fileoutputstream(output);
        byte[]bytes=new byte[1024*8];
        int len;
        while ((len=fis.read(bytes))!=-1){//每次从输入流读取到byte[]的内容,直接输出到某个文件,就是复制
            //bytes可能没存满,需要指定长度
            fos.write(bytes,0,len);
        }
        fis.close();
        fos.close();
    }
}

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!