文件操作
在使用各种 Resource 接口的实现类加载文件资源后,经常需要对文件资源进行读取、拷贝、转存等不同类型的操作。您可以通过 Resource 接口所提供了方法完成这些功能,不过在大多数情况下,通过 Spring 为 Resource 所配备的工具类完成文件资源的操作将更加方便。
文件内容拷贝
第一个我们要认识的是 FileCopyUtils,它提供了许多一步式的静态操作方法,能够将文件内容拷贝到一个目标 byte[]、String 甚至一个输出流或输出文件中。下面的实例展示了 FileCopyUtils 具体使用方法:
清单 4. FileCopyUtilsExample package com.baobaotao.io; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.OutputStream; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.util.FileCopyUtils; public class FileCopyUtilsExample { public static void main(String[] args) throws Throwable { Resource res = new ClassPathResource("conf/file1.txt"); // ① 将文件内容拷贝到一个 byte[] 中 byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile()); // ② 将文件内容拷贝到一个 String 中 String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile())); // ③ 将文件内容拷贝到另一个目标文件 FileCopyUtils.copy(res.getFile(), new File(res.getFile().getParent()+ "/file2.txt")); // ④ 将文件内容拷贝到一个输出流中 OutputStream os = new ByteArrayOutputStream(); FileCopyUtils.copy(res.getInputStream(), os); } }
往往我们都通过直接操作 InputStream 读取文件的内容,但是流操作的代码是比较底层的,代码的面向对象性并不强。通过 FileCopyUtils 读取和拷贝文件内容易于操作且相当直观。如在 ① 处,我们通过 FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接将文件内容读到一个 byte[] 中;另一个可用的方法是 copyToByteArray(InputStream in),它将输入流读取到一个 byte[] 中。
如果是文本文件,您可能希望将文件内容读取到 String 中,此时您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 对 File 进行封装,或使用 InputStreamReader 对 InputStream 进行封装就可以了。
FileCopyUtils 还提供了多个将文件内容拷贝到各种目标对象中的方法,这些方法包括:
方法 说明
static void copy(byte[] in, File out) 将 byte[] 拷贝到一个文件中
static void copy(byte[] in, OutputStream out) 将 byte[] 拷贝到一个输出流中
static int copy(File in, File out) 将文件拷贝到另一个文件中
static int copy(InputStream in, OutputStream out) 将输入流拷贝到输出流中
static int copy(Reader in, Writer out) 将 Reader 读取的内容拷贝到 Writer 指向目标输出中
static void copy(String in, Writer out) 将字符串拷贝到一个 Writer 指向的目标中
在实例中,我们虽然使用 Resource 加载文件资源,但 FileCopyUtils 本身和 Resource 没有任何关系,您完全可以在基于 JDK I/O API 的程序中使用这个工具类。
属性文件操作
我们知道可以通过 java.util.Properties的load(InputStream inStream) 方法从一个输入流中加载属性资源。Spring 提供的 PropertiesLoaderUtils 允许您直接通过基于类路径的文件地址加载属性资源,请看下面的例子:
package com.baobaotao.io; import java.util.Properties; import org.springframework.core.io.support.PropertiesLoaderUtils; public class PropertiesLoaderUtilsExample { public static void main(String[] args) throws Throwable { // ① jdbc.properties 是位于类路径下的文件 Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties"); System.out.println(props.getProperty("jdbc.driverClassName")); } }
一般情况下,应用程序的属性文件都放置在类路径下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法显然具有更强的实用性。此外,PropertiesLoaderUtils 还可以直接从 Resource 对象中加载属性资源:
方法 说明
static Properties loadProperties(Resource resource) 从 Resource 中加载属性
static void fillProperties(Properties props, Resource resource) 将 Resource 中的属性数据添加到一个已经存在的 Properties 对象中
特殊编码的资源
当您使用 Resource 实现类加载文件资源时,它默认采用操作系统的编码格式。如果文件资源采用了特殊的编码格式(如 UTF-8),则在读取资源内容时必须事先通过 EncodedResource 指定编码格式,否则将会产生中文乱码的问题。
清单 5. EncodedResourceExample package com.baobaotao.io; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; import org.springframework.util.FileCopyUtils; public class EncodedResourceExample { public static void main(String[] args) throws Throwable { Resource res = new ClassPathResource("conf/file1.txt"); // ① 指定文件资源对应的编码格式(UTF-8) EncodedResource encRes = new EncodedResource(res,"UTF-8"); // ② 这样才能正确读取文件的内容,而不会出现乱码 String content = FileCopyUtils.copyToString(encRes.getReader()); System.out.println(content); } }
EncodedResource 拥有一个 getResource() 方法获取 Resource,但该方法返回的是通过构造函数传入的原 Resource 对象,所以必须通过 EncodedResource#getReader() 获取应用编码后的 Reader 对象,然后再通过该 Reader 读取文件的内容。
Web 相关工具类
您几乎总是使用 Spring 框架开发 Web 的应用,Spring 为 Web 应用提供了很多有用的工具类,这些工具类可以给您的程序开发带来很多便利。在这节里,我们将逐一介绍这些工具类的使用方法。
操作 Servlet API 的工具类
当您在控制器、JSP 页面中想直接访问 Spring 容器时,您必须事先获取 WebApplicationContext 对象。Spring 容器在启动时将 WebApplicationContext 保存在 ServletContext的属性列表中,通过 WebApplicationContextUtils 工具类可以方便地获取 WebApplicationContext 对象。
WebApplicationContextUtils
当 Web 应用集成 Spring 容器后,代表 Spring 容器的EebApplicationContext 对象将以
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 为键存放在 ServletContext 属性列表中。您当然可以直接通过以下语句获取 WebApplicationContext:
WebApplicationContext wac = (WebApplicationContext)servletContext.
getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
但通过位于 org.springframework.web.context.support 包中的WebApplicationContextUtils 工具类获取 WebApplicationContext 更方便:
WebApplicationContext wac =WebApplicationContextUtils.
getWebApplicationContext(servletContext);
当 ServletContext 属性列表中不存在 WebApplicationContext 时,getWebApplicationContext() 方法不会抛出异常,它简单地返回 null。如果后续代码直接访问返回的结果将引发一个 NullPointerException 异常,而 WebApplicationContextUtils 另一个 getRequiredWebApplicationContext(ServletContext sc) 方法要求 ServletContext 属性列表中一定要包含一个有效的 WebApplicationContext 对象,否则马上抛出一个 IllegalStateException 异常。我们推荐使用后者,因为它能提前发现错误的时间,强制开发者搭建好必备的基础设施。
(编辑:aniston)
|