Guava - IO

除了java之外的其他几种jvm语言,例如kotlin,groovy,scala,在自带的库里,已经对文件以及io操作有了非常大的增强,而相比之下java的一些io方法相当原始,所以我们只能求助于类库。虽然自己写一些工具类并不费什么事,但是guava提供的io方法不仅效率高,而且抽象度也高,所以非常易学。

Files

files是一个工具类,估计很多人都写过类似的,但是guava是一个被无数人使用过的库,它的一些数值的考虑都是经过长期检验,相对来说对所有任务都比较高效的。

//复制文件
File original = new File("path/to/original");
File copy = new File("path/to/copy");
Files.copy(original, copy);
//移动文件
File original = new File("src/main/resources/copy.txt");
File newFile = new File("src/main/resources/newFile.txt");
try{
Files.move(original, newFile);
}catch (IOException e){
e.printStackTrace();
}
//快速读进io的每行 事实证明这个任务相当常见,以至于kotlin和groovy的标准库里都添加了这个方法
File file = new File("src/main/resources/lines.txt");
List<String> readLines = Files.readLines(file,Charsets.UTF_8);
//之后可以用java8的stream或者rxjava来进行字符串处理

//各种操作
File file = new File("src/test/resources/quote.txt");
file.deleteOnExit();
String hamletQuoteStart = "To be, or not to be";
Files.write(hamletQuoteStart,file, Charsets.UTF_8);
assertThat(Files.toString(file,Charsets.UTF_8),is(hamletQuoteStart));
String hamletQuoteEnd = ",that is the question";
Files.append(hamletQuoteEnd,file,Charsets.UTF_8);
assertThat(Files.toString(file, Charsets.UTF_8),
is(hamletQuoteStart + hamletQuoteEnd));
String overwrite = "Overwriting the file";
Files.write(overwrite, file, Charsets.UTF_8);
assertThat(Files.toString(file, Charsets.UTF_8),
is(overwrite));

Sources and Sinks

source sink基本上就是inputstream,outputstream,reader,writer的再包装,提供了更多实用的方法

//读字节
File f1 = new File("src/main/resources/sample.pdf");
byteSource = Files.asByteSource(f1);
//用bytesource一次读进所有byte
byte[] readBytes = byteSource.read();
assertThat(readBytes,is(Files.toByteArray(f1)));

//写字节
File dest = new File("src/test/resources/byteSink.pdf");
dest.deleteOnExit();
byteSink = Files.asByteSink(dest);
File file = new File("src/main/resources/sample.pdf");
byteSink.write(Files.toByteArray(file));
assertThat(Files.toByteArray(dest),is(Files.
toByteArray(file)));

//结合起来 拷贝文件
File dest = new
File("src/test/resources/sampleCompany.pdf");
dest.deleteOnExit();
File source = new File("src/main/resources/sample.pdf");
ByteSource byteSource = Files.asByteSource(source);
ByteSink byteSink = Files.asByteSink(dest);
byteSource.copyTo(byteSink);
assertThat(Files.toByteArray(dest),
is(Files.toByteArray(source)));

因为sink ,source代表的是抽象的流对象,所以不仅仅可以用于文件io,任何java里io覆盖到的地方都可以用guava的io对象代替

// 直接读进一个文件存为list,每行为一个元素
ImmutableList<String> lines = Files.asCharSource(file, Charsets.UTF_8)
    .readLines();

// 记录不同单词在文件中的出现次数
Multiset<String> wordOccurrences = HashMultiset.create(
    Splitter.on(CharMatcher.whitespace())
        .trimResults()
        .omitEmptyStrings()
        .split(Files.asCharSource(file, Charsets.UTF_8).read()));


// 从网络流直接拷贝数据到文件中
Resources.asByteSource(url).copyTo(Files.asByteSink(file));

guava的这些方法是很方便,但是有时候使用一个工具类还是显得不太直观(没有面向对象的感觉,一直用静态方法,让我想起用c的时候),所以我推荐使用其他支持扩展方法的jvm语言,直接把这些方法集成进去,用起来更加方便。


使用guava IO对一个小项目进行重构。(这个项目本来是kotlin的,所以提升可能没有重构java项目那么大)

//首先这里是一段使用自己写的工具类将整个文件读进来的代码
val file = File(Config.CONFIGUE)
        if (file.exists()) {
            val result = FileTool.readFile(file)
            val jsonObject = JSONObject(result)
            _parseJson(jsonObject)
        }
        else
        {
          throw RuntimeException("can't find file")
        }
//重构后 直接删除整个自己的工具类,转而用guava代替
val file = File(Config.CONFIGUE)
        if (file.exists()) {
            val result = Files.asCharSource(file,Charsets.UTF_8).read()
            val jsonObject = JSONObject(result)
            _parseJson(jsonObject)
        }
        else
        {
          throw RuntimeException("can't find file")
        }
//使用kotlin的扩展方法再次重构
val file = File(Config.CONFIGUE)
        if (file.exists()) {
            val json=file.readString(Charsets.UTF_8).toJSON()
            _parseJson(json)
        }
        else
        {
          throw RuntimeException("can't find file")
        }
//如果用上guava 的Preconditions还可以更清爽
     checkState(File(Config.CONFIGUE).exists(),"can't find configure file")
        val json= File(Config.CONFIGUE).readString(Charsets.UTF_8).toJSON()
        _parseJson(json)
 //这里插一句题外话,我觉得大部分if条件不中就报错的代码形式,都可以改成前置的Preconditions,然后之后的代码就默认条件为真,这样看起来更加清爽
 //像这种使用json 保存和读取配置文件的,还可以使用gson

第二个地方也一样

    private fun _outputJson(jsonObject: JSONObject) {
        FileTool.writeFile(File(Config.CONFIGUE),jsonObject.toString())
    }
    //重构后
      private fun _outputJson(jsonObject: JSONObject) {Files.asCharSink(File(Config.CONFIGUE),Charsets.UTF_8).write(jsonObject.toString())

    }
    //因为是kt所以就不用null检查了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值