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);

        }
    }
}
posted @ 2020-04-09 10:46  funny_coding  阅读(971)  评论(0编辑  收藏  举报
build beautiful things, share happiness