【JavaEE】File、InputStream和OutputStream的使用

1.File

在计算机中目录结构如下:
在这里插入图片描述
File就表示一个目录或者一个普通文件

File表示目录
在这里插入图片描述
File表示普通文件
在这里插入图片描述
我们先来看File的构造方法:

构造器描述
File(File parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径
File(String parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(URI uri)通过uri来创建一个File 实例

但是通常都用File(String pathname)这个构造器来创建File对象,其他的构造器比较少用。

创建File实例:

public class CreateFileObject {
    public static void main(String[] args) {
        File file = new File("blog/dir/tmp.txt");
    }
}

File类常用的方法基本都在下面了:

返回类型方法名描述
String getParent()返回 File 对象的父目录文件路径
String getName()返回 FIle 对象的纯文件名称
String getPath()返回 File 对象的文件路径
String getAbsolutePath()返回 File 对象的绝对路径
String getCanonicalPath()返回 File 对象的修饰过的绝对路径
boolean exists()判断 File 对象描述的文件是否真实存在
boolean isDirectory()判断 File 对象代表的文件是否是一个目录
boolean isFile()判断 File 对象代表的文件是否是一个普通文件
boolean createNewFile()根据 File 对象,自动创建一个空文件。成功创建后返回 true
boolean delete()根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行
String[] list()返回 File 对象代表的目录下的所有文件名
File[] listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示
boolean mkdir()创建 File 对象代表的目录
boolean mkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录
boolean renameTo(File dest)进行文件改名
boolean canRead()判断用户是否对文件有可读权限
boolean canWrite()判断用户是否对文件有可写权限

补充一个文件路径的小知识:

.表示当前路径
..表示上级目录

mkdirs()、getName()、getParent()、getPath()、getAbsolutePath()、getCanonicalPath()的使用

目录结构:
在这里插入图片描述

代码:

public class MethodTest1 {
    public static void main(String[] args) throws IOException {
        File file = new File("io/src/blog/dir/./tmp");

        //创建dir目录并且会创建tmp这个目录
        file.mkdirs();

        //获取文件的名称
        String filename = file.getName();
        System.out.println("文件名->: " + filename);

        //获取父目录的相对路径
        String parent = file.getParent();
        System.out.println("父目录的相对路径->: " + parent);


        //获取相对路径
        String path = file.getPath();
        System.out.println("相对路径->: " + path);

        //获取绝对路径
        String absPath = file.getAbsolutePath();
        System.out.println("绝对路径->: " + absPath);

        //获取修饰后的绝对路径
        String absPathMod = file.getCanonicalPath();
        System.out.println("修饰后的绝对路径->: " + absPathMod);

    }
}

结果:

文件名->: tmp
父目录的相对路径->: io\src\blog\dir\.
相对路径->: io\src\blog\dir\.\tmp
绝对路径->: H:\gitee\IdeaProgram\JavaEE\io\src\blog\dir\.\tmp
修饰后的绝对路径->: H:\gitee\IdeaProgram\JavaEE\io\src\blog\dir\tmp

exists()、isFile()、isDirectory()、list()、listFiles()的使用

目录结构:
在这里插入图片描述
代码:

public class MethodTest2 {
    public static void main(String[] args) {
        File file = new File("io/src/blog/dir/./tmp");

        //判断文件是否存在
        boolean isExists = file.exists();
        System.out.println("文件是否存在->: " + isExists);

        //判断是否为普通文件,比如xxx.txt
        boolean isFile = file.isFile();
        System.out.println("是否为普通文件->: " + isFile);

        //判断是否是一个目录
        boolean isDirctory = file.isDirectory();
        System.out.println("是否为一个目录->: " + isDirctory);

        //列出这个目录下面所有的文件,以String表示
        String[] list = file.list();
        System.out.println("tmp目录下所有的文件->: " + Arrays.toString(list));


        //列出这个目录下面所有的文件,以File对象表示
        File[] files = file.listFiles();
        System.out.println("tmp目录下所有的文件->: " + Arrays.toString(files));
    }
}

结果:

文件是否存在->: true
是否为普通文件->: false
是否为一个目录->: true
tmp目录下所有的文件->: [a.txt, b.txt]
tmp目录下所有的文件->: [io\src\blog\dir\.\tmp\a.txt, io\src\blog\dir\.\tmp\b.txt]

canRead()、canWrite()、renameTo()、delete()的使用

代码:

public class MethodTest3 {
    public static void main(String[] args) throws IOException {
        File file = new File("io/src/blog/dir/./tmp");

        //判断是否可读
        boolean canRead = file.canRead();
        System.out.println("是否可读->: " + canRead);

        //是否可写
        boolean canWrite = file.canWrite();
        System.out.println("是否可写->: " + canWrite);

        //改名为file_tmp
        file.renameTo(new File("io/src/blog/dir/./file_tmp"));

        //删除下面的一个.txt后缀文件
        File removeFile = new File("io/src/blog/dir/./file_tmp/a.txt");
        boolean ret = removeFile.delete();
        System.out.println("是否删除成功->: " + ret);

    }
}

结果:

是否可读->: true
是否可写->: true
是否删除成功->: true

2.InputStream

InputStream可以认为是输入设备和内存(Memory)之间的一个流,而且数据流向是从输入设备(input device)内存(Memory)的。
在这里插入图片描述

我们创建了一个InputStream,就相当于创建了一个输入流对象,可以从输入设备上读数据到内存中。

InputStream官方声明:

public abstract class InputStream
extends Object
implements Closeable

常用的方法:

方法描述
abstract int read()从输入流读取一个字节(byte)的数据,并返回
int read(byte[] b )从输入流读取一些字节并存到b这个数组中
(读取多少个字节,取决于b数组的大小和文件中数据有多少)
int read(byte[] b, int off, int len)最多读取len个字节到b数组中,从指定数组下标开始
void close()关闭输入流,释放资源

因为InputStream是抽象类,所以我们还得找这个类的子类。
InputStream的子类比较多,这里以FileInputStream举例,即文件流,也是经常使用的一个流。

文件流的输入设备就是磁盘(disk),更具体一点就是文件(File)
在这里插入图片描述

FileInputStream的声明:

public class FileInputStream extends InputStream

FileInputStream常用的构造器:

构造器描述
FileInputStream(File file)根据File对象创建一个输入流
FileInputStream(String name)根据文件名创建一个输入流

下面是文件中的数据:

文件:filetest.txt

abcdefghijk

read()方法使用:

public static void test1() {
    InputStream inputStream = null;
    try {
        //创建FileInputStream输入流对象
        inputStream = new FileInputStream("io/filetest.txt");

        //读取一个字节的数据,返回-1表示到达文件末尾
        int data = inputStream.read();

        //输出
        System.out.println("data->: " + data);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //关闭资源
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果:

data->: 97

int read(byte[] b)方法使用

public static void test2() {
   InputStream inputStream = null;
   try {
       //创建FileInputStream输入流对象
       inputStream = new FileInputStream("io/filetest.txt");

       //读取数据到bytes数组中,返回读取到的字节数,返回-1表示到文件末尾,
       byte[] bytes = new byte[32];
       int ret = inputStream.read(bytes);

       //输出
       System.out.println(Arrays.toString(bytes));

   } catch (IOException e) {
       e.printStackTrace();
   } finally {
       //关闭资源
       try {
           inputStream.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

}

结果:

[97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

int read(byte[] b, int off, int len)方法使用:

public static void test3() {
    InputStream inputStream = null;
    try {
        //创建FileInputStream输入流对象
        inputStream = new FileInputStream("io/filetest.txt");

        //读取数据写到bytes数组指定的位置
        byte[] b = new byte[32];
        int ret2 = inputStream.read(b, 10, 10);

        //输出
        System.out.println(Arrays.toString(b));

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //关闭资源
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

结果:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

不知道你有没有觉得上面的try…catch…finally这种写法有点繁琐,说白了就是丑😣。
上面的写法跟下面的等价。

    public static void test() throws IOException {
        try (InputStream inputStream = new FileInputStream("io/filetest.txt")) {
            //读取一个字节的数据,返回-1表示到达文件末尾
            int data = inputStream.read();

            //输出
            System.out.println("data->: " + data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这种写法叫,try-with-resource可以自动帮助我们释放资源,即自动调用close()方法。

  • 当发生异常时,能自动调用close()方法,帮助我们释放资源。
    但是并不是所有类都能这样用,只有实现AutoCloseable或者Closeable接口的类,并且重写close()方法才能用这种语法。

AutoCloseableCloseable的关系:

public interface Closeable
extends AutoCloseable

底层释放资源伪代码如下:

AutoCloseable o = (AutoCloseable)inputStream;
o.close();
  • 这里只是伪代码,帮助我们理解,而底层实现跟这个不一样。

3.OutputStream

OutputStream是从内存(Memory)输出设备(output device)的一个流,且流向从内存到输出设备的。

在这里插入图片描述

官方声明:

public abstract class OutputStream
extends Object
implements Closeable, Flushable

常用的方法:

方法描述
abstract void write(int b)写入低八位的数据,后24位的数据是不会写入的
void write(byte[] b)将b数组中的全部字节写入到文件中
void write(byte[] b, int off, int len)从off这个位置开始,将数组b的字节写到文件中
void close()关闭输出流,释放资源
void flush()刷新内存中的缓冲区,把缓冲区的数据写入文件中

调用输出设备flush()方法执行的过程如下:
在这里插入图片描述

OutputStream也是抽象类,最常用的子类是FileOutputStream(文件输出流)。
在这里插入图片描述

FileOutputStream常用的构造器:

构造器描述
FileOutputStream(File file)根据File对象创建一个输出流
FileOutputStream(String name)根据文件名创建一个输出流
FileOutputStream(File file, boolean append)根据File对象创建一个输出流
并且指定是否可追加
FileOutputStream(String name, boolean append)根据文件名创建一个输出流
并且指定是否可追加

example

public class OutputStreamTest {
    public static void main(String[] args) throws IOException {
        //文件路径
        String path = "./io/filetest.txt";

        //创建文件输出流对象
        try ( FileOutputStream fileOutputStream = new FileOutputStream(path)) {
            //调用wirite(int b)方法, 将
            fileOutputStream.write(1);

            //调用write(byte[] b)方法,将byte数组里的每个字节写入文件
            fileOutputStream.write(new byte[]{2, 3, 4});
        }
    }
}

文件内容:
在这里插入图片描述
在idea中显示的内容:
在这里插入图片描述
ascii码表:
在这里插入图片描述

  • 因为文件是二进制文件,以字节为单位,1对应了中的SOH
    2对应STX,3对应ETX,4对应EOT

  • 记事本是不会显示控制字符的,会用其他的字符代替,所以就出现了乱码。而在idea中打开就可以显示每个字节对应的字符。

追加的方式打开文件并写入byte数组:

public class OutputStreamTest2 {
    public static void main(String[] args) {
        appendConstructorTest();
    }

    public static void appendConstructorTest() {
        //路径
        String path = "io/filetest.txt";

        //以追加的方式打开文件输出流
        try (FileOutputStream fileOutputStream = new FileOutputStream(path, true)) {

            //把byte数组写入文件
            fileOutputStream.write(new byte[]{5, 6, 7});
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果:
在这里插入图片描述


寄语
清风拂来头发飞扬,指间跳动理想锋芒。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值