0

Till now my code works fine where I am creating file in temporary directory and processing it.

But now I am trying to provide specific directory where I actually want to create xml file. So in method createTmpXmlFile

    private static Path createTmpXmlFile(final String prefix) {
        try {
            log.info("Creating temporary file {}{}", prefix, XML_SUFFIX);
            return Files.createTempFile(Paths.get(gleifZipFile), prefix, XML_SUFFIX);

        } catch (IOException e) {
            throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
        }
    }

I changed from

return Files.createTempFile(prefix, XML_SUFFIX);

to

return File.createTempFile(prefix, XML_SUFFIX, "/tmp/in");

and I get following error:

java: incompatible types: java.lang.String cannot be converted to java.io.File.

If I change the logic here then its affecting other method that are calling createTmpXmlFile method.

I really don't understand how to resolve this issue. Below is my code:

@Slf4j
public class InputCS implements Runnable {

    public static final String XML_SUFFIX = ".xml";
    
    @Value("${gleifdataimporter.file.dir}")    
    private String gleifZipFile;

    private void processleifZipFile() {
        final AtomicBoolean isInsideLeiRecord = new AtomicBoolean();
        isInsideLeiRecord.set(false);
        final StringBuilder currentLeiRecordXml = new StringBuilder();

        try (FileSystem zipFs = FileSystems.newFileSystem(jobRunner.getInputZipPath(), null)) {
            Path tmpXMLPath = xmlFileFromLeiZipFile(zipFs);

            try (Stream<String> lines = Files.lines(tmpXMLPath)) {
                AtomicInteger processedLinesCounter = new AtomicInteger();
                AtomicInteger currentLineNumber = new AtomicInteger();
                lines.sequential().forEach(handleLineAndIncrementLineNumber(isInsideLeiRecord, currentLeiRecordXml, processedLinesCounter, currentLineNumber));
                log.info("{} lines of XML file inside LEIF input ZIP file {} processed.", processedLinesCounter.get(), jobRunner.getInputZipPath());
            }catch (IOException e) {
                throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
            } finally {
                Files.delete(tmpXMLPath);
            }
        } catch (IOException e) {
            throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
        }
    }

    private Path xmlFileFromLeiZipFile(FileSystem zipFs) {       //extracts the xml file from zip file
        log.info("Input file {} exists: {}", jobRunner.getInputZipPath(), Files.exists(jobRunner.getInputZipPath()));
        Path tmpXmlPath = createTmpXmlFile("leif__" + System.currentTimeMillis());
        for (Path rootDir : zipFs.getRootDirectories()) {
            try (Stream<Path> files = treeAt(rootDir)) {
                log.info("Trying to extract LEIF XML file from ZIP file into {}.", tmpXmlPath);
                final Path xmlFileInsideZip = files
                        .filter(isNotADir())
                        .filter(Files::isRegularFile)
                        .findFirst()
                        .orElseThrow(() -> new IllegalStateException("No file found in LEI ZIP file."));
                log.info("Path to LEIF XML file inside ZIP file: {}.", xmlFileInsideZip);
                return copyReplacing(xmlFileInsideZip, tmpXmlPath);
            }
        }
        throw new IllegalStateException("No file found in LEI ZIP file " + jobRunner.getInputZipPath() + ".");
    }
    

    private static Path createTmpXmlFile(final String prefix) {
        try {
            log.info("Creating temporary file {}{}", prefix, XML_SUFFIX);
            return Files.createTempFile(Paths.get(gleifZipFile), prefix, XML_SUFFIX);

        } catch (IOException e) {
            throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
        }
    }
    
    @NotNull
    private static Path copyReplacing(Path from, Path to) {
        requireNonNull(from, "Trying to copy from a path, which is null to path " + to + ".");   //trying to copy file where no xml file exist in root directory
        requireNonNull(to, "Trying to copy from path " + from + " to a path, which is null.");
        try {
            return Files.copy(from, to, REPLACE_EXISTING);
        } catch (IOException e) {
            throw new IllegalStateException("Cannot copy from " + from + " to " + to + ". ", e);
        }
    }
    
}
samabcde
  • 6,988
  • 2
  • 25
  • 41
Andrew
  • 3,632
  • 24
  • 64
  • 113
  • Hello, `Files` instead of `File` in `File.createTempFile(prefix, XML_SUFFIX, "/tmp/in")` ? – dariosicily Jun 23 '20 at 14:49
  • 2
    Why did you switch to `java.io.File`? If you want to put temporary files in a specific directory use [`Files#createTempFile(Path,String,String,FileAttribute...)`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/nio/file/Files.html#createTempFile(java.nio.file.Path,java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute...)). Note that `java.nio.file.Files` also has methods for creating temporary directories. – Slaw Jun 23 '20 at 14:49
  • i updated question sorry i tried same approach as u can see in question but same error java: incompatible types: java.io.File cannot be converted to java.nio.file.Path – Andrew Jun 23 '20 at 15:00
  • You're still using `File.createTempFile` instead of `Files.createTempFile`. – Slaw Jun 23 '20 at 15:02

2 Answers2

2
  1. As suggested by Slaw, use Files#createTempFile(Path,String,String,FileAttribute...) to specify the directory to create temp file.
  2. Use Paths#get(String,String...) for java 7 or 8, or Path#of(String,String...) for java 11 or later to convert String to Path. Further reading: Paths.get vs Path.of

private static Path createTmpXmlFile(final String prefix) {
    try {
        // Java 11 or later
        // return Files.createTempFile(Path.of("/tmp/in"), prefix, XML_SUFFIX);
        // Java 8
        return Files.createTempFile(Paths.get("/tmp/in"), prefix, XML_SUFFIX);
    } catch (IOException e) {
        throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
    }
}
samabcde
  • 6,988
  • 2
  • 25
  • 41
  • yes its working now but i have question..is it possible if i can change from /tmp/in to any directory and also is it possible if i can provide just value in this and save this value as property where i can provide the path ? – Andrew Jun 23 '20 at 15:06
  • Possible of course. It depends on how you store/retrieve the path value, One of the way is to add one more parameter and let the caller to provide the path. – samabcde Jun 23 '20 at 15:12
  • can you please tell me how it can be done actually sorry tmp directory was just an example... i have updated question now with you answer but modified path...and getting error as java.lang.NullPointerException...i am soring the value in db properties and fetching from there...actually it works for another class where i am trying to fetch other values from properties but here i am getting error – Andrew Jun 23 '20 at 15:14
  • when i tried to check it says the the directory path is null..so somehow its not fetching value from properties – Andrew Jun 23 '20 at 15:22
  • now i have updated question and provided class which is inside same package and which is taking the value from properties file to create zip file inside specified directory...for example here: final String zipFileAbsolutePath = createTempFile("life", ".zip", new File(lifeZipFile)).getAbsolutePath(); //Temp path where zip file gets download – Andrew Jun 23 '20 at 15:29
  • From updated code, it seems that the value `gleifZipFile` is null, check if the properties file has this key and value first. If nothing wrong, I suggest you to find any difference between this class and other working class to find out why the value is null. – samabcde Jun 23 '20 at 15:36
  • actually if you see in both classes we need to provide same directory and using the same value but somehow its getting null in the classes where i am creating xml file – Andrew Jun 23 '20 at 15:42
  • I suspect that `lifeDataImporter` has the annotation @Service which `InputConsumer` does not have makes the difference. Spring does not scan `InputConsumer` and provide the value. – samabcde Jun 23 '20 at 15:47
  • i think you are right now i have provided the same @Service in the class InputConsumer and now getting error as i mentioned in the question at the bottom – Andrew Jun 23 '20 at 15:51
1

File.createTempFile is expecting a File object as third parameter. Just wrap your "/tmp/in" into a File => return File.createTempFile(prefix, XML_SUFFIX, new File("/tmp/in")); and you should be good to go.

so you can do:

File.createTempFile("prefix", "suffix", new File("/tmp/in"));

Or using NIO (recommended)

Files.createTempFile(Paths.get("/tmp/in"), "prefix", "suffix");
Léo Schneider
  • 2,085
  • 3
  • 15
  • 28
  • i updated the code little bit u can check the question ...i tried your approach but getting same error java: incompatible types: java.io.File cannot be converted to java.nio.file.Path...its telling me to change private static PathcreateTmpXmlFile(final String prefix) to private static File createTmpXmlFile(final String prefix) which might affect other part i guess – Andrew Jun 23 '20 at 14:59
  • have a look at https://stackoverflow.com/questions/617414/how-to-create-a-temporary-directory-folder-in-java if you want to have the same repository generalized – Léo Schneider Jun 23 '20 at 15:07
  • i checked that question but did not understand sorry :( i have updated question little bit just to make it configurable but now i am getting error as java.lang.NullPointerException – Andrew Jun 23 '20 at 15:13
  • now i have updated question and provided class which is inside same package and which is taking the value from properties file to create zip file inside specified directory...for example here: final String zipFileAbsolutePath = createTempFile("life", ".zip", new File(lifeZipFile)).getAbsolutePath(); //Temp path where zip file gets download – Andrew Jun 23 '20 at 15:29