将 SmbFile 转换为 Java IO 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36339504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert SmbFile to Java IO File
提问by arash moeen
My Java application requires access to a large excel file (1GB+ in size) saved on remote shared folder. I'm using SmbFileto get the file with authentication.
我的 Java 应用程序需要访问保存在远程共享文件夹中的大型 excel 文件(大小超过 1GB)。我正在使用SmbFile来获取带有身份验证的文件。
Note:Downloading of the file is not an option mainly for size reasons.
注意:主要是由于大小原因,不能选择下载文件。
The problem is that I need the excel file to be a Java IO File and not SmbFile since the other librariesthat I'm using to parse the excel only accepts Java IO File.
问题是我需要 excel 文件是 Java IO 文件而不是 SmbFile,因为我用来解析 excel的其他库只接受 Java IO 文件。
- Is there any way to convert this SmbFile into a Java compatible File?
- 有没有办法将此 SmbFile 转换为 Java 兼容文件?
回答by Adam Michalik
See implementation detailsof 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
该库将采用提供的 InputStream 并将其输出到文件系统。(...) 创建文件后,它将从文件系统流式传输到内存中。
需要以这种方式输出流的原因与 ZIP 文件的工作方式有关。因为 XLSX 文件格式基本上是一个 ZIP 文件,所以不读取整个 InputStream 就不可能找到所有条目。
(...) 这个库的工作原理是将流读出到一个临时文件中。作为自动关闭操作的一部分,临时文件被删除。
如果您需要更多地控制文件的创建/处理方式,可以选择使用
java.io.File
. 该文件不会被写入或删除
So it doesn't matter if you use the File
or InputStream
API - the whole file will need to be downloaded anyhow.
因此,如果您使用File
或InputStream
API并不重要- 无论如何都需要下载整个文件。
The simplest solution is to pass the SmbFile.getInputStream()
to
最简单的解决方案是传递SmbFile.getInputStream()
给
StreamingReader.builder().read(smbFile.getInputStream())
but alternatively you can first download the file eg. by means of IOUtils.copy()
or Files.copy()
但也可以先下载文件,例如。通过IOUtils.copy()
或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
并传递file
给
StreamingReader.builder().read(file)
回答by Ellington Brambila
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.
在您的情况下,您需要使用带有身份验证的 SmbFile 将 excel 文件从源(远程目录)复制到目标(本地目录),然后才转换目标的 excel 文件路径(getCanonicalPath() 函数)并转换它从 SmbFile 格式到 File 格式,代码如下。之后,使用文件目标路径创建 File 对象并执行您想要的操作。
I use JCIFSto work with remote shared directories using the SMBFILEclass.
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 SmbFileformat to Fileformat:
其次,您需要创建一个静态方法来将SmbFile格式转换为File格式:
/**
* 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;
}
Opcional, you could also create a static method to convert from Fileformat to SmbFileformat:
可选,您还可以创建一个静态方法来从文件格式转换为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("\", "/");
}
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()
额外信息:getCanonicalPath()
Maybe this code will help you and I am available to talk about if you want.
也许此代码会对您有所帮助,如果您愿意,我可以讨论。
Good Luck!
祝你好运!
回答by rsinha
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
smbFile.getUncPath() 的 javadoc 说
Retuns the Windows UNC style path with backslashs intead of forward slashes.
使用反斜杠而不是正斜杠重新调整 Windows UNC 样式路径。
I am using jcifs-1.3.17.jar on Windows 10.
我在 Windows 10 上使用 jcifs-1.3.17.jar。
回答by LAGHRAOUI
It's just a matter of structure I guess, with SmbFile we have two arguments while with File we have just one argument. So, my Idea is to declare a File with the same path of the SmbFile and try to handle your file. For example, in my I want to delete recursively the content of my folder :
我猜这只是结构问题,对于 SmbFile 我们有两个参数,而对于 File 我们只有一个参数。所以,我的想法是声明一个与 SmbFile 路径相同的 File 并尝试处理您的文件。例如,在我想递归删除我的文件夹的内容:
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();
}
I hope this peace of code help you, and sorry for my english !
我希望这种和平的代码可以帮助您,并为我的英语感到抱歉!