0

I've read this Reading a resource file from within jar however I couldn't figure out how to get a file instead of a inputstream, which is what I need. This is the code:

private void duplicateDocument() {
    FileOutputStream fos = null;
    File file;

    try {
        try {
            doc = new File(getClass().getResource("1.docx").toURI());
            //doc = new File(getClass().getResourceAsStream("1.docx"));
        } catch (URISyntaxException ex) {
            Logger.getLogger(ForensicExpertWitnessReportConfigPanel.class.getName()).log(Level.SEVERE, "Failed ...", ex);
        }

        file = new File("C:\\Users\\student\\Documents\\myfile.docx");
        fos = new FileOutputStream(file);

        /* This logic will check whether the file
        * exists or not. If the file is not found
        * at the specified location it would create
        * a new file
        */
        if (!file.exists()) {
            file.createNewFile();
        }

        /*String content cannot be directly written into
        * a file. It needs to be converted into bytes
        */          
        byte[] bytesArray = FileUtils.readFileToByteArray(doc);

        fos.write(bytesArray);
        fos.flush();
        System.out.println("File Written Successfully");
    } 
    catch (IOException ioe) {
        ioe.printStackTrace();
    } 
    finally {
        try {
            if (fos != null) 
            {
                fos.close();
            }
        } 
        catch (IOException ioe) {
            System.out.println("Error in closing the Stream");
        }
    }
}

FileUtils.readFileToByteArray is the only thing I've been able to get working so far, which is why I need the value a a file rather than an inputstream.

Currently, the code above gives "A java.lang.IllegalArgumentException" which is why I saw a suggestion online to use getResourceAsStream() instead - however haven't been able to return it as a file.

My next option is to try Reading a resource file from within jar - buffered reader instead.

Can someone help?

Polarbearz
  • 35
  • 6

2 Answers2

0

I recommend Files with its many useful functions:

Path out = Paths.get("C:\\Users\\student\\Documents\\myfile.docx");
InputStream in = getClass().getResourceAsStream("1.docx");
Files.copy(in, out, StandardCopyOption.REPLACE_EXISTING);

A resource in principle is a read-only file, possibly zipped in a jar. Hence one cannot write back to it, and it can only serve as template for a real file, as is done here.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Sorry, can't up-vote answer without it showing good resource management, i.e. a simple [try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html). It's only one more line of code (for the end-brace), and teaching good resource management would make this answer *very useful*. – Andreas Mar 15 '18 at 16:23
  • @Andreas on the input: the stream could be null (resource not found), on the output: `Files.copy` will throw an exception. But I agree, when one would use an InputStreamReader or such. – Joop Eggen Mar 15 '18 at 16:27
  • Not sure what you were trying to say with that comment. Whether `in` is null or not, has no bearing on use of try-with-resources, since it can handle nulls. Your code doesn't close `in`, at all, and since `Files.copy` *can* throw exception, it's important to close it in a `finally` block, as question does, but since try-with-resources will do that for you, *better* than a `finally` block, and can handle null, not using try-with-resources gives a bad example. – Andreas Mar 15 '18 at 19:25
  • Anyway, I was just trying to say: Let's make this answer a *great* example, including good resource management, since all it takes to do that is to add `try (...) { ... }`, i.e. 7 characters (excl. whitespace), to the code. *Bonus:* It also scopes `in` to just the `Files.copy` statement. – Andreas Mar 15 '18 at 19:32
0

I got it working, using this:

InputStream in = getClass().getResourceAsStream("1.docx"); 
byte[] bytesArray = IOUtils.toByteArray(in);
Polarbearz
  • 35
  • 6