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

文章分类:JavaSE 标签:JavaCodeSnippet 作者:Hackyle

更新时间:Tue Aug 29 13:48:55 CST 2023

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

  • 基于环境变量user.dir找到文件位置
  • 基于ClassLoader找到文件的位置
  • IDEA中打开文件
  • Tomcat中打开文件
  • 基于Spring找到文件的位置
  • 基于Maven打开resources目录下的文件

打开文件的一般思路

  1. 确定文件位置
  2. 使用java.io.File打开文件,使用InputStream、Reader载入文件流,或者OutputStream、Writer写出文件流

内容导览

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

  • 读取字节码路径下的文件
    1. 类名.getResource(“资源名称”),返回URL
      1. 绝对路径以 / 开头,从classpath 或 jar 包根目录下开始搜索;
      2. 相对路径是相对当前class 所在的目录,允许使用 .. 或 . 来定位文件。
    2. 类名.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" %>

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>PN</title>
</head>
<body>
<%
  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(""));
%>
<!-- JSP表达式 -->
catalina.home: <%= System.getProperty("catalina.home") %> <br/>
user.dir: <%= System.getProperty("user.dir") %> <br/>
requestServerletPath: ${requestServerletPath} <br/>

file01: ${file01} <br/>
file02: ${file02} <br/>
file03: ${file03} <br/>

<!-- 
  Output
  catalina.home: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64
  user.dir: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64\bin
  requestServerletPath: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64\webapps/pn
  
  file01: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64\bin\.
  file02: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64\bin\.
  file03: F:\A04-Storage\PN-Tomcat\apache-tomcat-9.0.31-windows-x64\bin\..
 -->
</body>
</html>

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);
    }
}

 

————————————————
版权声明:非明确标注皆为原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上本文链接及此声明。
原文链接:https://blog.hackyle.com/article/java/open-file

留下你的评论

Name: 

Email: 

Link: 

TOP