4

我刚刚发现 VFS 作为访问 sftp 的一种方式。似乎有效,但所有示例都假定一个本地文件;相反,我将数据保存在内存中。我只看到一个方法copyFrom(FileObject),没有接受流或缓冲区的重载......所以我尝试了ram,因为它听起来大致正确(一些文档不会受到伤害,但我不能很好)并且以下测试成功. 复制到 sftp FileObject 也可以。

问题。它提供以下输出: INFO:使用“C:\Users\myname\AppData\Local\Temp\vfs_cache”作为临时文件存储。

- 它实际上是在写一个临时文件吗?这就是我试图避免的(由于运行这个东西的 Unix 服务器上潜在的权限/并发问题)。如果是这样,我如何完全在内存中完成它?

// try to copy a string from memory into a FileObject
public class VFSTest {

    public static void main(String[] args) throws IOException {
        String hello = "Hello, World!";
        FileObject ram = VFS.getManager().resolveFile("ram:/tmp");
        OutputStream os = ram.getContent().getOutputStream();
        os.write(hello.getBytes());
        ram.getContent().close();

        FileObject local = VFS.getManager().resolveFile("C:\\foo.txt");
        local.copyFrom(ram, Selectors.SELECT_SELF);
    }
}
4

2 回答 2

1

不,日志消息是设置文件系统管理器时生成的一般消息。它用于所谓的复制器。您没有在示例中使用它。

是的 ram 文件系统是将文件保存在内存中的一种选择。另一方面,如果您有现有的数据源或字节缓冲区,则需要对其进行泵送:恕我直言,VFS 中没有函数可以从 InputStream 中读取(有一个函数可以将 FileContent 的内容写入 OutputStream)。你通常会使用 commons-ioIOUtils#copy()来做到这一点。

是的,描述有点短,但实际上并不多。唯一的实际配置是可能的最大尺寸。(我实际上注意到文件系统参考也谈到了过滤资源的谓词,但没有实现,所以我从这个页面的 2.1 版本中删除了它)。

于 2015-01-05T16:04:40.387 回答
0

这是一个老问题,但我遇到了同样的问题,我能够在不假设本地文件的情况下解决它,所以这对于与 B W 有相同问题的人可能很有用。基本上,我们可以直接复制输入流进入远程文件的输出流。

代码是这样的:

InputStream is = ... // you only need an input stream, no local file
    
DefaultFileSystemManager fsmanager = (DefaultFileSystemManager) VFS.getManager();
        
FileSystemOptions opts = new FileSystemOptions();
FtpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
StaticUserAuthenticator auth = new StaticUserAuthenticator(host, username, password);
         
DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);
        
String ftpurl = "ftp://" + host + ":" + port + "/" + folder + "/" + filename;
FileObject remoteFile = fsmanager.resolveFile(ftpurl, opts);
        
try (OutputStream ostream = remoteFile.getContent().getOutputStream()) {
    // either copy input stream manually or with IOUtils.copy()
    IOUtils.copy(is, ostream);
}
        
boolean success = remoteFile.exists();
long size = remoteFile.getContent().getSize();
System.out.println(success ? "Successful, copied " + size + " bytes" : "Failed");
于 2020-12-21T15:15:02.853 回答