yannrichet / rsession

R sessions wrapping for Java
BSD 2-Clause "Simplified" License
52 stars 31 forks source link

Add a method public synchronized void getFile(OutputStream os, String remoteFile) to org.math.R.RserveSession.java #48

Closed icejean closed 1 year ago

icejean commented 1 year ago

When calling Rserve backend in a servlet and so on, it's better to write the file got from Rserve remote to HttpOutputStream. The function below works for me to get a PDF/Excel/Word file back and push the binary stream to the browser.

    /**
     * Get file from R environment to user OutputStream
     *
     * @param os local OutputStream file
     * @param remoteFile R environment file name
     */
    public synchronized void getFile(OutputStream os, String remoteFile) {
        try {
            if (((REXP) silentlyRawEval("file.exists('" + remoteFile.replace("\\", "/") + "')", TRY_MODE)).asInteger() != 1) {
                log(HEAD_ERROR + IO_HEAD + "file " + remoteFile + " not found.", Level.ERROR);
            }
        } catch (Exception ex) {
             log(HEAD_ERROR + ex.getMessage() + "\n  getFile(File remoteFile=" + remoteFile + ")", Level.ERROR);
            return;
        }

        InputStream is = null;
        //synchronized (R) {
        try {
            is = R.openFile(remoteFile.replace("\\", "/"));
            //os = new BufferedOutputStream(new FileOutputStream(localfile));
            IOUtils.copy(is, os);
            log(IO_HEAD + "File " + remoteFile + " received.", Level.INFO);
            is.close();
        } catch (IOException e) {
            log(HEAD_ERROR + IO_HEAD + R.getLastError() + ": file " + remoteFile + " not transmitted.\n" + e.getMessage(), Level.ERROR);
        } finally {
            IOUtils.closeQuietly(is);
         }
        //}
    }
icejean commented 1 year ago

Hope that this feature may be merged into the coming versions in the future.