Java中的File类与IO流(File类的基本使用、字节流、字符流、转换流、java文件拷贝)

文章目录

  • 1. File类的基本使用
    • 1.1 文件操作
      • 1.1.1 创建新文件
      • 1.1.2 删除文件
      • 1.1.3 路径分隔符
    • 1.2 目录操作
      • 1.2.1 取得父路径与父File对象
      • 1.2.2 创建目录
    • 1.3 取得文件或者目录的信息(大小、最后修改日期)
  • 2. IO流
    • 2.1 流的操作过程
    • 2.2 字节流
      • 2.2.1 字节的输出流OutputStream
        • 2.2.1.1 输出方法
      • 2.2.2 字节的输入流InputStream
        • 2.2.2.1 输入方法
    • 2.3 字符流
      • 2.3.1 字符输出流Writer
      • 2.3.2 字符输入流Reader
    • 2.3 字节流与字符流
    • 2.3 转换流
    • 2.4 文件拷贝

1. File类的基本使用

File类即可描述真实文件,也可描述文件夹(目录)
File类是java.io包中唯一一个与文件本身操作(创建、删除、取得信息)有关,与文件内容无关的程序类
File类的常用构造方法:

 public File(String pathname); //pathname:文件的绝对路径
 public File(String parent,String child);//parent:文件的父路径 child:文件的子路径

1.1 文件操作

1.1.1 创建新文件

public boolean createNewFile() throws IOException 
import java.io.File;
import java.io.IOException;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象,此处的路径为绝对路径
        File file = new File("C:\\Users\\79024\\Desktop\\java.txt");
        try {
     
            file.createNewFile();
        } catch (IOException e) {
     
            e.printStackTrace();
        }
    }
}

Java中的File类与IO流(File类的基本使用、字节流、字符流、转换流、java文件拷贝)_第1张图片

1.1.2 删除文件

public boolean delete();
import java.io.File;
import java.io.IOException;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:\\Users\\79024\\Desktop\\java.txt");
        //判断文件是否存在 此方法也可判断文件夹是否存在
        if(file.exists())
        {
     
            file.delete();
        }else{
     
            try {
     
                file.createNewFile();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
    }
}

1.1.3 路径分隔符

路径分隔符:File.separator用于替换路径中的\

import java.io.File;
import java.io.IOException;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:"+File.separator+"Users"+
                File.separator+"79024"+File.separator+
                "Desktop"+ File.separator+"java.txt");
        try {
     
            file.createNewFile();
        } catch (IOException e) {
     
            e.printStackTrace();
        }
    }
}

1.2 目录操作

1.2.1 取得父路径与父File对象

public String getParent();
public File getParentFile();

1.2.2 创建目录

无论有多少级父目录都会一次性创建public boolean mkdirs();

import java.io.File;
import java.io.IOException;

public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:"+File.separator+"Users"+
                File.separator+"79024"+File.separator+
                "Desktop"+ File.separator+
                "www"+File.separator+"java"+File.separator+"java.txt");
        //取得父路径对象
        File parentFile = file.getParentFile();
        //如果父路经不存在 -- 创建父路径
        //父文件即C:\Users\79024\Desktop\www\java
        if(!parentFile.exists()){
     
        //无论有多少级父目录都一次性创建
            parentFile.mkdirs();
        }
        //如果文件存在 删除
        if(file.exists()){
     
            file.delete();
        }else{
     
            try {
     
                file.createNewFile();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
    }
}

1.3 取得文件或者目录的信息(大小、最后修改日期)

public boolean isFile(); //判断路径是否是文件
public long length();//取得文件大小
public long lastModified();//取得最后修改日期
import java.io.File;
import java.util.Date;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:" + File.separator + "Users" +
                File.separator + "79024" + File.separator +
                "Desktop" + File.separator  + "happy.png");
        //如果路径存在 且 路径是一个文件
        //输出文件的大小(字节)以及最后的修改时间(1970年开始的时间戳)
        if(file.exists()&&file.isFile()){
     
            System.out.println(file.length());
            System.out.println(file.lastModified());
            //最后的修改时间以能看懂的形式显示
            System.out.println(new Date(file.lastModified()));
        }
    }
}

对目录的操作:

public boolean isDirectory();//判断路径是否是目录
public File[] listFile();//列举一个目录的全部组成
import java.io.File;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:" + File.separator + "Users" +
                File.separator + "79024" + File.separator +
                "Desktop");
        //如果路径存在且路径是一个目录
        //列举该目录下的文件和目录
        if(file.exists()&&file.isDirectory()){
     
        	//只展开一层
            File[] files = file.listFiles();
            for(File file1:files){
     
                System.out.println(file1);
            }
        }

    }
}

如果目录的全部组成下还有目录递归展示:

import java.io.File;
public class Test {
     
    public static void main(String[] args) {
     
        //取得File对象
        File file = new File("C:" + File.separator + "Users" +
                File.separator + "79024" + File.separator +
                "Desktop");
        listAllFiles(file);
    }
    public static void listAllFiles(File file){
     
        /**
         * 如果路径存在且路径是一个文件直接输出
         */
        if(file.exists()&&file.isFile()){
     
            System.out.println(file);
        }else{
     
            //此时file对象为目录
            File[] files = file.listFiles();
            for(File file1:files){
     
                listAllFiles(file1);
            }
        }
    }
}

IO相关处理属于阻塞式耗时操作。一般放在子线程中进行

import java.io.File;
public class Test {
     
    public static void main(String[] args) {
     
        System.out.println("主线程开始");
        new Thread(()->{
     
            //取得File对象
            File file = new File("C:" + File.separator + "Users" +
                    File.separator + "79024" + File.separator +
                    "Desktop");
            System.out.println("遍历文件开始...");
            long start = System.currentTimeMillis();
            listAllFiles(file);
            long end = System.currentTimeMillis();
            System.out.println("遍历文件结束,共耗时"+(end-start));
        }).start();
        System.out.println("主线程结束");
    }
    public static void listAllFiles(File file){
     
        /**
         * 如果路径存在且路径是一个文件直接输出
         */
        if(file.exists()&&file.isFile()){
     
            System.out.println(file);
        }else{
     
            //此时file对象为目录
            File[] files = file.listFiles();
            for(File file1:files){
     
                listAllFiles(file1);
            }
        }
    }
}

2. IO流

流的分类:

  1. 字节流(byte):InputStream、OutputStream
  2. 字符流(char):Reader、Write
    字节流与字符流的区别:
    字节流是原生操作,字符流是处理后的操作
    一般使用字节流(无论是网络传输还是磁盘的数据保存都是字节流),只有处理中文的文本时才会用到字符流

2.1 流的操作过程

无论是字节流还是字符流,操作流程几乎一样,以文件操作为例:
1.取得File对象
2.取得File对象的输入、输出流
3.进行数据的读取或写入
4.关闭流(close)
IO操作属于资源处理,所有资源处理(IO、数据库、网络)使用后都必须关闭

2.2 字节流

2.2.1 字节的输出流OutputStream

//抽象类
public abstract class OutputStream implements Closeable, Flushable
Closeable:public void close() throws IOException;
Flushable:void flush() throws IOException;

2.2.1.1 输出方法

public void write(byte[] b)throws IOException; //将指定的字节数组全部输出
public void write(byte[] b,int offset,int len)throws IOException;//将部分字节数组输出
public abstract void write(int b)throws IOException;//输出单个字节

要进行文件内容的输出:使用FileOutputStream子类

public FileOutputStream(File file) throws FileNotFoundException              //文件内容的覆盖
public FileOutputStream(File file, boolean append)throws FileNotFoundException //文件内容的追加

当使用FileOutoutStream进行文件内容输出时,只要文件的父路径存在,FileOutputStream会自动创建文件

import java.io.*;
public class Test {
     
    public static void main(String[] args) throws IOException {
     
        //1.取得File对象
        File file = new File("C:"+File.separator+"Users"+File.separator+
                "79024"+File.separator+"Desktop"+File.separator+"java.txt");
        //---------------------------------------------------------- 以下内容可写可不写
        //如果文件不存在 则创建
        if(!file.exists()){
     
            try {
     
                file.createNewFile();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
        //--------------------------------------------------------------
        //2.取得File的输出 文件内容的追加
        OutputStream out = new FileOutputStream(file,true);
        //3.进行数据的输出
        String msg ="好好学习\n";
        out.write(msg.getBytes());
        //4.关闭流
        out.close();
    }
}

2.2.2 字节的输入流InputStream

public abstract class InputStream implements Closeable 
Closeable:public void close() throws IOException;

2.2.2.1 输入方法

public int read(byte b[]) throws IOException;  //读取数据到字节数组b中
    1.返回b的长度:当被读取的数据大小>字节数组大小 返回字节数组大小
    2.返回一个大于0的数但是小于b长度: 被读取的数据大小<字节数组大小 返回真正读取的个数
    3.返回-1: 数据读取完毕
    可以将被读取的数据看作稀饭,将字节数组的大小看作勺子
public abstract int read() throws IOException;//读取单个字节    
import java.io.*;
public class Test {
     
    public static void main(String[] args) throws IOException {
     
        //1.取得File对象
        File file = new File("C:"+File.separator+"Users"+File.separator+
                "79024"+File.separator+"Desktop"+File.separator+"java.txt");
        //2.取得输入流
        InputStream in  = new FileInputStream(file);
        //3.进行数据的写入 将数据写入data数组中
        byte[] data = new byte[1024];
        int result = in.read(data);
        System.out.println(result);
        //将字节数组转为字符串
        System.out.println(new String(data,0,result));
        //4.关闭流
        in.close();
    }
}

2.3 字符流

2.3.1 字符输出流Writer

无论是字节输出流还是字符输出流都是write方法,但是字符输出流多了一个传入String对象的方法public void write(String str) throws IOException

import java.io.*;
public class Test {
     
    public static void main(String[] args) throws IOException {
     
        //1.取得File对象
        File file = new File("C:" + File.separator + "Users" + File.separator +
                "79024" + File.separator + "Desktop" + File.separator + "java.txt");
        //2.取得输出流
        Writer writer = new FileWriter(file,true);
        //3.写入数据
        String str = "好好学习";
        writer.write(str);
        //4.关闭流
        writer.close();
    }
}

2.3.2 字符输入流Reader

Reader类中没有方法可以直接读取字符串,只能通过字符数组来读取public int read(char b[]) throws IOException; //读取数据到字符数组b中

import java.io.*;
public class Test {
     
    public static void main(String[] args) throws IOException {
     
        //1.取得File对象
        File file = new File("C:" + File.separator + "Users" + File.separator +
                "79024" + File.separator + "Desktop" + File.separator + "java.txt");
        //2.取得输出流
        Reader reader = new FileReader(file);
        //3.数据写入
        char[] data = new char[1024];
        int result = reader.read(data);
        System.out.println(result);
        System.out.println(new String(data,0,result));
        //4.关闭流
        reader.close();
    }
}

2.3 字节流与字符流

从实际开发来讲,字节流优先考虑,只有处理中文时才会考虑字符流
所有字符流操作,无论是写入还是输出,数据都先保存在缓存中,如果不关闭流,则数据不会写入或者读出

2.3 转换流

字节流–>字符流
转换流用于将底层的字节流转为字符流供子类w使用

OutputStreamWriter:字节输出流--->字符输出流
InputStreamReader:字节输入流--->字节输出流
import java.io.*;
public class Test{
     
    public static void main(String[] args) throws IOException {
     
        //1.取得文件对象
        File file = new File("C:"+File.separator+"Users"+File.separator+
        "79024"+File.separator+"Desktop"+File.separator+"java.txt");
       //2.取得文件的输出流
        OutputStream outputStream = new FileOutputStream(file);
        //字节流--->字符流
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
        //3.进行数据的输出
        outputStreamWriter.write("好好学习");
        //4.关闭流
        outputStreamWriter.close();
    }
}

2.4 文件拷贝

import java.io.*;
public class Test{
     
     public static void main(String[] args) throws IOException {
     
         String sourceFilePath = "C:\\Users\\79024\\Desktop\\哈.png";
         String destFilePath="C:\\Users\\79024\\Desktop\\嘿.png";
         System.out.println( copyFile(sourceFilePath,destFilePath));
     }

     /**
      * 文件拷贝
      * @param sourceFilePath
      * @param destFilePath
      * @return
      */
     public static boolean copyFile(String sourceFilePath,String destFilePath) throws IOException {
     
         //1.取得File对象
         File sourceFile = new File(sourceFilePath);
         File destFile = new File(destFilePath);
         //2.取得输入输出流
         /**
          * 由于是将源文件拷贝到目标文件中
          * 即需要先将源文件中的数据输入到缓冲区中 ,然后将数据输出到目标文件
          * 所以源文件对应字节输入流
          * 目标文件对应字节输出流
          */
         InputStream in = new FileInputStream(sourceFile);
         OutputStream out = new FileOutputStream(destFile);
         //3.数据的输入、输出
         long start = System.currentTimeMillis();
         int len = 0;
         /**
          * in.read() 读取单个字节  该方法有返回值
          * 返回值==-1即数据读取完毕
          * write(len)输出单个字节
          */
         while ((len = in.read()) != -1) {
     
             out.write(len);
         }
         long end = System.currentTimeMillis();
         System.out.println("文件拷贝耗时:" + (end - start) + "毫秒");
         in.close();
         out.close();
         return true;
     }
 }

由于一个字节一个字节的读取太过于耗时,所以修改输入方式,即增加缓冲区:

import java.io.*;
public class Test{
     
     public static void main(String[] args) throws IOException {
     
         String sourceFilePath = "C:\\Users\\79024\\Desktop\\哈.png";
         String destFilePath="C:\\Users\\79024\\Desktop\\嘿.png";
         System.out.println( copyFile(sourceFilePath,destFilePath));
     }

     /**
      * 文件拷贝
      * @param sourceFilePath
      * @param destFilePath
      * @return
      */
     public static boolean copyFile(String sourceFilePath,String destFilePath) throws IOException {
     
         //1.取得File对象
         File sourceFile = new File(sourceFilePath);
         File destFile = new File(destFilePath);
         //2.取得输入输出流
         /**
          * 由于是将源文件拷贝到目标文件中
          * 即需要先将源文件中的数据输入到缓冲区中 ,然后将数据输出到目标文件
          * 所以源文件对应字节输入流
          * 目标文件对应字节输出流
          */
         InputStream in = new FileInputStream(sourceFile);
         OutputStream out = new FileOutputStream(destFile);
         //3.数据的输入、输出
         long start = System.currentTimeMillis();
         int len = 0;
         /**
          * in.read() 读取单个字节  该方法有返回值
          * 返回值==-1即数据读取完毕
          * write(len)输出单个字节
          */
         byte[] data = new byte[1024];
         while ((len = in.read(data)) != -1) {
     
             out.write(data,0,len);
         }
         long end = System.currentTimeMillis();
         System.out.println("文件拷贝耗时:" + (end - start) + "毫秒");
         in.close();
        out.close();
         return true;
     }
 }

你可能感兴趣的:(Java,Java学习,File类的基本使用,字节流,字符流,转换流,java文件拷贝)