Java I/O通用api设计 (二)
来源:互联网 发布:淘宝 百科 编辑:程序博客网 时间:2024/06/07 12:03
上一篇处理了基本的I/O传输,我们常常还要做些其它的事。可能要计数一下传输了多少个数据,过滤一下数据,或者是每1000条数据做一下日志,又或者要看一下正在进行什么操作。既然输入输出已经分离,这些事变成在输入输出的协调代码中简单地插入一些逻辑。大部分协调代码有类似的功能,可以放到标准的工具方法中,更方便使用。
第一个标准修饰器是一个过滤器。实现时我用到了Specification。
public interface Specification<T> { boolean test(T item);}
从上一篇可以看到最后的操作是
Inputs.text(source).transferTo(Outputs.text(destination));要做其他事情只能对Output进行增强。因为sender和receiver都是通过他来调用的,同样的需要对这两个进行增强。
public class Filters { static class SpecificationOutputWrapper<T, ReceiverThrowableType extends Throwable> implements Output<T, ReceiverThrowableType> { final Output<T, ReceiverThrowableType> output; final Specification<T> specification; public SpecificationOutputWrapper(Output<T, ReceiverThrowableType> output, Specification<T> specification) { this.output = output; this.specification = specification; } public <SenderThrowableType extends Throwable> void receiveFrom(Sender<T, SenderThrowableType> sender) throws ReceiverThrowableType, SenderThrowableType { output.receiveFrom(new SpecificationSenderWrapper<T, SenderThrowableType>(sender, specification)); } } static class SpecificationSenderWrapper<T, SenderThrowableType extends Throwable> implements Sender<T, SenderThrowableType> { final Sender<T, SenderThrowableType> sender; final Specification<T> specification; public SpecificationSenderWrapper(Sender<T, SenderThrowableType> sender, Specification<T> specification) { this.sender = sender; this.specification = specification; } public <ReceiverThrowableType extends Throwable> void sendTo(Receiver<T, ReceiverThrowableType> receiver) throws ReceiverThrowableType, SenderThrowableType { sender.sendTo(new SpecificationReceiverWrapper<T, ReceiverThrowableType>(receiver, specification)); } } static class SpecificationReceiverWrapper<T, ReceiverThrowableType extends Throwable> implements Receiver<T, ReceiverThrowableType> { final Receiver<T, ReceiverThrowableType> receiver; final Specification<T> specification; public SpecificationReceiverWrapper(Receiver<T, ReceiverThrowableType> receiver, Specification<T> specification) { this.receiver = receiver; this.specification = specification; } public void receive(T item) throws ReceiverThrowableType { if(specification.test(item)) { receiver.receive(item); } } public void finished() throws ReceiverThrowableType { receiver.finished(); } } public static <T, ReceiverThrowableType extends Throwable> Output<T, ReceiverThrowableType> filter(Specification<T> specification, final Output<T, ReceiverThrowableType> output) { return new SpecificationOutputWrapper<T, ReceiverThrowableType>(output, specification); }}
测试代码:
public class Demo_Intercept_FilterLine { public static void main(String[] args) throws IOException { File source = new File("in"); File destination = new File("out"); Input<String, IOException> input = Inputs.text(source); Output<String, IOException> output = Outputs.text(destination); Specification<String> specification = new Specification<String>() { public boolean test(String item) { if(item.trim().length() == 0) return false; // 过滤空行 return true; } }; input.transferTo(Filters.filter(specification, output)); }}
第二个常见的操作是把数据从一个类型映射到另一个类型。就是处理要Input和Output的数据类型不同,要有方法把输入数据类型映射成输出的数据类型。下面例子的把String映射成JSONObject,先定义转换方法:
public interface Function<From, To> { /** * @return return the transformed data. {@code null} to indicate ignore the input data. */ To map(From from);}剩下的基本和上面的类似
public class FunctionFilter { private FunctionFilter(){} static class FunctionOutputWrapper<From, To, ReceiverThrowableType extends Throwable> implements Output<From, ReceiverThrowableType> { final Output<To, ReceiverThrowableType> output; final Function<From, To> function; public FunctionOutputWrapper(Output<To, ReceiverThrowableType> output, Function<From, To> function) { this.output = output; this.function = function; } public <SenderThrowableType extends Throwable> void receiveFrom(Sender<From, SenderThrowableType> sender) throws ReceiverThrowableType, SenderThrowableType { output.receiveFrom(new FunctionSenderWrapper<From, To, SenderThrowableType>(sender, function)); } } static class FunctionSenderWrapper<From, To, SenderThrowableType extends Throwable> implements Sender<To, SenderThrowableType> { final Sender<From, SenderThrowableType> sender; final Function<From, To> function; public FunctionSenderWrapper(Sender<From, SenderThrowableType> sender, Function<From, To> function) { this.sender = sender; this.function = function; } public <ReceiverThrowableType extends Throwable> void sendTo(Receiver<To, ReceiverThrowableType> receiver) throws ReceiverThrowableType, SenderThrowableType { sender.sendTo(new FunctionReceiverWrapper<From, To, ReceiverThrowableType>(receiver, function)); } } static class FunctionReceiverWrapper<From, To, ReceiverThrowableType extends Throwable> implements Receiver<From, ReceiverThrowableType> { final Receiver<To, ReceiverThrowableType> receiver; final Function<From, To> function; public FunctionReceiverWrapper(Receiver<To, ReceiverThrowableType> receiver, Function<From, To> function) { this.receiver = receiver; this.function = function; } public void receive(From item) throws ReceiverThrowableType { receiver.receive(function.map(item)); } public void finished() throws ReceiverThrowableType { receiver.finished(); } } public static <From, To, ReceiverThrowableType extends Throwable> Output<From, ReceiverThrowableType> filter(Function<From, To> function, final Output<To, ReceiverThrowableType> output) { return new FunctionOutputWrapper<From, To, ReceiverThrowableType>(output, function); }}
测试代码:
public class Demo_Intercept_CountLine { public static void main(String[] args) throws IOException { File source = new File("in"); File destination = new File("out"); final AtomicInteger count = new AtomicInteger(); Input<String, IOException> input = Inputs.text(source); Output<String, IOException> output = Outputs.text(destination); Function<String, String> function = new Function<String, String>() { public String map(String from) { count.incrementAndGet(); return from; } }; input.transferTo(FunctionFilter.filter(function, output)); System.out.println("Counter: " + count.get()); }}
转载自:https://github.com/oldratlee/io-api/wiki/generic-io-api-in-java-and-api-design
- Java I/O通用api设计 (二)
- Java I/O通用api设计 (一)
- 通用I/O模块设计
- JAVA API备忘----I/O
- java API 文件,I/O
- 初级 Java I/O 综述(二)
- JAVA的I/O操作(二)
- Java I/O (二)流类
- Java I/O总结(二)
- Java进击(二) I/O流
- java I/O学习(二)
- Java I/O体系(二)
- Java基础I/O流(二)
- java i/o 学习总结(二)
- Java I/O 学习总结(二)
- Java I/O 知识点(二)
- Java I/O流总结(二)
- 标准库I/O vs linux api I/O全面比较 系列2-------POSIX通用异步库AIO(1)
- 下载文件名出现乱码
- 【leetcode】Word Ladder
- struts1配置文件详解
- 管道、FIFO以及共享内存
- Ubuntu下设置adb环境变量
- Java I/O通用api设计 (二)
- 第八周项目2
- 情景模式
- Android::wifi热点问题
- n个元素进栈,共有多少种出栈顺序?
- Gaming Tweak - Disable Nagle's algorithm
- 我为什么开发EasyJS类库-一个更改JS编程风格的类库
- 【windows】套接口编程 - 包含winsock2.h的重定义问题
- hdu 3605 最大流