java编程思想读书笔记 第十八章 java I/O系统(第三篇)

1. 文件读写的工具
一一个很常见的程序化的任务就是读取文件到内存,修改,然后再写出。java I/O类库的问题之一就是:它需要编写相当多的代码去执行这些常用的工作–没有任何基本的帮助功能可以为我们做这一切。下面的例子是被用来简化对文件的读写操作。它包含的static方法可以向简单字符串那样写文本文件,并且可以创建一个TextFile对象,它用一个ArrayList来保存文件的若干行。

public class TextFile extends ArrayList {

    public static String read(String fileName) {
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader in = new BufferedReader(new FileReader(new File(
                    fileName).getAbsoluteFile()));
            try {
                String s;
                while ((s = in.readLine()) != null) {
                    sb.append(s);
                    sb.append("n");
                }
            } finally {

                in.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return sb.toString();
    }


    public static void write(String fileName, String text) {
        try {
            PrintWriter out = new PrintWriter(
                    new File(fileName).getAbsoluteFile());
            try {
                out.print(text);
            } finally {
                out.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public TextFile(String fileName, String splitter) {
        super(Arrays.asList(read(fileName).split(splitter)));

        if (get(0).equals(""))
            remove(0);
    }


    public TextFile(String fileName) {
        this(fileName, "n");
    }

    public void write(String fileName) {
        try {
            PrintWriter out = new PrintWriter(
                    new File(fileName).getAbsoluteFile());
            try {
                for (String item : this)
                    out.println(item);
            } finally {
                out.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public static void main(String[] args) {
        String file = read("文件路径");
        write("test.txt", file);
        TextFile text = new TextFile("test.txt");
        text.write("test2.txt");        
        TreeSet words = new TreeSet(new TextFile("文件路径", "\\W+"));      
        System.out.println(words.headSet("a"));
    }

read()将每行添加到StringBuffer,并且为每行加上换行符,因为在读的过程中换行符会被取出掉。接着返回一个包含整个文件的字符串。write()打开文本并将其写入文件。在这两个方法中,都要注意close()关闭文件。注意,在任何打开文件的代码在finally子句中,都需要添加close()方法,以保证文件都会被正确关闭。

1.1读取二进制文件
下面的的工具类与TextFile类似,因为它简化了读取二进制文件的过程:

public class BinaryFile {

    public static byte[] read(File bFile) throws IOException{
        BufferedInputStream bf = new BufferedInputStream(new FileInputStream(bFile));
        try {
            byte[] data = new byte[bf.available()];
            bf.read(data);
            read(bFile);
            return data;
        } finally{
            bf.close();
        }
    }
    public static byte[] read(String bFile) throws IOException{
        return read(new File(bFile).getAbsoluteFile());
    }
}

其中一个重载方法接受File参数,第二个重载方法接受表示文件名的String参数。这两个方法都返回产生的byte数组。available()方法被用来产生恰当的数组尺寸,并且reade()方法的特定的重载版本填充了这个数字。

2. 标准I/O类库
程序的所有输入都可以来自于标准输入,它的所有输出都可以发送到标准输出,以及所有的错误信息都可以发送到标准准成。标准I/O的一样在于:我们可以很容易地把程序串联起来,一个程序的标准输出可以称为另一程序的标准输入。

2.1从标准输入中读取
System.out已经事先被包装成了PrintStream对象。System.err同样也是PrintStream,但System.in却是一个没有被包装过的未经加工的InputStream。这意味着尽管我们可以立即使用System.out和System.err,但是在读取System.in之前必须对其进行包装。例如:

 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
 stdin.readLine();

System.in和大多数流一样,通常应该对它进行缓冲。

2.2将System.out转换成PrintWriter
PrintWriter有一个可以接受OutputStream作为参数的构造器。因此只要需要,就可以使用那个构造器把System.out转换成PrintWriter;示例:PrintWriter out = new PrintWriter(System.out, true);注意:第二个参数设为true,表示开启自动清空功能。

2.3 标准的I/O重定向
Java的System类允许我们对标准输入、输出和错误I/O流进行重定向

setIn(InputStream)
setOut(PrintStream)
setErr(PrintStream)

注意:I/O重定向操作的是字节流,而不是字符流,因为我们使用的是InputStream和OutputStream,而不是Reader和Writer。

3. 进程控制
你经常会需要在java内部执行其他操作系统的程序,并且要控制这些程序的输入和输出。java类库提供了执行这些操作的类。

public class OSExecute {
    public static void command(String command) {
        boolean err = false;
        try {
            Process process = new ProcessBuilder(command.split("")).start();
            BufferedReader results = new BufferedReader(new InputStreamReader(
                    process.getInputStream()));
            String s;
            while ((s = results.readLine()) != null)
                System.out.println(s);
            BufferedReader errors = new BufferedReader(new InputStreamReader(
                    process.getErrorStream()));
            while ((s = errors.readLine()) != null) {
                System.err.println(s);
                err = true;
            }
        } catch (Exception e) {
            if (!command.startsWith("CMD /C")) {

                command("CMD /C" + command);
            } else {

                throw new RuntimeException(e);
            }
        }
        if (err)
            throw new OSExecuteException("Errors executing" + command);
    }

    public static void main(String[] args) {
        OSExecute.command("文件路径");
    }
}

要运行一个程序,你需要向OSExecute.command()传递一个command字符串,它与你在控制台上运行该程序所键入的命令相同。这个命令被传递给java.lang.ProcessBuidler构造器,然后所产生的ProcessBuidler对象被启动。为了捕获执行时产生的标准输出流,你需要调用getInputStream(),这是因为InputStream是我们可以从中读取信息的流。从程序中产生的结果每次输出一行,因此要使用readLine()来读取。

你可能感兴趣的:(java编程思想读书笔记)