IO基本操作,看这篇就够了

I/O基本操作

File类
方法返回值描述
canExecute()boolean是否可执行
createNewFile()boolean原子性的检查该文件是否存在,不存在则创建。
如果文件不存在正常创建返回true
如果文件已经存在返回false
delete()boolean删除文件夹或文件,如果删除文件夹,文件夹必须为空才能删除
getParent()String返回抽象路径名的父级,如果未命名父目录,返回null
getPath()String将抽象路径名转换成路径字符串
getTotalSpace()long返回命名的区域总空间
list()String[]返回文件夹或文件的抽象路径名
如果抽象路径名不是文件夹,方法返回null
static listRoots() File[]返回文件的根目录
mkdirboolean创建抽象路径名的目录
mkdirsboolean创建抽象路径名的文件夹,包含任意不存在的路径
getAbsolutePath()
 public String getAbsolutePath()
  • 如果抽象路径名已经是绝对路径,直接调用 getPath返回

  • 如果抽象路径名是空的,返回当前用户路径,有系统的user.dir配置

  • 否则依赖系统的方式解析

private static void getAbsolutePath(){
	File file = new File("/tmp/1.txt");
	System.out.println(file.getAbsolutePath());
	file.renameTo(new File("/tmp/a.txt"));
	System.out.println(file.getAbsolutePath());
}
输出:
/tmp/1.txt
/tmp/1.txt

注意:以上代码输出!!!

listFiles(FileFilter filter)
public File[] listFiles(FileFilter filter)

返回符合FileFilter中accept方法的File类集合。

package j2ee.java.io.file;

import java.io.File;
import java.io.FileFilter;

/**
 * @Description
 * @Author lmn
 * @Date 2023/6/16 15:48
 */
public class TestFileFilter {
    public static void main(String[] args) {
        // 这样调用会编译不过,内部类不能在static中使用
//        File file = new File("/tmp");
//        file.listFiles(new MyFileFilter());
        TestFileFilter filter = new TestFileFilter();
        filter.run();
    }
    public void run(){
        File file = new File("/tmp");
        File[] files = file.listFiles(new MyFileFilter());
        if(null != files && files.length > 0){
            for (File file1 : files) {
                System.out.println(file1.getName());
            }
        }
    }

    /**
     * 内部类
     */
    class MyFileFilter implements FileFilter {

        @Override
        public boolean accept(File pathname) {
            return pathname.getName().endsWith("txt")?true:false;
        }
    }
}
public class TestFileFilter {
    public static void main(String[] args) {
        TestFileFilter filter = new TestFileFilter();
        filter.run();
    }
    public void run(){
        File file = new File("/tmp");
//        File[] files = file.listFiles(new MyFileFilter());
        // 匿名内部类
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith("txt")?true:false;
            }
        });
        if(null != files && files.length > 0){
            for (File file1 : files) {
                System.out.println(file1.getName());
            }
        }
    }
}

流的分类:

  • 按照方向分类:输入流和输出流
  • 按照类型分类:字节流和字符流
  • 按照操作方式分类:节点流和过滤流
  • 转换流

注意:这几种分类是有交叉的,比如:字节输入流,字符输出流

学习流,我们先明确一个概念,什么是输入流,什么是输出流:

输入流和输出流都是相对程序来说的,比如读一个文件中的数据输出到控制台,这个过程是先读入文件到程序(使用输入流),程序再输出到控制台(使用输出流)。

所有的输入流都实现 InputStream,所有的输出流都实现 OutputStream.

IO中的所有流操作都会抛异常

输入流:InputStream
public class TestFileInputStream {
    public static void main(String[] args){
        FileInputStream fis = null;
        try{
            // 1. 创建一个文件输入流
            fis = new FileInputStream("/tmp/a.txt");
            // 2. 创建一个字节数组用来存储读取的信息
            byte[] buf = new byte[6];
            // 3. 使用len读取长度
            int len = 0;
            // 4. 循环读取数据 只要len>0就说明读取到元素,可以对元素进行操作
            while((len=fis.read(buf))>=0){
                // 5. 通过控制台输出数据
                System.out.write(buf);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 6. 读完之后关闭释放流资源
            try {
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

所有流都是这个基本的操作过程!!

上述的代码有个问题:a.txt中的数据是:

hello world
中国

输出为:

hello world
中国
��国

原因是:

在这里插入图片描述

输出123456,再继续读,

在这里插入图片描述

输出7891056,所以出现了上述的问题。

public class TestFileInputStream {
    public static void main(String[] args){
        FileInputStream fis = null;
        try{
            // 1. 创建一个文件输入流
            fis = new FileInputStream("/tmp/a.txt");
            // 2. 创建一个字节数组用来存储读取的信息
            byte[] buf = new byte[1024];
            // 3. 使用len读取长度
            int len = 0;
            // 4. 循环读取数据 只要len>0就说明读取到元素,可以对元素进行操作
            while((len=fis.read(buf))>=0){
                // 5. 通过控制台输出数据,必须说明输出的长度
                System.out.write(buf,0,len);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 6. 读完之后关闭释放流资源
            try {
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
输出流:OutputStream
public class TestFileOutputStream {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("/tmp/a.txt");
            byte[] buf = new byte[1024];

            fos = new FileOutputStream("/tmp/b.txt");

            int len = 0;
            // 这里 (len = fis.read(buf))要注意传参buf,自己写的时候忘记了
            while ((len = fis.read(buf))>0){
                fos.write(buf, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 注意这里要分开读,否则一个执行了出现异常,另一个就不执行了
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                if(fos!= null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
节点流

可以直接创建的流

过滤流:BufferedXXXStream

可以装饰节点流,增加相应的功能,不能直接创建流,是对传入流的装饰

BufferedInputStream(InputStream in)
 public static void main(String[] args) {

        FileOutputStream fos = null;
        DataOutputStream dos = null;
        FileInputStream fis = null;
        DataInputStream dis = null;
        try {
            fos = new FileOutputStream("/tmp/b.txt");
            // 如果希望存储基本数据类型,使用DataOutputStream,同样是过滤流
            dos = new DataOutputStream(fos);
            // 这时候txt中是字节数据
            dos.writeInt(1231231212);
            dos.writeInt(3142);
            dos.writeInt(111);
            dos.writeInt(333);
            dos.writeInt(33);

            fis = new FileInputStream("/tmp/b.txt");
            dis = new DataInputStream(fis);
            System.out.println( dis.readInt());
            System.out.println( dis.readInt());
            System.out.println( dis.readInt());
            System.out.println( dis.readLong());
            // 读到头,程序会报错
            System.out.println( dis.readInt());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null != fos) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
字节流: inputStream/outputStream

读取图片等可以用字节流

字符流:BufferedReader/PrintWriter

字符流用来读取字符数据,对于输入字符流而言,最为常用操作是使用BufferedReader

BufferedReader有个readLine()方法,一行一行读取数据。

public class TestReader {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("/tmp/a.txt"));
            String str = null;
            while ((str = br.readLine()) != null) {
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

写用PrintWriter,最好读取的时候都加上BufferedXXX缓存流,增加效率。

public class TestWriter {
    public static void main(String[] args) {
        BufferedReader reader = null;
        PrintWriter writer = null;
        try {
            reader = new BufferedReader(new FileReader("/tmp/a.txt"));
            String str = null;
            // 没有换行 需要在输出时加换行
//            writer = new BufferedWriter(new FileWriter("/tmp/b.txt"));
            writer = new PrintWriter(new BufferedWriter(new FileWriter("/tmp/b.txt")));
            while ((str =reader.readLine()) != null) {
                // BufferedWriter 加入换行
//                writer.write(str, 0, str.length());
//                writer.newLine();
                writer.println(str);
            };
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader!= null)  reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (writer!= null)  writer.close();
        }
    }
}
转换流

将字节流(inputStream/outputStream)转换成字符流(InputStreamReader, OutputStreamWriter)

public class TestSystemInputStreamReader {

    public static void main(String[] args) {
        // 把字节流转换成字符流
        BufferedReader  reader = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        try {
            while ((str = reader.readLine()) != null) {
                if (str.equals("exit")) break;
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

将标准字符流写到文件中

public class TestSystemOutputStreamWriter {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = null;
        try{
            // FileWriter --> BufferedWriter(缓存流)--> PrintWriter(字符流)
            pw = new PrintWriter(new BufferedWriter(new FileWriter("/tmp/b.txt")));
            String str = null;
            while ((str = reader.readLine()) != null){
                if (str.equals("exit")) break;
                pw.println(str);
            }
        }catch (IOException e) {
            e.printStackTrace();
        } finally{
            if (pw!= null){
                pw.close();
            }
            try{
                if (reader!=null){
                    reader.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
ObjectInputStream/ObjectOutputStream
public class TestObjectStream {
    public static void main(String[] args) {
        writeObj();
        readObj();
    }

    public static void writeObj() {
        Student student = new Student();
        student.name = "lmn";
        student.money = 1000.0;

        ObjectOutputStream  oos= null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("/tmp/b.txt"));
            oos.writeObject(student);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void readObj() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("/tmp/b.txt"));
            Student student = (Student) ois.readObject();
            System.out.println(student.name);
            System.out.println(student.money);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // 如果希望把对象写到硬盘(文件)中,这个对象必须实现Serializable接口
    static class Student implements Serializable{
        private String name;
        // transient修饰的属性,不会序列化到硬盘
        private transient double  money;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值