欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

guava笔记10-IO 博客分类: guavajava相关

程序员文章站 2024-03-23 15:42:46
...

Java中使用IO Stream直接操作文件的,但是当我们使用这些的时候,往往要经过很多步骤,比如打开文件,关闭文件。很多时候,我们会记得打开文件,但是最后还是一个close()过程,我们总是容易忽略。

 

一.文件操作Util类

Guava建议我们定义所有的IO实体时都使用InputSupplier和OutputSupplier进行包装,这样,我们就不用考虑那么多事情了,简化了操作。

我们知道java IO包里面将文件流分为字节流(InputStream or OutputStream)和字符流(Reader or Writer),guava里面的ByteStreams and CharStreams分别提供了util方法,用来对字节流和字符流进行处理。主要包含的方法如下:

 
guava笔记10-IO
            
    
    博客分类: guavajava相关
 

 

此外,Files类提供了很多static的方法来对文件进行操作,其中有2个方法可以把文件使用InputSupplier或者OutputSupplier进行封装,使用封装后的对象就不会忘记关闭文件了。

 

static InputSupplier<T>  newInputStreamSupplier(File) 可以将file对象使用InputSupplier进行封装。

static OutputSupplier<T> newOutputStream(File) 可以将file对象使用OutputSupplier进行封装。

 

其实Files功能和ByteStreams and CharStreams差不多,其他的重要方法包括,:

toString():读取文件内容

copy():文件内容拷贝,包含多种参数形式

move():文件移到,可以重命名

getFileExtension():获取文件后缀名

getNameWithoutExtension():返回不含后缀的文件名

readLines(File, Charset, LineProcessor):每读取一行就交给LineProcessor进行处理

map(File):把文件映射到内存区块,返回java.nio. MappedByteBuffer

createParentDir(File):如果父目录不存在,则创建之。

simplifyPath(String):把路径格式化

 

二.关闭文件

在JDK7以前,对文件操作,我们需要时刻注意用完后关闭文件。

InputStream in = null;

try {

  in = openInputStream();

  OutputStream out = null;

  try {

    out = openOutputStream();

    // do something with in and out

  } finally {

    if (out != null) {

      out.close();

    }

  }

} finally {

  if (in != null) {

    in.close();

  }

}

可以看到,这段代码真是太复杂了,一不小心就出错了。

可喜的是JDK7有了新的措施来解决这类问题,那就是try-with-resources 语句,如:

try (

        java.util.zip.ZipFile zf =

             new java.util.zip.ZipFile(zipFileName);

        java.io.BufferedWriter writer = 

            java.nio.file.Files.newBufferedWriter(outputFilePath, charset)

    ) {

        // Enumerate each entry

        for (java.util.Enumeration entries =

                                zf.entries(); entries.hasMoreElements();) {

            // Get the entry name and write it to the output file

            String newLine = System.getProperty("line.separator");

            String zipEntryName =

                 ((java.util.zip.ZipEntry)entries.nextElement()).getName() +

                 newLine;

            writer.write(zipEntryName, 0, zipEntryName.length());

        }

    }

基本语法是:try(…) {} ,try里面所有实现接口java.lang.AutoCloseable,包括java.io.Closeable的对象,在{}的语句块执行完毕后都会自动的close。

 

那JDK7以前的版本怎么办呢,guava给我们提供了方法。我们可以把Closeable 的对象注册到Closer对象上,资源使用完毕后,调用closer的close方法,就可以把所有注册了的资源安全的close掉。这个方法虽然没有try-with-resources好用,但是比起传统的jdk做法,要好很多了。

Closer closer = Closer.create();

try {

  InputStream in = closer.register(openInputStream());

  OutputStream out = closer.register(openOutputStream());

  // do stuff with in and out

} catch (Throwable e) { // must catch Throwable

  throw closer.rethrow(e);

} finally {

  closer.close();

}

 

三.Source和Sink

此外,guava还提供了Source和Sink来对文件流进行操作。

Files提供了方法,从File对象得到Source和Sink。

stati c  ByteSource  Files.asByteSource

static  CharSource  Files.asCharSource

static  ByteSink  Files.asByteSink

static  CharSink  Files.asCharSink

 

Source实现了InputSupplier,表示可读的输入流,但是跟InputSupplier不同,它是一个不可变化的supplier实例。

Source分为ByteSource 和CharSource,分别用来处理字节流和字符流。

Source提供了方法openStream() 返回一个新创建的输入流,可以使用这个流来读取文件内容,读取完毕后调用方要负责关闭掉。

此外,Source还提供了一些快捷操作的方法,如copyTo,调用这样的方法,操作完毕后会自动关闭文件,不用考虑手动关闭文件的问题。

 

与Source对应,Sink实现了OutputSupplier,表示可写的输出流,它也是一个不可变的supplier实例。

Sink也分为ByteSink和CharSink,分别用来处理字节流和字符流。

Sink也提供了方法openStream()返回一个新创建的输出流,可以使用这个流来写文件,完成后调用方要记得关闭掉流。

Sink里面有些快捷操作方法,如writeLines,writeFrom操作完成后也是会自动关闭文件的。

Source和Sink用起来还是很方便的,如下面一句话就可以实现文件复制了,完全不用考虑文件的关闭。

Files.asByteSource(new File("d:/1.txt")).copyTo(Files.asByteSink(new File("d:/2.txt"),FileWriteMode.APPEND));

 

  • guava笔记10-IO
            
    
    博客分类: guavajava相关
  • 大小: 80.4 KB