将SmbFile转换为Java IO文件

时间:2016-03-31 17:03:44

标签: java smb

我的Java应用程序需要访问保存在远程共享文件夹中的大型excel文件(大小为1GB +)。我使用 SmbFile 来获取带有身份验证的文件。

注意:主要是出于尺寸原因,下载文件不是一种选择。

问题是我需要excel文件是Java IO文件而不是SmbFile,因为我用来解析excel的other libraries只接受Java IO文件。

  1. 有没有办法将此SmbFile转换为Java兼容文件?

5 个答案:

答案 0 :(得分:5)

查看您图书馆的implementation details

  

该库将采用提供的InputStream并将其输出到文件系统。 (...)创建文件后,它将从文件系统流入内存。

     

需要以这种方式输出流的原因与ZIP文件的工作方式有关。由于XLSX文件格式基本上是ZIP文件,因此无法在不读取整个InputStream的情况下找到所有条目。

     

(...)此库的工作原理是将流读出到临时文件中。作为自动关闭操作的一部分,临时文件将被删除。

     

如果您需要更多地控制文件的创建/处理方式,可以选择使用class="bton"初始化库。此文件不会被写入或删除

因此,如果您使用java.io.FileFile API并不重要 - 无论如何都需要下载整个文件。

最简单的解决方案是将InputStream传递给

SmbFile.getInputStream()

但也可以先下载文件,例如。通过IOUtils.copy()Files.copy()

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

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

并将try (in = smbFile.getInputStream()) { Files.copy(smbFile.getInputStream(), file.toPath()); } 传递给

file

答案 1 :(得分:1)

使用 Apache Commons IO

https://mvnrepository.com/artifact/commons-io/commons-io

NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", "user", "key");

SmbFile smbFile = new SmbFile("smb://IP/pitoka.tmp", auth)

InputStream initialStream = smbFile.getInputStream();

File targetFile = new File("/tmp/pitoka.tmp");

FileUtils.copyInputStreamToFile(initialStream, targetFile);

希望对您有所帮助。

答案 2 :(得分:0)

最近我有类似的情况,但是,我没有在互联网上找到一个好的解决方案,但我写了一个基本代码,可以轻松地完成我需要的工作。

在您的情况下,您需要使用SmbFile从源(远程目录)复制excel文件,并使用身份验证到目标(本地目录),然后转换目标的excel文件路径(getCanonicalPath()函数) )并使用下面的代码将其从SmbFile格式转换为文件格式。 之后,使用文件目标路径创建File对象并执行所需操作。

我使用JCIFS使用SMBFILE类来处理远程共享目录。

首先,您需要导入主库:

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

其次,您需要创建一个静态方法,将 SmbFile 格式转换为文件格式:

/**
 * 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;
}

此外,您还可以创建静态方法,将文件格式转换为 SmbFile 格式:

/**
 * 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("\\", "/");
}

最后,您可以调用以下示例的方法:

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);

    }

以前代码运行的结果:

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

额外信息:getCanonicalPath()

也许这段代码可以帮助你,如果你愿意,我可以谈谈。

祝你好运!

答案 3 :(得分:0)

    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);

输出

smb://host/fileShare/.../file
\\host\fileShare\...\file
smbFile.getUncPath()的

javadoc说

  

使用反斜杠替换正向来重新调整Windows UNC样式路径   斜线。

我正在Windows 10上使用jcifs-1.3.17.jar。

答案 4 :(得分:0)

我想这只是结构问题,使用SmbFile我们有两个参数,而使用File我们只有一个参数。 因此,我的想法是声明一个文件,该文件具有与SmbFile相同的路径,并尝试处理您的文件。 例如,在我中,我要递归删除文件夹中的内容:

SmbFile sFile = new SmbFile(path, auth)

if (sFile.exists()) {
 File file = new File(path);
 deleteDirectory(file);

}

 boolean deleteDirectory(File directoryToBeDeleted) {
    File[] allContents = directoryToBeDeleted.listFiles();
    if (allContents != null) {
        for (File file : allContents) {
            deleteDirectory(file);
        }
    }
    return directoryToBeDeleted.delete();
}

希望代码的这种和平对您有所帮助,对不起我的英语!!