黑马程序员-IO(2)

来源:互联网 发布:软件打不开是怎么了 编辑:程序博客网 时间:2024/06/06 01:49

---------------------android培训、java培训、期待与您交流! -------------------------

字节流:

开发中常用的字节流对象体系:


原始流copy示例:

@Testpublic void copyFile() {InputStream in = null;OutputStream out = null;try {in = new FileInputStream("src");out = new FileOutputStream("dest");byte[] buf = new byte[1024];int len = -1;while ((len = in.read(buf)) != -1) {out.write(buf, 0, len);}} catch (IOException e) {//Exception处理e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}

经过FilterInputStream FilterOutputStream 子类装饰的原始流:

@Testpublic void copyFile() {InputStream in = null;OutputStream out = null;try {//除了以下两句,其他的都与原始流处理相同in = new BufferedInputStream(new FileInputStream("src"));out = new BufferedOutputStream(new FileOutputStream("dest"));byte[] buf = new byte[1024];int len = -1;while ((len = in.read(buf)) != -1) {out.write(buf, 0, len);out.flush();//缓冲流一般需要flush}} catch (IOException e) {//Exception处理e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}

字符流:

开发中常用的字符流对象:


字符流使用示例:

/** * 按行读取文件中的内容到控制台 */@Testpublic void readLines() {BufferedReader in = null;PrintWriter out = null;try {in = new BufferedReader(new FileReader("srca"));out = new PrintWriter(System.out, true);//注意第二个参数, 自动刷新, 否则需要手动flushString line = null;while ((line = in.readLine()) != null) {out.println(line);}} catch (IOException e) {//实际应用时, 按需加入相应的处理e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (out != null) {out.close();}}}
/** *从控制台读取数据到文件中 */@Testpublic void test2() {Scanner in = null;BufferedWriter out = null;try {in = new java.util.Scanner(System.in);out = new BufferedWriter(new FileWriter("out.data"));String line = null;while (in.hasNextLine()) {line = in.nextLine();out.write(line);out.newLine();out.flush();}} catch (IOException e) {//实际应用时, 按需加入相应的处理e.printStackTrace();} finally {if (in != null) {in.close();}if (out != null) {try {out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

流式对象综合应用:

原始数据类型IO操作:

Java Tutorials中Data Stream 操作示例

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.IOException;import java.io.EOFException; public class DataStreams {    static final String dataFile = "invoicedata";     static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };    static final int[] units = { 12, 8, 13, 29, 50 };    static final String[] descs = { "Java T-shirt",            "Java Mug",            "Duke Juggling Dolls",            "Java Pin",            "Java Key Chain" };     public static void main(String[] args) throws IOException {           DataOutputStream out = null;                 try {            out = new DataOutputStream(new                    BufferedOutputStream(new FileOutputStream(dataFile)));             for (int i = 0; i < prices.length; i ++) {                out.writeDouble(prices[i]);                out.writeInt(units[i]);                out.writeUTF(descs[i]);            }        } finally {            out.close();        }         DataInputStream in = null;        double total = 0.0;        try {            in = new DataInputStream(new                    BufferedInputStream(new FileInputStream(dataFile)));             double price;            int unit;            String desc;             try {                while (true) {                    price = in.readDouble();                    unit = in.readInt();                    desc = in.readUTF();                    System.out.format("You ordered %d units of %s at $%.2f%n",                            unit, desc, price);                    total += unit * price;                }            } catch (EOFException e) { }            System.out.format("For a TOTAL of: $%.2f%n", total);        }        finally {            in.close();        }    }}

复杂对象IO操作:

使用Object Stream 读写的对象需要实现Serialization接口。但有一点需要注意由static, transient修饰的字段不可以保存。
以下是Java tutorials 中给出的示例代码:

import java.io.*;import java.math.BigDecimal;import java.util.Calendar; public class ObjectStreams {    static final String dataFile = "invoicedata";     static final BigDecimal[] prices = {         new BigDecimal("19.99"),         new BigDecimal("9.99"),        new BigDecimal("15.99"),        new BigDecimal("3.99"),        new BigDecimal("4.99") };    static final int[] units = { 12, 8, 13, 29, 50 };    static final String[] descs = { "Java T-shirt",            "Java Mug",            "Duke Juggling Dolls",            "Java Pin",            "Java Key Chain" };     public static void main(String[] args)         throws IOException, ClassNotFoundException {           ObjectOutputStream out = null;        try {            out = new ObjectOutputStream(new                    BufferedOutputStream(new FileOutputStream(dataFile)));             out.writeObject(Calendar.getInstance());            for (int i = 0; i < prices.length; i ++) {                out.writeObject(prices[i]);                out.writeInt(units[i]);                out.writeUTF(descs[i]);            }        } finally {            out.close();        }         ObjectInputStream in = null;        try {            in = new ObjectInputStream(new                    BufferedInputStream(new FileInputStream(dataFile)));             Calendar date = null;            BigDecimal price;            int unit;            String desc;            BigDecimal total = new BigDecimal(0);             date = (Calendar) in.readObject();             System.out.format ("On %tA, %<tB %<te, %<tY:%n", date);             try {                while (true) {                    price = (BigDecimal) in.readObject();                    unit = in.readInt();                    desc = in.readUTF();                    System.out.format("You ordered %d units of %s at $%.2f%n",                            unit, desc, price);                    total = total.add(price.multiply(new BigDecimal(unit)));                }            } catch (EOFException e) {}            System.out.format("For a TOTAL of: $%.2f%n", total);        } finally {            in.close();        }    }}

以下是java tutorials 中对读写复杂对象时注意事项的描述。

Output and Input of Complex Objects

The writeObject and readObject methods are simple to use, but they contain some very sophisticated object management logic. This isn't important for a class like Calendar, which just encapsulates primitive values. But many objects contain references to other objects. IfreadObject is to reconstitute an object from a stream, it has to be able to reconstitute all of the objects the original object referred to. These additional objects might have their own references, and so on. In this situation, writeObject traverses the entire web of object references and writes all objects in that web onto the stream. Thus a single invocation of writeObject can cause a large number of objects to be written to the stream.

This is demonstrated in the following figure, where writeObject is invoked to write a single object named a. This object contains references to objects b and c, while b contains references to d and e. Invoking writeobject(a) writes not just a, but all the objects necessary to reconstitute a, so the other four objects in this web are written also. When a is read back by readObject, the other four objects are read back as well, and all the original object references are preserved.

I/O of multiple referred-to objects

I/O of multiple referred-to objects

You might wonder what happens if two objects on the same stream both contain references to a single object. Will they both refer to a single object when they're read back? The answer is "yes." A stream can only contain one copy of an object, though it can contain any number of references to it. Thus if you explicitly write an object to a stream twice, you're really writing only the reference twice. For example, if the following code writes an object ob twice to a stream:

Object ob = new Object();out.writeObject(ob);out.writeObject(ob);

Each writeObject has to be matched by a readObject, so the code that reads the stream back will look something like this:

Object ob1 = in.readObject();Object ob2 = in.readObject();

This results in two variables, ob1 and ob2, that are references to a single object.

However, if a single object is written to two different streams, it is effectively duplicated — a single program reading both streams back will see two distinct objects.

字节流与字符流之间的转换:

相关API:

ConstructorsConstructor and DescriptionInputStreamReader(InputStream in)
Creates an InputStreamReader that uses the default charset.
InputStreamReader(InputStream in, Charset cs)
Creates an InputStreamReader that uses the given charset.
InputStreamReader(InputStream in, CharsetDecoder dec)
Creates an InputStreamReader that uses the given charset decoder.
InputStreamReader(InputStream in, String charsetName)
Creates an InputStreamReader that uses the named charset.
ConstructorsConstructor and DescriptionOutputStreamWriter(OutputStream out)
Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs)
Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName)
Creates an OutputStreamWriter that uses the named charset.

InputStreamReaderOutputStreamWriter充当字符流与字节流之间的桥梁。默认情况下,字符流以(file.encoding=GBK)为编码方式。通过这两个对象,我们可以指定自己的编码方式。
测试代码如下:

try(OutputStreamWriter w= new OutputStreamWriter(new FileOutputStream("dest"), "utf-8")) {w.write("测试");} catch (Exception e) {System.out.println(e.getMessage());}//UE打开输出文件,以十六进制查看:00000000h: E6 B5 8B E8 AF 95                               ; 娴嬭瘯byte[] buf = "测试".getBytes("utf-8");for (int i = 0; i < buf.length; i++) {System.out.format("%X ", buf[i]);}//Output: E6 B5 8B E8 AF 95//可以改变编码方式, 对比结果 

---------------------android培训、java培训、期待与您交流! -------------------------

0 0
原创粉丝点击