Java I/O通用api設計 (二)

來源:互聯網
上載者:User

上一篇處理了基本的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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.