文件的简单操作-字节流-字符流

时间:2021-02-04 21:00:46

File类

我们都知道Java是一个面向对象的编程语言,当我们要对一个文件进行操作的时候,我们也应该将文件进行封装,在Java里,我们可以把文件封装成一个File对象,通过调用File的类方法,实现该文件的操作。

首先看看File类的构造方法:

构造方法

  1. File(String pathname)

      通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 
      当你创造一个File对象的时候,输入了一个String类对象pathname,pathname将会被系统解析为一个抽象路径名
    
  2. File(String parent, String child)

      根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 
      这个构造方法前后输入的两个字符串一般代表一个父目录和一个子目录,并根据父抽象路径名解析子抽象路径名,如我想输入一个文件的绝对路径为“d://java/test/a.txt”,我可以将他分为父目录"d://java"和子目录“test/a.txt”
    
  3. File(File parent, String child)

    根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 
      File对象parent其实就是作为传递父抽象路径名的一个参数,再将字符串child解析为子抽象路径名,使用方式和(2)中相同
    

功能介绍

  1. 创建功能:

    A:创建文件
            public boolean createNewFile():
            当文件不存在的时候,创建文件,如果文件存在,不创建
                *注意:文件不存在可以创建,但是文件所在的路径要是不存在,会抛出一个异常:
                java.io.IOException: 系统找不到指定的路径
    
    B:创建目录
            public boolean mkdir():
            如果目录不存在,创建这个目录,如果文件存在,不创建
    
    
            public boolean mkdirs():
            如果目录不存在,创建这个目录,如果目录存在,不创建
            即使父目录不存在,也可以连父目录一起创建。
    
  2. 删除功能:

    public boolean delete():
    既可以删除文件,又可以删除目录。
    
    注意事项:
            A:Java程序的删除不走回收站。
            B:如果目录内还有内容就不能删除。
    
  3. 判断功能

      public boolean isDirectory():是否是目录
      public boolean isFile():是否是文件
      public boolean exists():是否存在
      public boolean canRead():是否可读
      public boolean canWrite():是否可写
      public boolean isHidden():是否隐藏
    
  4. 获取功能

     public String getAbsolutePath():获取绝对路径
     public String getPath():获取相对路径
     public String getName():获取名称
     *路径问题:
            A:绝对路径  就是以盘符开始的路径(d:\\test\\aaa\\b.txt)
            B:相对路径  就是不以盘符开始的路径(a.txt)
                        一般都是相对应当前的项目而言的。
    

字节流及字节高效流

当我们想要把一个文件上的数据读取或者把数据写入该文件的话,我们需要用到java里的I/O流,I/O流从数据类型上划分的话,有字节流和字符流,二者各有优劣,我们先来介绍一下字节流:

字节流

字节流按照输入流来分有InputSteam和OutputStream,但是这两个都是抽象类,不能被实例化,我们一般使用他们的子类:FileInputStream和FileOutputStream。

FileInputStream

  1. 构造方法

    FileInputStream(File file) 
    通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
    
    FileInputStream(String name) 
    通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。 
    
  2. 功能介绍

     int read() 
              从此输入流中读取一个数据字节。 
    
     int read(byte[] b) 
              从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 
    
     int read(byte[] b, int off, int len) 
              从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 
    
  3. 通过InputStream来读一个文件

一次读一个字节

FileInputStream fis = new FileInputStream("a.txt");//相对路径,我的这个工程根目录下正好有个a.txt文件
int by;
while((by = fis.read())!=-1){
    System.out.print((char)by);
    }   
//3.释放资源
fis.close();

一次读一个数组

FileInputStream fis = new FileInputStream("a.txt");
byte by[] = byte[1024];//使用一个byte数组来存放读取的数据一般来说数组的大小得是2的整数倍
int len;
while((len = fis.read(by,0,len))!=-1){
    System.out.print((char)by);
    }
//3.释放资源
fis.close();

FileOutputStream

构造和InputStream很像所以直接讨论其功能
但是有一点值得注意:
构造一个输出流对象的时候,如果指定的路径上没有这个文件,则会自动创建这个文件,而输入流则不行
1. 功能

void write(byte[] b) 
 将 b.length 个字节从指定 byte 数组写入此文件输出流中。 

 void write(byte[] b, int off, int len) 
 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 

 void write(int b) 
 将指定字节写入此文件输出流。 

2. 通过FileOutoutStream来将数据写入一个文件

FileOutputStream fos = new FileOutputStream("b.txt");
        //write(int b) :一次写一个字节
        fos.write(97);

        //write(byte[] b, int off, int len) :一次写一个字节数组的一部分
        byte[] byf = {97,98,99,100};
        fos.write(byf, 1, 2);

        //3.关流
        fos.close();

使用字节流复制一个文件

        //1.封装数据源和目的地
        FileInputStream fis = new FileInputStream("Test.java");
        FileOutputStream fos= new FileOutputStream("f.java");

        //一次读写一个字节数组
        byte[] byf = new byte[1024];
        int len;
        while ((len=fis.read(byf))!=-1) {
            fos.write(byf, 0, len);
        }

        //3.关流
        fos.close();
        fis.close();

字节缓冲区流

字节缓冲区流也叫高效流

  • BufferedInputStream
  • BufferedOutputStream

流可以分为
低级流: 基本的流,可以直接操作文件。
高级流:是操作基本流的流。
BufferedInputStream和BufferedOutputStream是操作基本流的流
当我们构造一个高效流的时候需要输入一个基本流作为参数

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutInputStream(new FileOutputStream("a.txt"));

另外:字节缓冲区流的方法和普通字节流的用法完全一样

字符流

顾名思义,字节流是一次传输一个字节的流,字符流就是一次传输一个字的流
字符流根据输入输出分为Reader和Writer,同样,这两个类也都是抽象类,我们一般使用它的子类来使用字符流的操作

将字节流转化为字符流

写入数据,把字节输出流转换为字符输出流(不指定码表)
     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
     把字节输出流转换为字符输出流(指定码表)
     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "GBK");
     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8"); 

 读取数据, 把字节输入流转换为字符输入流(不指定码表)
 InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));
 把字节输入流转换为字符输入流(指定码表)
 InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"), "GBK");

FileWriter和FileReader

使用上面的方法来操作字符流的话,确实有些复杂,所以我们一般使用它的子类FileWriter和FileReader来对一个File对象进行读写
1. 构造方法

 FileWriter(File file) 
 FileWriter(String fileName) 
 FileReader(File file) 
 FileReader(String fileName)

2. 功能
读功能

public int read() 读取单个字符。
public int read(char[] cbuf) 将字符读入数组。
public abstract int read(char[] cbuf,int off,int len) 将字符读入数组的某一部分。 

写功能

write(int c) 一次写入一个字符
write(char[] cbuf)一次写入一个字符数组
write(char[] cbuf, int off,int len)一次写入一个字符数组并可以指定起始位置和长度
write(String str)一次写入一个字符串
write(String str,int off,int len)一次写入一个字符串,并可以指定起始位置和长度

值得注意的是:字符流每写入一个数据,最好将其刷新——flush(),不需要用到字符流的时候需要对字符流的空间进行释放——close()

字符缓冲区流

windows系统下的换行符是“/r/n”,Linux是”\n”,Mac是”\r”
如果在windows下写入换行符的话的话的输入“/r/n”,而Linux则是“\n”,这样的写入方式通用性不强
对应字符流的高效流——字符缓冲区流里定义了readLine()方法和write()方法,它们会根据操作系统的不同自动写入不同的换行符,提高了通用性
我们来用代码演示一下如何用字符缓冲流复制一个文件

    //封装数据源和目的地
        BufferedReader br = new BufferedReader(new FileReader("InputStreamReaderDemo.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("CopyFile.java"));

        //读取一行写一行
        String line;
        while ((line = br.readLine())!=null) {
            //System.out.println();
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();