本文共 4138 字,大约阅读时间需要 13 分钟。
-- Start
数据从其他地方流入我们的程序叫做输入流, 数据从我们的程序中流到其他地方叫做输出流, 由此可见, 所谓的输入输出是相对我们的程序而言的. Java 用 InputStream 类来表示输入流, 用 OutputStream 类来表示输出流, 由于它们是以字节(byte)为单位处理的, 所以在处理 Unicode 编码的信息时很不方便, 因此, Java 还提供了处理双字节(char)为单位的字符输入流(Reader) 和字符输出流(Writer).
Java I/O 库为我们提供了丰富的流类, 但同时也增大了我们学习的难度, 事实上如果你理解了装饰模式(Decorator), 那么学习 I/O 是非常容易的, 因为大部分流是为了包装另一个流, 从而提供额外的功能. 下面是 Java I/O 库为我们提供的流.
InputStream
ByteArrayInputStream | 从 byte 数组中读取数据 |
FileInputStream | 从文件中读取数据 |
SequenceInputStream | 连接一系列InputStream, 如linux命令 cat a.txt b.txt, 可以一次读取多个文件 |
PipedInputStream | 连接一个PipedOutputStream, 通常一个线程读取数据, 另一个线程输出数据 |
ObjectInputStream | 用来还原一个序列化后的对象 |
BufferedInputStream | 包装另一个InputStream, 提供缓冲功能 |
PushbackInputStream | 包装另一个InputStream, 提供了预查看的功能 |
DataInputStream | 包装另一个InputStream, 以二进制形式读取Java原始数据类型和String |
OutputStream
ByteArrayOutputStream | 将数据输出到byte数组 |
FileOutputStream | 将数据输出到文件 |
PipedOutputStream | 连接一个PipedInputStream, 通常一个线程读取数据, 另一个线程输出数据 |
ObjectOutputStream | 用来序列化对象 |
BufferedOutputStream | 包装另一个OutputStream, 提供缓冲功能 |
DataOutputStream | 包装另一个InputStream, 以二进制形式输出Java原始数据类型和String |
PrintStream | 包装另一个OutputStream, 提供格式化的功能 |
Reader
CharArrayReader | 从 char 数组中读取数据 |
StringReader | 从String变量中读取数据 |
FileReader | 从文件中读取数据 |
BufferedReader | 包装另一个Reader, 提供缓冲功能 |
LineNumberReader | 包装另一个Reader, 提供缓冲和获取行号的功能 |
PushbackReader | 包装另一个Reader, 提供了预查看的功能 |
PipedReader | 连接一个PipedWriter, 通常一个线程读取数据, 另一个线程输出数据 |
InputStreamReader | 将字节输入流转换为字符输入流 |
Writer
CharArrayWriter | 将数据输出到 char 数组中 |
StringWriter | 将数据输出到 String 变量中 |
FileWriter | 将数据输出到文件中 |
BufferedWriter | 包装另一个Writer, 提供缓冲功能 |
PrintWriter | 包装另一个Writer, 提供了格式化的功能 |
PipedWriter | 连接一个PipedReader, 通常一个线程读取数据, 另一个线程输出数据 |
OutputStreamWriter | 将字节输出流转换为字符输出流 |
RandomAccessFile | 提供了随机读写文件的能力 |
通常, 系统与系统之间的交互方式之一是通过 FTP 发送文件, A 系统生成一个文件, 然后通过 FTP 发送给 B 系统, B 系统读取这个文件, 通常文件的格式有分隔符和定长两种, 下面的例子演示了如何输出和读取文件.
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.PrintWriter;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.List;public class Test { public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Service s = new Service(); // 从数据库中获取数据 List--- 更多参见: -- 声 明:转载请注明出处 -- Last Updated on 2012-06-06 -- Written by ShangBo on 2012-06-06 -- Endusers = s.getUsersFromDB(); // 输出数据到文件 // PrintWriter 和 BufferedWriter 包装了 FileWriter, 提供了缓冲和格式化的功能 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("user.csv"))); for (User user : users) { out.printf("%1$s,%2$tF%n", user.getName(), user.getBirthday()); // 分隔符文件 // out.printf("%1$-20s%2$-10tF%n", user.getName(), user.getBirthday()); // 定长文件 } out.close(); // 从文件中读取数据, 然后重新构造成对象 // BufferedReader 包装了 FileReader, 提供了缓冲功能 users.clear(); BufferedReader in = new BufferedReader(new FileReader("user.csv")); String line; while ((line = in.readLine()) != null) { String[] fields = line.split(","); users.add(new User(fields[0].trim(), sdf.parse(fields[1].trim()))); } in.close(); }}class Service { public List getUsersFromDB() { Calendar birthday = Calendar.getInstance(); List users = new ArrayList (); // birthday.set(Calendar.YEAR, 1980); birthday.set(Calendar.MONTH, 0); birthday.set(Calendar.DAY_OF_MONTH, 1); User u1 = new User("ZhangSan", birthday.getTime()); users.add(u1); // birthday.set(Calendar.YEAR, 1990); birthday.set(Calendar.MONTH, 5); birthday.set(Calendar.DAY_OF_MONTH, 4); User u2 = new User("LiSi", birthday.getTime()); users.add(u2); // return users; }}class User { private String name; private Date birthday; public User() { } public User(String name, Date birthday) { this.name = name; this.birthday = birthday == null ? null : (Date) birthday.clone(); // 保护性 copy } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday == null ? null : (Date) birthday.clone(); // 保护性 copy } public void setBirthday(Date birthday) { this.birthday = birthday == null ? null : (Date) birthday.clone(); // 保护性copy }}