【问题标题】:Apache VFS in-memoryApache VFS 内存
【发布时间】:2014-11-03 09:40:05
【问题描述】:

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

问题。它提供以下输出: 信息:使用“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);
    }
}

【问题讨论】:

  • 如果您不将 ram 文件用于源以外的任何东西,最好将您的字符串或缓冲区直接写入目标(使用write())。如果您创建 ram 文件,您可以尝试直接创建远程文件并保存 ram 副本。

标签: java ram apache-commons-vfs


【解决方案1】:

这是一个老问题,但我遇到了同样的问题,我能够在不假设本地文件的情况下解决它,所以这可能对遇到与 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");

【讨论】:

    【解决方案2】:

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

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

    是的,描述有点短,但实际上并不多。唯一的实际配置是可能的maximum size。 (实际上我注意到file system reference 还谈到了用于过滤资源的谓词,但没有实现,因此我从本页的 2.1 版本中删除了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 2023-01-17
      • 2014-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多