Vert.x核心模块 访问文件系统(十三)

用Vert.x使用文件系统

Vert.x的FileSystem对象提供了一些维护文件系统的操作。每一个Vert.x实例都有一个文件系统对象,用fileSystem获取。每一个操作都提供了阻塞和非阻塞版本。非阻塞版本执行器在操作完成或出现错误时被调用。

这里有一个异步复制文件的例子:
FileSystem fs = vertx.fileSystem();

 // Copy file from foo.txt to bar.txt

fs.copy("foo.txt","bar.txt", res -> {

    if(res.succeeded()) {

        // Copied ok!

    }else {

       // Something went wrong

    }

});

阻塞的版本被命名为xxxBlocking并且直接返回一个结果或抛出异常。一些情况下,依赖于操作系统和文件系统,一些潜在的阻塞操作能迅速返回,这就是为什么提供了阻塞版本。但是更好的建议是在一个事件循环中使用之前,必须在特别的应用中测试其需要多长时间才能返回。

这是一个用阻塞API复制的例子:

FileSystem fs = vertx.fileSystem();

 // Copy file from foo.txt to bar.txtsynchronously

fs.copyBlocking("foo.txt","bar.txt");

存在一些操作,如copy,move,truncate,chmod和一些其他文件操作。我不一一列出,请查看API文档获取整个列表。

让我们看两个使用异步方法的例子:
Vertx vertx = Vertx.vertx();

// Read a file

vertx.fileSystem().readFile("target/classes/readme.txt",result -> {

    if(result.succeeded()) {

       System.out.println(result.result());

    }else {

       System.err.println("Oh oh ..." + result.cause());

    }

});

 // Copy a file

vertx.fileSystem().copy("target/classes/readme.txt","target/classes/readme2.txt", result -> {

    if(result.succeeded()) {

       System.out.println("File copied");

    }else {

       System.err.println("Oh oh ..." + result.cause());

    }

});

 // Write a file

vertx.fileSystem().writeFile("target/classes/hello.txt",Buffer.buffer("Hello"), result -> {

    if(result.succeeded()) {

       System.out.println("File written");

    }else {

       System.err.println("Oh oh ..." + result.cause());

    }

});

 // Check existence and delete

vertx.fileSystem().exists("target/classes/junk.txt",result -> {

    if(result.succeeded() && result.result()) {

       vertx.fileSystem().delete("target/classes/junk.txt", r -> {

           System.out.println("File deleted");

       });

    }else {

        System.err.println("Oh oh ... -cannot delete the file: " + result.cause());

    }

});

 异步文件

Vert.x提供一个异步文件抽象允许在文件系统上操作文件。象现面一样打开一个异步文件(AsyncFile):

OpenOptions options = new OpenOptions();

fileSystem.open("myfile.txt",options, res -> {

    if(res.succeeded()) {

       AsyncFile file = res.result();

    }else {

       // Something went wrong!

    }

});

AsyncFile实现了ReadStrean和WriteStream,所以可以泵接文件到其他流对象或从其他流对象泵接,如网络socket,http请求和响应及WebSocket。他们允许对他们直接读取或写入。

 随机访问写

使用AsyncFile的write方法进行随机访问。

write方法的参数有:

·          buffer:写缓冲器

·          position:在文件中一整型位置,Buffer将从此处写。如果此参数大于或等于文件大小,文件将会扩大容纳此偏移。

·          handler:结果处理器,在成功/失几时调用

这是一个随机写入的例子:

Vertx vertx = Vertx.vertx();

vertx.fileSystem().open("target/classes/hello.txt",new OpenOptions(), result -> {

    if(result.succeeded()) {

       AsyncFile file = result.result();

       Buffer buff = Buffer.buffer("foo");

       for (int i = 0; i < 5; i++) {

           file.write(buff, buff.length() * i, ar -> {

               if (ar.succeeded()) {

                    System.out.println("Writtenok!");

                    // etc

               } else {

                   System.err.println("Failed to write: " + ar.cause());

               }

           });

        }

    }else {

       System.err.println("Cannot open file " + result.cause());

    }

});

 随机读

使用read方法进行AsyncFile的随机读。

此方法参数有:

·          buffer:读入数据的缓冲区。

·          offset:读入缓冲区的偏移量,数据将从此位置向缓冲区写入。

·          position:文件中读取数据开始的位置。

·          length:需要读取数据的字节数,既长度。

·          handler:结果处理器,在读取成功/失败时调用。

这是一个随机读取的例子:
Vertx vertx = Vertx.vertx();

vertx.fileSystem().open("target/classes/les_miserables.txt",new OpenOptions(), result -> {

    if(result.succeeded()) {

       AsyncFile file = result.result();

       Buffer buff = Buffer.buffer(1000);

       for (int i = 0; i < 10; i++) {

           file.read(buff, i * 100, i *100, 100, ar -> {

               if (ar.succeeded()) {

                   System.out.println("Read ok!");

               } else {

                   System.err.println("Failed to write: " + ar.cause());

               }

           });

        }

    }else {

       System.err.println("Cannot open file " + result.cause());

    }

});

 打开文件的选项

在打开一个AsyncFile时,可以传入一个OpenOption实例。此选项描述了文件访问的行为。例如,可以用setRead,setWrite和setPerm方法设置文件的权限。也以设置用setCreateNew和setTruncateExisting方法设置是否打开存在的文件。也可用setDeleteOnClose方法设置一个标识,指示在JVM关闭时是否删除文件。

 刷新数据到你层的存储

在OpenOptions中,可以用setDsync方法启用或禁在每次写时是否自动内容同步。在那种情况下,用flus方法手动将操作系统缓存数据刷新到存储(如磁盘)。flush方法可以传递一个处理器参数,此处理器在刷新完成时被调用。

 将AsyncFile作为读写流(ReadStream和WriteStream)

AsyncFile实现了ReadStream和WriteStream。可以使用AsyncFile的读写流泵接到其他读取流抽取数据或将数据泵接给其他读写流。例如,下面代码可以将一个AsyncFile的内容复制到另一个AsyncFile。

Vertx vertx = Vertx.vertx();

final AsyncFile output =vertx.fileSystem().openBlocking("target/classes/plagiary.txt", newOpenOptions());

 vertx.fileSystem().open("target/classes/les_miserables.txt",new OpenOptions(), result -> {

    if(result.succeeded()) {

       AsyncFile file = result.result();

       Pump.pump(file, output).start();

       file.endHandler((r) -> {

           System.out.println("Copy done");

       });

    }else {

       System.err.println("Cannot open file " + result.cause());

    }

});

也可用泵接功能将内容写到HTTP响应,或者更多一般的WriteStream.

 从类路径中访问文件

在Vert.x不能在文件系统中找到文件时,Vert.x偿试从类路径中处理文件。注意类路么资源路径从不以”/”开头。因为此原因,Java不提供异步从类路径访问资源,所以在类路径资源第一次异步被访问和服务时,文件会在工作线程中被复制到文件系统。在同一资源第二次被访问时,将用来自文件系统的文件直接对外提供服务。如果类路径资源改变了,将用原内容对外服务(你如,在开发系统中)。

此缓存行为通过设置vertx.disableFileCache系统属性为true,可以查看到。缓存的文件默认路径是vertx,也可能通过设置vertx.cacheDirBase系统属性进行定制。完整的类路径处理特性可以通过设置vertx.disableFileCPResolving属性为true显示出来。

注意:这些系统属性在加载io.vertx.core.impl.FileResolver类时仅解析一次,所此属性应当在加载此类之前或者作为加载应用的JVM的系统属性时设置。

 关闭一个AsyncFile

调用close方法关闭AsyncFile。关闭方法是异步的,如果想获取真正的关闭通知,可以指定一个处理器函数作为参数,此处理器将在关闭完成后被调用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值