Java IO 系统(一)

本文深入探讨了Java中File类的应用,包括目录列表器的实现、文件流操作的多种配置及其实现细节。通过具体示例介绍了如何使用File类进行文件和目录的操作,以及如何处理文件输入输出流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

File类

package thinking.in.java.chapter10;

/**
 * File 类有一个欺骗性的名字——通常会认为它对付的是一个文件,但实情并非如此。它既代表一个特定文件
 * 的名字,也代表目录内一系列文件的名字。若代表一个文件集,便可用list()方法查询这个集,返回的是一
 * 个字串数组。之所以要返回一个数组,而非某个灵活的集合类,是因为元素的数量是固定的。而且若想得到
 * 一个不同的目录列表,只需创建一个不同的File 对象即可。事实上,“FilePath”(文件路径)似乎是一个
 * 更好的名字。本节将向大家完整地例示如何使用这个类,其中包括相关的 FilenameFilter(文件名过滤器)
 * 接口。
 */

/**
 * 10.4.1 目录列表器
 * 现在假设我们想观看一个目录列表。可用两种方式列出File 对象。若在不含自变量(参数)的情况下调用
 * list(),会获得 File 对象包含的一个完整列表。然而,若想对这个列表进行某些限制,就需要使用一个“目
 * 录过滤器”,该类的作用是指出应如何选择File 对象来完成显示。
 */
//: DirList.java
// Displays directory listing
import java.io.*;
public class DirList {
    public static void main(String[] args) {
        try {
            File path = new File(".");
            String[] list;
            if(args.length == 0)
                list = path.list();
            else
                list = path.list(new DirFilter(args[0]));
            for(int i = 0; i < list.length; i++)
                System.out.println(list[i]);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
class DirFilter implements FilenameFilter {
    String afn;
    DirFilter(String afn) { this.afn = afn; }
    public boolean accept(File dir, String name) {
        // Strip path information:
        String f = new File(name).getName();
        return f.indexOf(afn) != -1;
    }
} ///:~

在这里插入图片描述
output result:

.git
.gitignore
.idea
.mvn
doc
mvnw
mvnw.cmd
out
pom.xml
readinglist.iml
README.en.md
README.md
src
target

Process finished with exit code 0
package thinking.in.java.chapter10;

/**
 * 下例用一个匿名内部类(已在第7 章讲述)来重写显得非常理想。首先创建了一个filter()方法,它返回指
 * 向FilenameFilter 的一个句柄:
 */
//: DirList2.java
// Uses Java 1.1 anonymous inner classes
import java.io.*;
public class DirList2 {
    public static FilenameFilter
    filter(final String afn) {
        // Creation of anonymous inner class:
        return new FilenameFilter() {
            String fn = afn;
            public boolean accept(File dir, String n) {
                // Strip path information:
                String f = new File(n).getName();
                return f.indexOf(fn) != -1;
            }
        }; // End of anonymous inner class
    }
    public static void main(String[] args) {
        try {
            File path = new File(".");
            String[] list;
            if(args.length == 0)
                list = path.list();
            else
                list = path.list(filter(args[0]));
            for(int i = 0; i < list.length; i++)
                System.out.println(list[i]);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
} ///:~
package thinking.in.java.chapter10;

//: DirList3.java
// Building the anonymous inner class "in-place"
import java.io.*;
public class DirList3 {
    public static void main(final String[] args) {
        try {
            File path = new File(".");
            String[] list;
            if(args.length == 0)
                list = path.list();
            else
                list = path.list(
                        new FilenameFilter() {
                            public boolean
                            accept(File dir, String n) {
                                String f = new File(n).getName();
                                return f.indexOf(args[0]) != -1;
                            }
                        });
            for(int i = 0; i < list.length; i++)
                System.out.println(list[i]);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
} ///:~
package thinking.in.java.chapter10;

//: SortedDirList.java
// Displays sorted directory listing
import thinking.in.java.chapter8.StrSortVector;

import java.io.*;
public class SortedDirList {
    private File path;
    private String[] list;
    public SortedDirList(final String afn) {
        path = new File(".");
        if(afn == null)
            list = path.list();
        else
            list = path.list(
                    new FilenameFilter() {
                        public boolean
                        accept(File dir, String n) {
                            String f = new File(n).getName();
                            return f.indexOf(afn) != -1;
                        }
                    });
        sort();
    }
    void print() {
        for(int i = 0; i < list.length; i++)
            System.out.println(list[i]);
    }
    private void sort() {
        StrSortVector sv = new StrSortVector();
        for(int i = 0; i < list.length; i++)
            sv.addElement(list[i]);
        // The first time an element is pulled from
        // the StrSortVector the list is sorted:
        for(int i = 0; i < list.length; i++)
            list[i] = sv.elementAt(i);
    }
    // Test it:
    public static void main(String[] args) {
        SortedDirList sd;
        if(args.length == 0)
            sd = new SortedDirList(null);
        else
            sd = new SortedDirList(args[0]);
        sd.print();
    }
} ///:~
//这里进行了另外少许改进。不再是将path(路径)和 list(列表)创建为main()的本地变量,它们变成了
//类的成员,使它们的值能在对象“生存”期间方便地访问。事实上,main()现在只是对类进行测试的一种方
//式。大家可以看到,一旦列表创建完毕,类的构建器就会自动开始对列表进行排序。
//这种排序不要求区分大小写,所以最终不会得到一组全部单词都以大写字母开头的列表,跟着是全部以小写
//字母开头的列表。然而,我们注意到在以相同字母开头的一组文件名中,大写字母是排在前面的——这对标
//准的排序来说仍是一种不合格的行为。Java 1.2 已成功解决了这个问题。
Usage:MakeDirectories path1 ...
Creates each path
Usage:MakeDirectories -d path1 ...
Deletes each path
Usage:MakeDirectories -r path1 path2
Renames from path1 to path2


Process finished with exit code 1

IO 流的典型应用

package thinking.in.java.chapter10;

//: IOStreamDemo.java
// Typical IO Stream Configurations
import java.io.*;
//import com.bruceeckel.tools.*;
public class IOStreamDemo {
    public static void main(String[] args) {
        try {
            // 1. Buffered input file
            DataInputStream in =
                    new DataInputStream(
                            new BufferedInputStream(
                                    new FileInputStream(args[0])));
            String s, s2 = new String();
            while((s = in.readLine())!= null)
                s2 += s + "\n";
            in.close();
            // 2. Input from memory
            StringBufferInputStream in2 =
                    new StringBufferInputStream(s2);
            int c;
            while((c = in2.read()) != -1)
                System.out.print((char)c);
            // 3. Formatted memory input
            try {
                DataInputStream in3 =
                        new DataInputStream(
                                new StringBufferInputStream(s2));
                while(true)
                    System.out.print((char)in3.readByte());
            } catch(EOFException e) {
                System.out.println(
                        "End of stream encountered");
            }
            // 4. Line numbering & file output
            try {
                LineNumberInputStream li =
                        new LineNumberInputStream(
                                new StringBufferInputStream(s2));
                DataInputStream in4 =
                        new DataInputStream(li);
                PrintStream out1 =
                        new PrintStream(
                                new BufferedOutputStream(
                                        new FileOutputStream(
                                                "IODemo.out")));
                while((s = in4.readLine()) != null )
                    out1.println(
                            "Line " + li.getLineNumber() + s);
                out1.close(); // finalize() not reliable!
            } catch(EOFException e) {
                System.out.println(
                        "End of stream encountered");
            }
            // 5. Storing & recovering data
            try {
                DataOutputStream out2 =
                        new DataOutputStream(
                                new BufferedOutputStream(
                                        new FileOutputStream("Data.txt")));
                out2.writeBytes(
                        "Here's the value of pi: \n");
                out2.writeDouble(3.14159);
                out2.close();
                DataInputStream in5 =
                        new DataInputStream(
                                new BufferedInputStream(
                                        new FileInputStream("Data.txt")));
                System.out.println(in5.readLine());
                System.out.println(in5.readDouble());
            } catch(EOFException e) {
                System.out.println(
                        "End of stream encountered");
            }
            // 6. Reading/writing random access files
            RandomAccessFile rf =
                    new RandomAccessFile("rtest.dat", "rw");
            for(int i = 0; i < 10; i++)
                rf.writeDouble(i*1.414);
            rf.close();
            rf =
                    new RandomAccessFile("rtest.dat", "rw");
            rf.seek(5*8);
            rf.writeDouble(47.0001);
            rf.close();
            rf =
                    new RandomAccessFile("rtest.dat", "r");
            for(int i = 0; i < 10; i++)
                System.out.println(
                        "Value " + i + ": " +
                                rf.readDouble());
            rf.close();
            // 7. File input shorthand
            InFile in6 = new InFile(args[0]);
            String s3 = new String();
            System.out.println(
                    "First line in file: " +
                            in6.readLine());
            in6.close();
            // 8. Formatted file output shorthand
            PrintFile out3 = new PrintFile("Data2.txt");
            out3.print("Test of PrintFile");
            out3.close();
            // 9. Data file output shorthand
            OutFile out4 = new OutFile("Data3.txt");
            out4.writeBytes("Test of outDataFile\n\r");
            out4.writeChars("Test of outDataFile\n\r");
            out4.close();
        } catch(FileNotFoundException e) {
            System.out.println(
                    "File Not Found:" + args[0]);
        } catch(IOException e) {
            System.out.println("IO Exception");
        }
    }
} ///:~

package thinking.in.java.chapter10;

/**
 * 3. 格式化内存输入
 * StringBufferInputStream 的接口是有限的,所以通常需要将其封装到一个DataInputStream 内,从而增强
 * 它的能力。然而,若选择用readByte()每次读出一个字符,那么所有值都是有效的,所以不可再用返回值来
 * 侦测何时结束输入。相反,可用available()方法判断有多少字符可用。下面这个例子展示了如何从文件中
 * 一次读出一个字符
 */
//: TestEOF.java
// Testing for the end of file while reading
// a byte at a time.
import java.io.*;
public class TestEOF {
    public static void main(String[] args) {
        try {
            DataInputStream in =
                    new DataInputStream(
                            new BufferedInputStream(
                                    new FileInputStream("src/main/java/thinking/in/java/chapter10/TestEOF.java")));
            while(in.available() != 0)
                System.out.print((char)in.readByte());
        } catch (IOException e) {
            System.err.println("IOException");
        }
    }
} ///:~
package thinking.in.java.chapter10;

/**
 * 3. ₩ᅠᄐ¥ᄐマ¥フヨ¥ニナ¥ᆳリ│ᄒモ¥ナᆬ
 * StringBufferInputStream ￧レト₩ホᆬ¥マᆪ₩リᆵ₩ワノ←ルミ￧レト￯ᄐフ₩ノタ¦ᄏᆬ←タレ¥ᄌᄌ←ワタ│ᆭチ¥ᄚニ¥ナᄊ¥ᄚチ│ᆪナ¥ネᄚ¦ᄌタ¦ᄌᆰDataInputStream ¥ニナ￯ᄐフ¦ᄏホ│タフ¥ᄁ゙¥ᄐᄎ
 * ¥ᆴテ￧レト│テᄑ¥ハロ ̄タツ￧トᄊ│タフ￯ᄐフ│ヒᆬ←タノ₩ヒᄅ￧ヤᄄreadByte()₩ᆵマ₩ᆲᄀ│ᆵᄏ¥ヌᄎ¦ᄌタ¦ᄌᆰ¥ᆳラ￧ᆲᆭ￯ᄐフ←ツᆪ¦ᄍネ₩ノタ₩ワノ¥タᄐ←テᄑ₩リᆵ₩ワノ₩ユネ￧レト￯ᄐフ₩ノタ¦ᄏᆬ¦ᄌヘ¥マᆵ¥ニヘ￧ヤᄄ│﾿ヤ¥ロ゙¥タᄐ₩ンᆬ
 * ¦ᄒᆭ₩ᄉヒ¦ᄑユ₩ラᄊ￧ᄏモ₩ン゚│ᄒモ¥ナᆬ ̄タツ￧ロᄌ¥マヘ￯ᄐフ¥マᆵ￧ヤᄄavailable()₩ヨᄍ₩ᄈユ¥ネᄂ₩ヨᆳ₩ワノ¥ᄂレ¥ᄚム¥ᆳラ￧ᆲᆭ¥マᆵ￧ヤᄄ ̄タツ¦ᄌヒ←ンᄁ│﾿ル¦ᄌᆰ¦ᄒヒ¥ᆳミ¥ᄆユ￧ᄂᄎ¦ᄎニ¥ᆭツ¦ᄑユ¦ᄏホ₩ヨヌ¦ᄏᄊ¦ᄌᆳ
 * ¦ᄌタ₩ᆲᄀ│ᆵᄏ¥ヌᄎ¦ᄌタ¦ᄌᆰ¥ᆳラ￧ᆲᆭ
 */
//: TestEOF.java
// Testing for the end of file while reading
// a byte at a time.
import java.io.*;
public class TestEOF {
    public static void main(String[] args) {
        try {
            DataInputStream in =
                    new DataInputStream(
                            new BufferedInputStream(
                                    new FileInputStream("src/main/java/thinking/in/java/chapter10/TestEOF.java")));
            while(in.available() != 0)
                System.out.print((char)in.readByte());
        } catch (IOException e) {
            System.err.println("IOException");
        }
    }
} ///:~
Process finished with exit code 0
/**
 * 7. 快速文件输入
 * 若想创建一个对象,用它从一个缓冲的DataInputStream 中读取一个文件,可将这个过程封装到一个名为
 * InFile 的类内。如下所示:
 */

import java.io.*;
public class InFile extends DataInputStream {
    public InFile(String filename)
            throws FileNotFoundException {
        super(
                new BufferedInputStream(
                        new FileInputStream(filename)));
    }
    public InFile(File file)
            throws FileNotFoundException {
        this(file.getPath());
    }
} ///:~
package thinking.in.java.chapter10;

import java.io.*;

/**
 * 8. 快速输出格式化文件
 * 亦可用同类型的方法创建一个 PrintStream,令其写入一个缓冲文件。下面是对com.bruceeckel.tools 的扩
 * 展:
 */
public class PrintFile extends PrintStream {
    public PrintFile(String filename)
            throws IOException {
        super(
                new BufferedOutputStream(
                        new FileOutputStream(filename)));
    }
    public PrintFile(File file)
            throws IOException {
        this(file.getPath());
    }
} ///:~
package thinking.in.java.chapter10;

import java.io.*;

/**
 * 9. 快速输出数据文件
 * 最后,利用类似的快捷方式可创建一个缓冲输出文件,用它保存数据(与由人观看的数据格式相反):
 */
public class OutFile extends DataOutputStream {
    public OutFile(String filename)
            throws IOException {
        super(
                new BufferedOutputStream(
                        new FileOutputStream(filename)));
    }
    public OutFile(File file)
            throws IOException {
        this(file.getPath());
    }
} ///:~
package thinking.in.java.chapter10;

//: Echo.java
// How to read from standard input
import java.io.*;

/**
 * 10.5.4 从标准输入中读取数据
 * 以Unix 首先倡导的“标准输入”、“标准输出”以及“标准错误输出”概念为基础,Java 提供了相应的
 * System.in,System.out 以及System.err。贯这一整本书,大家都会接触到如何用 System.out 进行标准输
 * 出,它已预封装成一个 PrintStream 对象。System.err 同样是一个 PrintStream,但System.in 是一个原始
 * 的InputStream,未进行任何封装处理。这意味着尽管能直接使用 System.out 和System.err,但必须事先封
 * 装System.in,否则不能从中读取数据。
 * 典型情况下,我们希望用readLine()每次读取一行输入信息,所以需要将System.in 封装到一个
 * DataInputStream 中。这是 Java 1.0 进行行输入时采取的“老”办法。在本章稍后,大家还会看到 Java 1.1
 * 的解决方案。下面是个简单的例子,作用是回应我们键入的每一行内容:
 */
public class Echo {
    public static void main(String[] args) {
        DataInputStream in =
                new DataInputStream(
                        new BufferedInputStream(System.in));
        String s;
        /**
         * 之所以要使用try 块,是由于 readLine()可能“掷”出一个 IOException。注意同其他大多数流一样,也应
         * 对System.in 进行缓冲。
         * 由于在每个程序中都要将System.in 封装到一个 DataInputStream 内,所以显得有点不方便。但采用这种设
         * 计方案,可以获得最大的灵活性。
         */
        try {
            while((s = in.readLine()).length() != 0)
                System.out.println(s);
            // An empty line terminates the program
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
} ///:~
package thinking.in.java.chapter10;

//: SortedWordCount.java
// Counts words in a file, outputs
// results in sorted form.
import thinking.in.java.chapter8.StrSortVector;

import java.io.*;
import java.util.*;

/**
 * 下面是一个简单的程序,用于计算各个单词在文本文件中重复出现的次数:
 */
class Counter {
    private int i = 1;
    int read() { return i; }
    void increment() { i++; }
}
public class SortedWordCount {
    private FileInputStream file;
    private StreamTokenizer st;
    private Hashtable counts = new Hashtable();
    SortedWordCount(String filename)
            throws FileNotFoundException {
        try {
            file = new FileInputStream(filename);
            st = new StreamTokenizer(file);
            st.ordinaryChar('.');
            st.ordinaryChar('-');
        } catch(FileNotFoundException e) {
            System.out.println(
                    "Could not open " + filename);
            throw e;
        }
    }
    void cleanup() {
        try {
            file.close();
        } catch(IOException e) {
            System.out.println(
                    "file.close() unsuccessful");
        }
    }
    void countWords() {
        try {
            while(st.nextToken() !=
                    StreamTokenizer.TT_EOF) {
                String s;
                switch(st.ttype) {
                    case StreamTokenizer.TT_EOL:
                        s = new String("EOL");
                        break;
                    case StreamTokenizer.TT_NUMBER:
                        s = Double.toString(st.nval);
                        break;
                    case StreamTokenizer.TT_WORD:
                        s = st.sval; // Already a String
                        break;
                    default: // single character in ttype
                        s = String.valueOf((char)st.ttype);
                }
                if(counts.containsKey(s))
                    ((Counter)counts.get(s)).increment();
                else
                    counts.put(s, new Counter());
            }
        } catch(IOException e) {
            System.out.println(
                    "st.nextToken() unsuccessful");
        }
    }
    Enumeration values() {
        return counts.elements();
    }
    Enumeration keys() { return counts.keys(); }
    Counter getCounter(String s) {
        return (Counter)counts.get(s);
    }
    Enumeration sortedKeys() {
        Enumeration e = counts.keys();
        StrSortVector sv = new StrSortVector();
        while(e.hasMoreElements())
            sv.addElement((String)e.nextElement());
        // This call forces a sort:
        return sv.elements();
    }
    public static void main(String[] args) {
        try {
            SortedWordCount wc =
                    new SortedWordCount(args[0]);
            wc.countWords();
            Enumeration keys = wc.sortedKeys();
            while(keys.hasMoreElements()) {
                String key = (String)keys.nextElement();
                System.out.println(key + ": "
                        + wc.getCounter(key).read());
            }
            wc.cleanup();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
} ///:~

package thinking.in.java.chapter8;

//: StrSortVector.java
// Automatically sorted Vector that
// accepts and produces only Strings
import java.util.*;
public class StrSortVector {
    private SortVector v = new SortVector(
            // Anonymous inner class:
            new Compare() {
                public boolean
                lessThan(Object l, Object r) {
                    return
                            ((String)l).toLowerCase().compareTo(
                                    ((String)r).toLowerCase()) < 0;
                }
                public boolean
                lessThanOrEqual(Object l, Object r) {
                    return
                            ((String)l).toLowerCase().compareTo(
                                    ((String)r).toLowerCase()) <= 0;
                }
            }
    );
    private boolean sorted = false;
    public void addElement(String s) {
        v.addElement(s);
        sorted = false;
    }
    public String elementAt(int index) {
        if(!sorted) {
            v.sort();
            sorted = true;
        }
        return (String)v.elementAt(index);
    }
    public Enumeration elements() {
        if(!sorted) {
            v.sort();
            sorted = true;
        }
        return v.elements();
    }
    // Test it:
    public static void main(String[] args) {
        StrSortVector sv = new StrSortVector();
        sv.addElement("d");
        sv.addElement("A");
        sv.addElement("C");
        sv.addElement("c");
        sv.addElement("b");
        sv.addElement("B");
        sv.addElement("D");
        sv.addElement("a");
        Enumeration e = sv.elements();
        while(e.hasMoreElements())
            System.out.println(e.nextElement());
    }
} ///:~
package thinking.in.java.chapter10;

//: AnalyzeSentence.java
// Look for particular sequences
// within sentences.
import java.util.*;
public class AnalyzeSentence {
    public static void main(String[] args) {
        analyze("I am happy about this");
        analyze("I am not happy about this");
        analyze("I am not! I am happy");
        analyze("I am sad about this");
        analyze("I am not sad about this");
        analyze("I am not! I am sad");
        analyze("Are you happy about this?");
        analyze("Are you sad about this?");
        analyze("It's you! I am happy");
        analyze("It's you! I am sad");
    }
    static StringTokenizer st;
    static void analyze(String s) {
        prt("\nnew sentence >> " + s);
        boolean sad = false;
        st = new StringTokenizer(s);
        while (st.hasMoreTokens()) {
            String token = next();
            // Look until you find one of the
            // two starting tokens:
            if(!token.equals("I") &&
                    !token.equals("Are"))
                continue; // Top of while loop
            if(token.equals("I")) {
                String tk2 = next();
                if(!tk2.equals("am")) // Must be after I
                    break; // Out of while loop
                else {
                    String tk3 = next();
                    if(tk3.equals("sad")) {
                        sad = true;
                        break; // Out of while loop
                    }
                    if (tk3.equals("not")) {
                        String tk4 = next();
                        if(tk4.equals("sad"))
                            break; // Leave sad false
                        if(tk4.equals("happy")) {
                            sad = true;
                            break;
                        }
                    }
                }
            }
            if(token.equals("Are")) {
                String tk2 = next();
                if(!tk2.equals("you"))
                    break; // Must be after Are
                String tk3 = next();
                if(tk3.equals("sad"))
                    sad = true;
                break; // Out of while loop
            }
        }
        if(sad) prt("Sad detected");
    }
    static String next() {
        if(st.hasMoreTokens()) {
            String s = st.nextToken();
            prt(s);
            return s;
        }
        else
            return "";
    }
    static void prt(String s) {
        System.out.println(s);
    }
} ///:~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值