java的IO流-行云流水篇(学习笔记全)

java的IO流-行云流水篇(学习笔记全)

先来看一下java中IO流 的图谱

在这里插入图片描述

一、File类

File类能代表与平台 无关的文件和目录。File能新建、删除、重命名文件和目录,但是不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入输出流。

File类常用方法:

大致有以下几种:

  1. isDirectory() 是否为文件夹
  2. isFile() 是否为文件
  3. getPath() 得到file的路径
  4. getName() 得到最后一层的名字
  5. getParent() 得到去掉最后一层的路径
  6. getParentFile() 得到父类路径的新文件
  7. renameTo() 改名
  8. mkdir() 创建新文件夹,只能创建一层
  9. mkdirs() 创建新文件夹,可以多层
  10. createNewFile() 创建新文件,只能一层
  11. exists() 路径(文件或者文件夹)是否存在
  12. delete() 删除文件或者目录(为空的目录)
  13. list() 返回该路径下文件或者文件夹的名字数组
  14. listFiles() 返回该路径下文件或者文件夹组成的File数组
  15. separator 代替文件或文件夹路径的斜线或反斜线,防止跨平台出现错误

递归遍历文件夹,输出路径下的所有文件和文件夹

public class IOTest {
    public static void main(String[] args) {
        File file=new File("E:\\mabook\\Git_code");
        IOTest ioTest=new IOTest();
        ioTest.recursion(file);
    }

    public void recursion(File file){
        if (file.isFile()){
            System.out.println("文件--->"+file.getAbsolutePath());
        }else{
            System.out.println("文件夹->"+file.getAbsolutePath());
            File[] fs=file.listFiles();
            for (File ff:fs){
                recursion(ff);
            }
        }
    }
}

二、文件字节流&字符流

文件字节流较为通用,可以用来操作字符的文档,还可以操作任何的其他类型文件(图片,压缩包等等)

输入流 FileInputStream,FileReader

输出流 FileOutputStream,FileWriter

public class IOTest {
    public static void main(String[] args) {
        IOTest ioTest=new IOTest();     		                 ioTest.copyFile("E:\\mabook\\Git_code\\demo\\README.md","E:\\mabook\\Git_code\\demo\\README10086.md");
        //输出文件路径的目录结构确保真实存在,不会自动建文件夹目录
    }
/**
 * 文件字节流操作
 */
    public void copyFile(String inPath,String outPath){
        try{
            FileInputStream in=new FileInputStream(inPath);
            FileOutputStream out=new FileOutputStream(outPath);
            byte[] b=new byte[127];
            int len=0;
            while ((len=in.read(b))!=-1){
                out.write(b,0,len);
            }
            out.flush();
            out.close();
            in.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
 /**
     * 文件字符流操作
     * @param inPath 被复制文件路径
     * @param outPath 复制后的文件路径
     */
    public void copyFile2(String inPath,String outPath){
        try{
            FileReader in=new FileReader(inPath);
            FileWriter out=new FileWriter(outPath);
            char[] c=new char[100];
            int len=0;
            while ((len=in.read(c))!=-1){
                out.write(c,0,len);
            }
            out.flush();
            out.close();
            in.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

flush()和write()方法有什么区别

java在使用流时,都会有一个缓冲区,按一种它认为比较高效的方法来发数据:把要发的数据先放到缓冲区,缓冲区放满以后再一次性发过去,而不是分开一次一次地发.而flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.所以如果在用流的时候,没有用flush()这个方法,很多情况下会出现流的另一边读不到数据的问题,特别是在数据特别小的情况下.

三、缓冲流

缓冲流即先把数据缓存到内存里,在内存中做io操作,速度比上面的的直接操作能快上万倍。

输入流 BufferedInputStream,BufferedReader

输出流 BufferedOutputStream,BufferedWriter

关闭流的顺序:遵循最先开的最晚关

public class IOTest {
    public static void main(String[] args) {
        IOTest ioTest=new IOTest();
        try {
            ioTest.bufferedTest("E:\\Desktop\\git\\java.md","E:\\Desktop\\git\\copy_java.md");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void bufferedTest(String inPath,String outPath) throws Exception{
        //文件字节输入流对象
        FileInputStream in=new FileInputStream(inPath);
        //创建字节输出流对象
        FileOutputStream out=new FileOutputStream(outPath);
        //把文件字节输入流放到缓冲字节输入流对象
        BufferedInputStream br=new BufferedInputStream(in);
        //把字节输出流对象放到缓冲字节输流流中
        BufferedOutputStream bo=new BufferedOutputStream(out);

        byte[] b=new byte[1024];
        int len=0;
        while ((len=br.read(b))!=-1){
            bo.write(b,0,len);
        }
        bo.flush();
        bo.close();
        br.close();
        in.close();
        out.close();
    }
}

缓冲字节流跟字符流基本一样,使用FileReader,FileWriter,BufferedReader,BufferedWriter替换即可。

三、转换流

输入流 InputStreamReader

输出流 OutputStreamWriter

为啥使用转换流?

转换流提供了字节流和字符流之间的装换,如果我们程序使用字节流在操作文件时,文件中存在大量字符(例如是txt,word文件等等),那么效率大打折扣,所以需要使用到转换流,将字节流转换为字符流

注意点?

所有文件都有编码格式,一般有

ISO8859-1西欧编码,不适应中文

GBK和utf-8,使用于中文和英文

public class IOTest {
    public static void main(String[] args) {
        IOTest ioTest=new IOTest();
        try {
            ioTest.testInputStreamReader("E:\\Desktop\\笔记\\java待探究.md");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 转换输入流
     * @throws Exception
     */
    public void testInputStreamReader(String inPath) throws Exception{
        FileInputStream fs=new FileInputStream(inPath);
        InputStreamReader in=new InputStreamReader(fs,"UTF-8");
        char[] c=new char[100];
        int len=0;
        while ((len=in.read(c))!=-1){
            System.out.println(new String(c,0,len));
        }
        in.close();
        fs.close();
    }
}

转换输出流也一样,参考前面代码举一反三(OutputStreamWriter)

四、标准输入输出流

System.in和System.out分别代表了系统标准的输入输出设备,默认键盘和显示器

System.in的类型是InputStream

System.out的类型是PrintStream,

public class IOTest {
    public static void main(String[] args) {
        IOTest ioTest=new IOTest();
        try {
            ioTest.testSystemIn();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 标准输入流
     * 程序功能:
     *      将键盘输入流的内容写入到abc.txt文件中,输入finish结束输入
     */
    public void testSystemIn() throws Exception{
        InputStreamReader isr=new InputStreamReader(System.in);
        BufferedReader br=new BufferedReader(isr);
        BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\abc.txt"));
        String str="";
        while ((str=br.readLine())!=null){
            if(str.equals("finish")){
                break;
            }
            bw.write(str);
        }
        bw.flush();
        bw.close();
        br.close();
        isr.close();
    }
}

五、简单了解流(打印流、数据流)

开发中比较少用到,简单了解即可

字节打印流 PrintStream,字符打印流 PrintWriter,其输出不会抛出异常 ,都有自动flush功能

数据输出流 DataOutputStream,数据输入流 DataInputStream

六、对象流

ObjectInputStream和ObjectOutputStream,用于存储读取对象的处理流。强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。

**序列化和反序列化:**java对象流在网络传输中是以二进制传输的,使用序列化和反序列化可以使得对象转化成二进制的字节流,使其能在网络中中传输,最后在另一端将流通过反序列化重新恢复为对象。

//IOTest.java
public class IOTest {
    public static void main(String[] args) {
        IOTest ioTest=new IOTest();
        try {
            ioTest.testSerialize();
            ioTest.testDeserialize();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void  testSerialize() throws Exception{
        ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\abc.txt"));
        Person person=new Person();
        person.name="yuec1998";
        person.age=21;
        out.writeObject(person);
        out.flush();
        out.close();
    }
    public void testDeserialize() throws Exception{
        ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\abc.txt"));
        Person person=(Person)in.readObject();
        System.out.println(person.name+":"+person.age);
    }
}
//Person.java
public class Person implements Serializable {
    public static final long serialVersionUID=1L;
    String name;
    Integer age;
}

七、随机存取流

RandomAccessFile类支持“随机访问“的方式,程序可以直接跳转到文件的任意地方来读写文件

long getFilePointer():获取文件记录指针的当前位置

void seek(long pos):将文件记录指针定位到pos位置

public class IOTest {

    public static void main(String[] args) {
        IOTest ioTest=new IOTest();
        try {
            ioTest.testRandomAccessFileRead("E:\\abc.txt");
            ioTest.testRandomAccessFileWrite("E:\\abc.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 随机读
     * @param inPath
     * @throws Exception
     */
    public void testRandomAccessFileRead(String inPath) throws Exception{
        //参数一:读写文件的路径
        //参数二:访问模式(r:只读 rw:打开以便读写)
        RandomAccessFile ra=new RandomAccessFile(inPath,"r");
        ra.seek(5);//指针
        byte[] b=new byte[1024];
        int len =0;
        while ((len=ra.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
        ra.close();
    }

     /**
     * 随机写
     * @param outPath
     * @throws Exception
     */
    public void testRandomAccessFileWrite(String outPath) throws Exception{
        RandomAccessFile ra=new RandomAccessFile(outPath,"rw");
        ra.seek(0);
        /**
         * 设置写的起始点,0表示文件内容的开头,如果在开头或中间则会发生内容覆盖
         * ra.seek(0);
         * 文件末尾追加
         * ra.seek(ra.length());
         */
        ra.write("aaa11111".getBytes());
        ra.close();
    }
}

在这里插入图片描述

结束!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里东君~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值