java.io.FileNotFoundException:类路径资源即使文件存在于 src/main/resources

Posted

技术标签:

【中文标题】java.io.FileNotFoundException:类路径资源即使文件存在于 src/main/resources【英文标题】:java.io.FileNotFoundException: class path resource even though file exists in src/main/resources 【发布时间】:2018-09-16 00:03:19 【问题描述】:

我的 XML 文件位于 src/main/resources 目录下。我的弹簧代码看起来像

import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.springframework.core.io.ClassPathResource;
import org.springframework.integration.xml.transformer.XsltPayloadTransformer;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class BdeApplicationController 

    @GetMapping("/ping")
    @ResponseBody
    public String ping(@RequestParam(name="name", required=false, defaultValue="Stranger") String name) 
        return myFlow();
    

    private String myFlow() 
        XsltPayloadTransformer transformer = getXsltTransformer();
        return transformer.transform(buildMessage(getXMLFileString())).toString();
    

    private String getXMLFileString() 
        try 
            return Files.toString(new ClassPathResource("XML1.xml").getFile(), Charsets.UTF_8);
         catch (IOException e) 
            e.printStackTrace();
        
        return "";
    

    private XsltPayloadTransformer getXsltTransformer() 
        return new XsltPayloadTransformer(new ClassPathResource("XSLT1.xsl"));
    

    protected Message<?> buildMessage(Object payload) 
        return MessageBuilder.withPayload(payload).build();
    

在运行此代码时,我得到以下异常:-

java.io.FileNotFoundException:类路径资源 [XML1.xml] 无法解析为绝对文件路径,因为它不驻留在文件系统中:jar:file:/Users/user/Documents/project/target/bde -0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/XML1.xml

您能建议我如何解决这个问题吗?

【问题讨论】:

【参考方案1】:

当您使用 resource.getFile() 时,您会在文件系统中查找文件,这就是为什么当您作为 jar 运行时它不起作用的原因。

尝试使用 InputStream

String data = "";
ClassPathResource resource = new ClassPathResource("/XML1.xml");
try 
    byte[] dataArr = FileCopyUtils.copyToByteArray(resource.getInputStream());
    data = new String(dataArr, StandardCharsets.UTF_8);
 catch (IOException e) 
    // do whatever

【讨论】:

你是像罐子一样运行它吗? 嗨,是的,我将它作为 jar 运行,您的解决方案现在可以工作了 :)【参考方案2】:

jar 存档中没有文件:使用 InputStream

一旦获得资源(通过ClassPathResource),您应该使用getInputStream() 来获取其内容,而不管它位于何处。这种方式可以在您的 IDE 内部(实际上是 File 那里)以及在服务器上运行 jar 时(在 jar 存档中,而不是确切地 File)。

您只需修改您的 getXMLFileString() 方法,使其使用 InputStream 而不是 File:

private String getXMLFileString() 
    String xml;
    try 
        BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
        xml = reader.lines().collect(Collectors.joining("\n"));
        reader.close();
     catch (IOException e) 
        e.printStackTrace();
        xml = null;
    
    return new String(xml, Charsets.UTF_8);

【讨论】:

以上是关于java.io.FileNotFoundException:类路径资源即使文件存在于 src/main/resources的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中解码 jpeg