Convert SmbFile to Java IO File

末鹿安然 提交于 2019-11-30 14:50:12

See implementation details of your library:

This library will take a provided InputStream and output it to the file system. (...) Once the file is created, it is then streamed into memory from the file system.

The reason for needing the stream being outputted in this manner has to do with how ZIP files work. Because the XLSX file format is basically a ZIP file, it's not possible to find all of the entries without reading the entire InputStream.

(...) This library works by reading out the stream into a temporary file. As part of the auto-close action, the temporary file is deleted.

If you need more control over how the file is created/disposed of, there is an option to initialize the library with a java.io.File. This file will not be written to or removed

So it doesn't matter if you use the File or InputStream API - the whole file will need to be downloaded anyhow.

The simplest solution is to pass the SmbFile.getInputStream() to

StreamingReader.builder().read(smbFile.getInputStream())

but alternatively you can first download the file eg. by means of IOUtils.copy() or Files.copy()

File file = new File("...");
try (
     in = smbFile.getInputStream();
     out = new FileOutputStream(file)
) {
    IOUtils.copy(in, out);
}

or

try (in = smbFile.getInputStream()) {
    Files.copy(smbFile.getInputStream(), file.toPath());
}

and pass file to

StreamingReader.builder().read(file)

Recently i had a similar situation, however, I hadn't found a good solution in the internet, but I wrote a basic code that did what I need easily.

In your case, you will need to copy the excel file from the source (Remote Directory) using SmbFile with authentication to the destination (Local Directory) and only after, convert the excel file path of the destination (getCanonicalPath() function) and convert it from SmbFile format to File format with the code below. After, create your File object with the file destination path and do what you want.

I use JCIFS to work with remote shared directories using the SMBFILE class.

First, you need to import the main libraries:

import java.io.File;
import java.io.IOException;
import jcifs.smb.SmbFile;

Second, you need to create a static method to convert from SmbFile format to File format:

/**
 * This method convert a directory path from SmbFile format to File format.<br />
 * <p><strong>Sintax:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertSmbFileToFile("Canonical Path")</p>
 * <p><strong>Example:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertSmbFileToFile("smb://localhost/D$/DOCUMENTOS/workspace/tests2/access")</p>
 * @param smbFileCanonicalPath String
 * @see String
*/
public static String convertSmbFileToFile(String smbFileCanonicalPath) {
    String[] tempVar = smbFileCanonicalPath.substring(6).replace("$", ":").split("/"); 
    String bar = "\\";
    String finalDirectory = "";
    for (int i = 1; i < tempVar.length; i++) {
        finalDirectory += tempVar[i] + bar;
        if (i == tempVar.length - 1) {
            finalDirectory = finalDirectory.substring(0,finalDirectory.length()-1);
        }
    }
    return finalDirectory;
}

Opcional, you could also create a static method to convert from File format to SmbFile format:

/**
 * This method convert a directory path from File format to SmbFile format.<br />
 * <p><strong>Sintax:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertFileToSmbFile("Canonical Path")</p>
 * <p><strong>Example:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertFileToSmbFile("D:\DOCUMENTOS\workspace\tests2\access")</p>
 * @param fileCanonicalPath String
 * @see String
*/
public static String convertFileToSmbFile(String fileCanonicalPath) {
    return "smb://localhost/" + fileCanonicalPath.toString().replace(":", "$").replace("\\", "/");
}

Finally, you can call the methods like the below example:

String dirDest = "access/";

    try {

        File localDirFile = new File(dirDest);

        SmbFile localSmbDirFile = new SmbFile(convertFileToSmbFile(localDirFile.getCanonicalPath()));
        File localDirFile2 = new File(convertSmbFileToFile(localSmbDirFile.getCanonicalPath()));

        System.out.println("Original File Format: " + localDirFile.getCanonicalPath());
        System.out.println("Original File Format to SmbFile Format: " + localSmbDirFile.getCanonicalPath());
        System.out.println("Converted SmbFile Format to File Format: " + localDirFile2.getCanonicalPath());

    } catch (IOException e) {

        System.err.println("[ERR] IO Exception - " + e);

    }

Result of previous code run:

Original File Format: D:\DOCUMENTOS\workspace\tests2\access
Original File Format to SmbFile Format: smb://localhost/D$/DOCUMENTOS/workspace/tests2/access
Converted SmbFile Format to File Format: D:\DOCUMENTOS\workspace\tests2\access

Extra Information: getCanonicalPath()

Maybe this code will help you and I am available to talk about if you want.

Good Luck!

    jcifs.smb.SmbFile smbFile = new SmbFile("smb://host/fileShare/.../file");
    java.io.File javaFile = new File(smbFile.getUncPath());

    System.out.println(smbFile);
    System.out.println(javaFile);

Output

smb://host/fileShare/.../file
\\host\fileShare\...\file

javadoc of smbFile.getUncPath() says

Retuns the Windows UNC style path with backslashs intead of forward slashes.

I am using jcifs-1.3.17.jar on Windows 10.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!