apache commons-vfs源码赏析(二)

在上篇中说到了第一个比较重要的类是VFS类.在那个类中说到StandardFileSystemManager这个类.因此在这里我们引申出vfs中第二个比较重要的类:StandardFileSystemManager.这个类集成一个父类DefaultFileSystemManager

在上篇中说道VFS会初始化一个StandardFileSystemManager对象,并调用其init方法.因此我们便去看看这个类的init方法.

因为这个类的比较大,所以在说的时候我只列出我认为比较重要的代码.

public void init() throws FileSystemException
{
// Set the replicator and temporary file store (use the same component)
final DefaultFileReplicator replicator = createDefaultFileReplicator();
setReplicator(new PrivilegedFileReplicator(replicator));
setTemporaryFileStore(replicator);

/* replaced by findClassLoader
if (classLoader == null)
{
// Use default classloader
classLoader = getClass().getClassLoader();
}
*/

if (configUri == null)
{
// Use default config
final URL url = getClass().getResource(CONFIG_RESOURCE);
if (url == null)
{
throw new FileSystemException("vfs.impl/find-config-file.error", CONFIG_RESOURCE);
}
configUri = url;
}

// Configure
configure(configUri);

// Configure Plugins
configurePlugins();

// Initialise super-class
super.init();
}

我们可以看到这个init方法做了很多事,首先是设置临时文件并复制和存储,然后做了一些配置,配置插件并调用其父类的init方法.
在这个方法中用到一个常量CONFIG_RESOURCE和一个变量configUri,
在类的开头已经定义.

private static final String CONFIG_RESOURCE = "providers.xml";
private URL configUri;

说的意思就是我们可以通过configUri去自定义配置文件.如果没有的话就使用默认的providers.xml.

我们重点要看的就是init方法要调用configure(Url url)和configurePlugins()方法

首先看看configure(Url url)方法,这个方法主要做的是根据url去Load一个配置文件.然后里面在去调用configure(Element config)方法.

这个方法的部分代码

InputStream configStream = null;
try
{
// Load up the config
// TODO - validate
final DocumentBuilder builder = createDocumentBuilder();
configStream = configUri.openStream();
final Element config = builder.parse(configStream).getDocumentElement();

configure(config);
}
catch (final Exception e)
{
throw new FileSystemException("vfs.impl/load-config.error", configUri.toString(), e);
}


因此重点要看的就是看看configure(Element config)方法里面做了什么事情.这个比较关键.

private void configure(final Element config) throws FileSystemException
{
// Add the providers
final NodeList providers = config.getElementsByTagName("provider");
final int count = providers.getLength();
for (int i = 0; i < count; i++)
{
final Element provider = (Element) providers.item(i);
addProvider(provider, false);
}

// Add the operation providers
final NodeList operationProviders = config.getElementsByTagName("operationProvider");
for (int i = 0; i < operationProviders.getLength(); i++)
{
final Element operationProvider = (Element) operationProviders.item(i);
addOperationProvider(operationProvider);
}

// Add the default provider
final NodeList defProviders = config.getElementsByTagName("default-provider");
if (defProviders.getLength() > 0)
{
final Element provider = (Element) defProviders.item(0);
addProvider(provider, true);
}

// Add the mime-type maps
final NodeList mimeTypes = config.getElementsByTagName("mime-type-map");
for (int i = 0; i < mimeTypes.getLength(); i++)
{
final Element map = (Element) mimeTypes.item(i);
addMimeTypeMap(map);
}

// Add the extension maps
final NodeList extensions = config.getElementsByTagName("extension-map");
for (int i = 0; i < extensions.getLength(); i++)
{
final Element map = (Element) extensions.item(i);
addExtensionMap(map);
}
}

通过这个方法我们可以看到就是把从配置文件读到的一些内容加入一些容器里面.实际上这些容器在这个类的父类中已经定义过.

private final Map providers = new HashMap();
private final Map operationProviders = new HashMap();
private final FileTypeMap map = new FileTypeMap();

说白了就是从配置文件中读取一些信息加入到这些map中.具体是怎么加入的我就不列举出来,感兴趣的可以自己去看看源码.

init中另外调用的一个方法就是configurePlugins()方法.这个方法就是如果有一些文件系统在vfs中没有实现,我们就可以通过插件的方式自己去实现.

例如smb(共享)这类文件系统的操作在vfs中并没有提供实现,但是apache中沙箱中已经提供实现.这个后面会提供介绍.

这个方法其实就是调用了另外一个配置文件.跟providers.xml类似.然后也加入哪些map中.


因此从中我们可以看出来VFS.getManager()其实做的事情就是读取一些配置文件并讲其内容加入到定义好的map中.

因此我们在使用VFS.getManager()获取FileSystemManager时最好只使用一次,因为这个
方法要读取大量的配置文件并初始话一些数据,会大量占用资源.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中集成SFTP可以通过使用Apache Commons VFS(Virtual File System)库来实现。面是一个简单的示例代码: 1. 首先,确保在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-vfs2</artifactId> <version>2.7.0</version> </dependency> ``` 2. 创建一个SFTPUtil类,用于封装SFTP操作: ```java import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemOptions; import org.apache.commons.vfs2.Selectors; import org.apache.commons.vfs2.impl.StandardFileSystemManager; import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder; public class SFTPUtil { private static final String SFTP_URI = "sftp://username:password@hostname:port/path/to/directory"; public static void uploadFile(String localFilePath, String remoteFilePath) throws FileSystemException { StandardFileSystemManager manager = new StandardFileSystemManager(); try { manager.init(); FileObject localFile = manager.resolveFile(localFilePath); FileObject remoteFile = manager.resolveFile(SFTP_URI + remoteFilePath, createDefaultOptions()); remoteFile.copyFrom(localFile, Selectors.SELECT_SELF); } finally { manager.close(); } } private static FileSystemOptions createDefaultOptions() throws FileSystemException { FileSystemOptions options = new FileSystemOptions(); SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no"); SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, true); SftpFileSystemConfigBuilder.getInstance().setTimeout(options, 10000); // 设置连接超时时间 return options; } } ``` 3. 在你的代码中调用SFTPUtil类的uploadFile方法来上传文件: ```java public class Main { public static void main(String[] args) { try { SFTPUtil.uploadFile("path/to/local/file", "/path/to/remote/file"); System.out.println("File uploaded successfully!"); } catch (FileSystemException e) { e.printStackTrace(); } } } ``` 确保替换SFTP_URI中的`username`、`password`、`hostname`、`port`和`path/to/directory`为正确的SFTP连接信息。然后将本地文件路径和远程文件路径传递给uploadFile方法即可实现文件上传。 这只是一个简单的示例,你可以根据实际需求进行扩展和修改。另外,还可以使用其他的SFTP库,如JSch等,根据自己的喜好选择适合的库进行集成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值