• TeeOutputStream 数据流复制


    目的: 数据冗余备份,提高稳定性

    工具类
    http://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/output/TeeOutputStream.html

    自己实现
    参考> https://blog.csdn.net/fanrey123/article/details/84215112

    Develop a parallel multithreaded program (in C using Pthreads, or in Java) that implements the Unix tee command, which is invoked as follows:
    tee filename
    The command reads the standard input and writes it to both the standard output and to the file filename. Your parallel tee program should have three threads: one for reading standard input, one for writing to standard output, and one for writing to file filename.

    思考》
    怎么判断文件读到结尾
    写线程如何停下来
    队列被读两次 信号量的控制

    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    import java.util.concurrent.locks.Lock;
    
    public class TeeTest {
        private static List<String> queue = new ArrayList<>();
        private static boolean EOF = false;
        public static Lock lock = new ReentrantLock();
        public static Condition condOutput = lock.newCondition();
    
        public static Condition condReader = lock.newCondition();
    
        public static int counterFile = 0;
        public static int counterConsole = 0;
    
        public static void main(String[] args) {
            args = new String[2];
            args[0] = "C:\LCT\3.txt";
            args[1] = "C:\LCT\tmp.txt";
            if (args == null || args.length != 2) {
                System.out.println("java Tee <input file> <output file>");
                System.exit(1);
            }
            FileWriterThread fThread = new FileWriterThread(args[1]);
            ConsoleWriterThread cThread = new ConsoleWriterThread();
    
            fThread.start();
            cThread.start();
    
            ReaderThread rThread = new ReaderThread(args[0]);
            rThread.start();
    
        }
    
        static class ReaderThread extends Thread {
            private String fileName;
    
            public ReaderThread(String fileName) {
                this.fileName = fileName;
            }
    
            public void run() {
                BufferedReader in;
                try {
                    in = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
                    String line;
                    while ((line = in.readLine()) != null) {
                        lock.lock();
    
                        queue.add(line);
                        condOutput.signalAll();
                        condReader.await();
                        queue.clear();
                        lock.unlock();
    
                    }
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    EOF = true;
                    lock.lock();
                    condOutput.signalAll();
                    lock.unlock();
                }
    
            }
        }
    
        static class FileWriterThread extends Thread {
            private FileOutputStream out;
            private PrintWriter pw;
    
            public FileWriterThread(String fileName) {
    
                try {
                    out = new FileOutputStream(new File(fileName));
                    pw = new PrintWriter(out);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            public void run() {
                do {
                    lock.lock();
                    if (queue.isEmpty() || counterFile == 1) {
                        try {
                            condOutput.await();
                        } catch (InterruptedException e1) {
    // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }
                    for (Iterator<String> iter = queue.iterator(); iter.hasNext(); ) {
                        String line = iter.next();
    
                        pw.println(line);
                        try {
                            out.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    counterFile++;
    
                    if (counterFile == 1 && counterConsole == 1) {
    
                        queue.clear();
                        counterFile = 0;
                        counterConsole = 0;
                        condReader.signal();
                    }
                    lock.unlock();
                } while (!EOF);
    
                try {
                    pw.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        static class ConsoleWriterThread extends Thread {
    
            public ConsoleWriterThread() {
    
            }
    
            public void run() {
                do {
                    lock.lock();
                    if (queue.isEmpty() || counterConsole == 1) {
                        try {
                            condOutput.await();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    for (Iterator<String> iter = queue.iterator(); iter.hasNext(); ) {
                        System.out.println(iter.next());
                    }
                    counterConsole++;
    
                    if (counterFile == 1 && counterConsole == 1) {
                        queue.clear();
                        counterFile = 0;
                        counterConsole = 0;
                        condReader.signal();
                    }
                    lock.unlock();
                } while (!EOF);
    
            }
        }
    }
    
  • 相关阅读:
    Centos7安装dockercompose
    windows环境下python2和python3版本的切换
    移动硬盘无法读取分区表修复RAW格式修复
    网络与信息安全初探
    MyBatis下在插入数据时获得MySQL自增长序列的值
    CentOS7下mongodb忘记密码后重置密码
    url中有空格等特殊字符及中文字符处理
    通过linux mail实现网站存活监控告警通知
    如何通过SecureCRT转发功能实现外网访问内网服务
    java转JSON串的几种方式
  • 原文地址:https://www.cnblogs.com/yszzu/p/12665266.html
Copyright © 2020-2023  润新知