Blog Detail

  • Java打开文件的所有方式收录

    本文的主要内容是介绍几种常用的文件打开方式,可以解决实际项目开发中很多的文件打开场景

    基于环境变量user.dir找到文件位置

    基于ClassLoader找到文件的位置

    在IDEA中打开文件

    在Tomcat中打开文件

    基于Spring找到文件的位置

    基于Maven打开resources目录下的文件

    打开文件的一般思路

    确定文件位置

    使用java.io.File打开文件,使用InputStream、Reader载入文件流,或者OutputStream、Writer写出文件流

    内容导览

    user.dir

    ClassLoader

    IDEA

    Tomcat

    Spring加载文件

    读取resources下的文件

    user.dir

    dir系统属性是 JVM 启动的时候设置的,通常是 Java 虚拟机的调用目录,即执行 java 字节码所在的目录。

    如果存在包,那么“./”为包的上一级目录。如果是jar包,则“./”为当前jar包所在目录。

    对于Tomcat/jboss 容器,dir 是 %web容器目录%/bin/ 目录,因为这个目录就是我们启动 web 容器的地方。

    在Eclipse和IDEA,getProperty("user.dir")为工程的根目录

    public class OpenFileDemo {

    public static void main(String[] args) throws Exception {

    String userDir = System.getProperty("user.dir");

    System.out.println("当前程序(不含包名)运行所在目录: " + userDir); //D:\A03-Program\A-Programming\IDEA\boot

    }

    }

    在Tomcat容器中的user.dir为bin目录

    ClassLoader

    读取字节码路径下的文件

    类名.getResource(“资源名称”),返回URL

    绝对路径以 / 开头,从classpath 或 jar 包根目录下开始搜索;

    相对路径是相对当前class 所在的目录,允许使用 .. 或 . 来定位文件。

    类名.getClassLoader().getResourceAsStream(),返回InputStream。只能使用绝对路径,而且不用以 / 开头。

    这两种方式读取资源文件,不会依赖于dir,也不会依赖于具体部署的环境,是推荐的做法

    ClassLoader 不能读取太大的文件,它适合读取项目的配置文件

    ClassLoader加载字节码所在目录下的文件

    获取当前字节码文件的绝对路径

    import java.io.File;

    import java.net.URL;

    public class OpenFileDemo {

    public static void main(String[] args) throws Exception {

    //在静态方法中使用".class.getClassLoader()"获取类加载器

    String path = OpenFileDemo.class.getClassLoader().getResource("").getPath();//注意getResource("")里面是空字符串

    System.out.println(path); //输出:/D:/A03-Program/A-Programming/IDEA/boot/target/classes/

    //File file = new File(path + "aa.txt");

    new OpenFileDemo().test01();

    }

    public void test01() {

    //在普通方法中使用"this.getClass().getClassLoader()"获取类加载器

    URL resource = this.getClass().getClassLoader().getResource(""); //注意getResource("")里面是空字符串

    String path = resource.getPath();

    System.out.println(path);

    String filePath = URLDecoder.decode(path, "UTF-8"); //如果路径中带有中文会被URLEncoder,因此这里需要解码

    String fileName = "aa.txt";

    File file = new File(filePath + fileName);

    System.out.println(file.exists()); //true

    }

    }

    IDEA

    IDEA默认从项目根目录查找文件

    public static void readFile() throws Exception {

    //IDEA中还是以工程的根目录为相对文件的根目录

    //在项目的根目录下建立一个文件夹file,在其文件夹下建立文件hello.txt

    File file = new File("file/hello.txt");

    System.out.println("文件的绝对路径:" + file.getAbsolutePath());

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));

    byte[] buffer = new byte[1024];

    int read = in.read(buffer);

    System.out.println("文件内容:" + new String(buffer, 0, read, StandardCharsets.UTF_8));

    //Output:

    //文件的绝对路径:D:\E-DataProject\JSE\file\hello.txt

    //文件内容:This is a test text.

    }

    Tomcat

    获取Tomcat的运行目录

    new File(".").getAbsolutePath() 当前文件所在目录

    getSession().getServletContext().getRealPath("") 项目所在目录

    getProperty("catalina.home") Tomcat根目录

    getProperty("user.dir") Tomcat的bin目录,因为Tomcat是从改个目录启动的

    <%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>

    <%@ page import="java.io.File" %>

    PN

    <%

    File file01 = new File(".");

    pageContext.setAttribute("file01", file01.getAbsolutePath());

    File file02 = new File("./");

    pageContext.setAttribute("file02", file02.getAbsolutePath());

    File file03 = new File("../");

    pageContext.setAttribute("file03", file03.getAbsolutePath());

    pageContext.setAttribute("requestServerletPath", request.getSession().getServletContext().getRealPath(""));

    %>

    catalina.home: <%= System.getProperty("catalina.home") %>

    user.dir: <%= System.getProperty("user.dir") %>

    requestServerletPath: ${requestServerletPath}

    file01: ${file01}

    file02: ${file02}

    file03: ${file03}

    Spring加载文件

    import org.springframework.core.io.ClassPathResource;

    //加载resources/static/template目录下的文件

    ClassPathResource resource = new ClassPathResource("static/template/report_template.xlsx");

    File file = resource.getFile();

    import org.springframework.util.ResourceUtils;

    File rootPath = new File(ResourceUtils.getURL("classpath:").getPath()); //SpringBoot项目获取根目录的方式

    File templatePath = new File(rootPath.getAbsolutePath(),"/excel_template/userInfo.xlsx"); //加载resources/excel_template目录下的文件

    读取resources下的文件

    import org.springframework.core.io.ClassPathResource;

    import java.io.BufferedInputStream;

    import java.io.File;

    import java.io.InputStream;

    import java.net.URL;

    import java.net.URLDecoder;

    import java.nio.charset.StandardCharsets;

    public class OpenFileDemo {

    public static void main(String[] args) throws Exception {

    OpenFileDemo openFileDemo = new OpenFileDemo();

    openFileDemo.method01();

    openFileDemo.method02();

    openFileDemo.method03();

    openFileDemo.method04();

    openFileDemo.method05();

    openFileDemo.method06();

    openFileDemo.method07();

    }

    /**

    * getPath(): 直接通过文件名来获取路径

    * 使用单元测试@Test,获取的是Junit的jar包所在位置

    */

    public void method01() {

    URL resource = this.getClass().getClassLoader().getResource(""); //注意getResource("")里面是空字符串

    String path = resource.getPath();

    String filePath = URLDecoder.decode(path, StandardCharsets.UTF_8); //如果路径中带有中文会被URLEncoder,因此这里需要解码

    //打开resources/data/aa.txt下的文件

    File file = new File(filePath + "data/aa.txt");

    System.out.println(filePath + ": " +file.exists());

    }

    public void method02() {

    //打开resources/data/aa.txt下的文件

    URL resource = this.getClass().getClassLoader().getResource("data/aa.txt");

    String path = resource.getPath();

    String filePath = URLDecoder.decode(path, StandardCharsets.UTF_8); //如果路径中带有中文会被URLEncoder,因此这里需要解码

    File file = new File(filePath);

    System.out.println(filePath + ": " +file.exists());

    }

    /**

    * getFile():等价于getPath

    * 如果是文件路径的话getFile和getPath效果是一样的,如果是URL路径的话getPath是带有参数的路径。

    */

    public void method03() {

    //打开resources/data/aa.txt下的文件

    URL resource = this.getClass().getClassLoader().getResource("data/aa.txt");

    String path = resource.getFile();

    String filePath = URLDecoder.decode(path, StandardCharsets.UTF_8); //如果路径中带有中文会被URLEncoder,因此这里需要解码

    File file = new File(filePath);

    System.out.println(filePath + ": " +file.exists());

    }

    /**

    * getResourceAsStream: 直接获取到InputStream

    * 基于Spring

    */

    public void method04() throws Exception {

    //打开resources/data/aa.txt下的文件

    InputStream in = this.getClass().getClassLoader().getResourceAsStream("data/aa.txt");

    BufferedInputStream is = new BufferedInputStream(in);

    System.out.println(new String(is.readAllBytes(), StandardCharsets.UTF_8));

    }

    /**

    * 通过ClassPathResource获取文件流

    */

    public void method05() throws Exception {

    //打开resources/data/aa.txt下的文件

    ClassPathResource classPathResource = new ClassPathResource("data/aa.txt");

    InputStream in = classPathResource.getInputStream();

    BufferedInputStream is = new BufferedInputStream(in);

    System.out.println(new String(is.readAllBytes(), StandardCharsets.UTF_8));

    }

    /**

    * 获取项目的绝对路径,不能用于服务器获取

    * 不要使用!!!

    */

    public void method06() throws Exception {

    String projectPath = System.getProperty("user.dir");

    String filePath = projectPath + "/src/main/resources/data/aa.txt";

    File file = new File(filePath);

    System.out.println(filePath + ": " + file.exists());

    }

    /**

    * 获取当前字节码文件的绝对路径

    * 不能用于服务器获取

    */

    public void method07() throws Exception {

    File dir = new File(".");

    File canonicalFile = dir.getCanonicalFile();

    String absolutePath = dir.getAbsolutePath();

    System.out.println(absolutePath);

    }

    }