我的Java应用程序需要访问保存在远程共享文件夹中的大型excel文件(大小为1GB +)。我使用 SmbFile 来获取带有身份验证的文件。
注意:主要是出于尺寸原因,下载文件不是一种选择。
问题是我需要excel文件是Java IO文件而不是SmbFile,因为我用来解析excel的other libraries只接受Java IO文件。
答案 0 :(得分:5)
查看您图书馆的implementation details:
该库将采用提供的InputStream并将其输出到文件系统。 (...)创建文件后,它将从文件系统流入内存。
需要以这种方式输出流的原因与ZIP文件的工作方式有关。由于XLSX文件格式基本上是ZIP文件,因此无法在不读取整个InputStream的情况下找到所有条目。
(...)此库的工作原理是将流读出到临时文件中。作为自动关闭操作的一部分,临时文件将被删除。
如果您需要更多地控制文件的创建/处理方式,可以选择使用
class="bton"
初始化库。此文件不会被写入或删除
因此,如果您使用java.io.File
或File
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对象并执行所需操作。
首先,您需要导入主库:
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 /> convertSmbFileToFile("Canonical Path")</p>
* <p><strong>Example:</strong> <br /> 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 /> convertFileToSmbFile("Canonical Path")</p>
* <p><strong>Example:</strong> <br /> 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();
}
希望代码的这种和平对您有所帮助,对不起我的英语!!