在Spring启动胖罐里面读取文件

时间:2017-02-01 15:09:41

标签: java spring spring-boot jar

我们有一个spring boot应用程序,它有一个我们使用的遗留jar api,需要通过使用InputFileStream来加载属性。我们将传统jar包装在spring boot fat jar中,属性文件位于BOOT-INF / classes文件夹下。我可以看到spring加载了所有相关的属性,但是当我将属性文件名传递给传统jar时,它无法读取属性文件,因为它在jar中并且不在物理路径下。在这种情况下,我们如何将属性文件传递给传统jar?

请注意我们无法更改传统jar。

5 个答案:

答案 0 :(得分:1)

实际上你可以使用FileSystem。您只需要在获取文件所需的文件夹上模拟文件系统。例如,如果您想获得file.propertiessrc/main/resources,则可以执行以下操作:

FileSystem fs = FileSystems.newFileSystem(this.getClass().getResource("").toURI(), Collections.emptyMap());
String pathToMyFile = fs.getPath("file.properties").toString();
yourLegacyClassThatNeedsAndAbsoluteFilePath.execute(pathToMyFile)

答案 1 :(得分:0)

基本上,你不能,因为属性" file"不是文件,它是jar文件中的资源,它被压缩(它实际上是.zip文件)。

AFAIK,实现这项工作的唯一方法是从jar中提取文件,并将其放在服务器上一个众所周知的位置。然后在运行时使用FileInputStream打开该文件并将其传递给legacy方法。

答案 2 :(得分:0)

我想从resources文件夹中读取一个JSON文件。src / main / resources因此在下面编写了类似这样的代码。

Spring Boot Reading Spring Boot中的资源不适用于胖子。在花了很多时间处理这些简单的事情之后,我发现下面可以进行一些工作。

我发现有一个detailed link on reading resources in Spring Boot,以防装满油罐子。

    @Value("classpath:test.json")
    Resource resourceFile;

    try {
             InputStream resourcee =resource.getInputStream();
             String text = null;
                try (final Reader reader = new InputStreamReader(resourcee)) {
                    text = CharStreams.toString(reader);
                }

            System.out.println(text);

        } catch (IOException e) {

            e.printStackTrace();
        }

答案 3 :(得分:0)

我最近也遇到了这个问题。我有一个文件放入资源文件中,我们称它为path,但我无法读取它。 @madoke提供了使用FileSystem的解决方案之一。这是另一种,这里我们假设我们在一个容器中,如果没有,我们将使用Java 8功能。

@Component 
@Log4j2
public class DataInitializer implements 
    ApplicationListener<ApplicationReadyEvent> {

private YourRepo yourRepo; // this is your DataSource Repo

@Value(“${path.to.file}”). // the path to file MUST start with a forward slash: /iaka/myfile.csv
private String path;

public DataInitializer(YourRepo yourRepo) {
    this.yourRepo = yourRepo;
}

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
    try {
        persistInputData();
        log.info("Completed loading data");
    } catch (IOException e) {
        log.error("Error in reading / parsing CSV", e);
    }
}

private void persistInputData() throws IOException {
    log.info("The path to Customers: "+ path);
    Stream<String> lines;
    InputStream inputStream = DataInitializer.class.getClassLoader().getResourceAsStream(path);
    if (inputStream != null) { // this means you are inside a fat-jar / container
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        lines = bufferedReader.lines();
    } else {
        URL resource = this.getClass().getResource(path);
        String path = resource.getPath();
        lines = Files.lines(Paths.get(path));
    }

    List<SnapCsvInput> inputs = lines.map(s -> s.split(","))
                                     .skip(1) //the column names
                                     .map(SnapCsvInput::new)
                                     .collect(Collectors.toList());
    inputs.forEach(i->log.info(i.toString()));
    yourRepo.saveAll(inputs);

}

}

答案 4 :(得分:0)

根据@moldovean 的解决方案,您只需要调用'getResourceAsStream(path)' 并继续返回InputStream。请注意,“路径”基于 ClassPath。例如:

InputStream stream = this.getClass().getResourceAsStream("/your-file.csv");

在类路径的根目录中,有一个名为“your-file.csv”的文件要读取。

相关问题