码迷,mamicode.com
首页 > 编程语言 > 详细

Java IO

时间:2016-06-13 13:11:36      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:

一、概述

Java IO是Java用来读写数据(输入和输出)的API。这里主要介绍以下几点内容:

①,Java流式输入/输出
②,Java流类的分类
③,输入/输出流类
④,常见的节点流和处理流
⑤,文件流
⑥,缓冲流
⑦,数据流
⑧,转换流
⑨,Print流
,Object流

二、Java流式输入和输出

在Java程序中,对于数据的输入输出操作以"流"(Stream)方式进行;J2SDK提供了各种各样的"流"类,用以获取不同种类的数据;程序中通过标准的方法输入或输出数据。各类用途汇总如下:

 

  • 文件访问
  • 网络访问
  • 内存缓存访问
  • 线程内部通信(管道)
  • 缓冲
  • 过滤
  • 解析
  • 读写文本 (Readers / Writers)
  • 读写基本类型数据 (long, int etc.)
  • 读写对象

技术分享

 

三、Java流的分类

java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能。可以从不同的角度对其进行分类:

 

  • 按数据流的方向不同可以分为输入流和输出流;
  • 按处理数据单位不同可以分为字节流和字符流(一个字节1 byte=8 bits,一个字符Unicode=2字节);
  • 按照功能不同可以分为节点流和处理流;

输入和输出:四个抽象类(凡是Stream结尾的否是字节流)

  字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

 

 

 

 

节点流和处理流:

节点流为可以从一个特定的数据源(节点)读写数据(比如:文件,内存)

技术分享

处理流是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能:

技术分享

四、InputStream & OutputStream,Reader & Writer

①,InputStream

继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(byte,8bits),下图中深色为节点流,浅色为处理流。

技术分享

InputStream的基本方法:

//读取一个字节并以整数的形式返回(0~255)
//如果返回-1表示已到输入流的末尾
int read() throws IOException

//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
int read(byte[] buffer) throws IOException

//读取length个字节
//并存储到一个字节数组buffer,从length位置开始
//返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
int read(byte[] buffer, int offset, int length) throws IOException

//关闭流释放内存资源
void close() throws IOException

//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

 ②,OutputStream

继承自OutputStream的流是用于从程序中输出数据,切数据的单位是字节(byte,8bits),下图中深色为节点流,浅色为处理流。

技术分享

OutputStream的基本方法:

//向输出流中写入一个字节数据,该字节数据位参数b的低8位
void write(int b) throws IOException

//将一个字节类型的数组中的数据写入输出流
void writer(byte[] b) throws IOException

//将一个字节类型的数组中的数据从指定位置(off)开始len个字节写入到输出流
void write(byte[] b, int off, int len) throws IOException

//关闭流释放内存资源
void close() throws IOException

//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

 

 ③,Reader

继承自Reader的流都是用于向程序中输入数据,且数据的单位是字符(16bits,例如一个中文是两个字节表示);下图中深色为节点流,浅色为处理流:

技术分享

Reader的基本方法

//读取一个字符并以整数的形式返回(0~255)
//如果返回-1表示已到输入流的末尾
int read() throws IOException

//读取一系列字符并存储到一个数组buffer
//返回实际读取的字符数,如果读取前已到输入流的末尾返回-1表示已到输入流的末尾
int read(char[] cbuf) throws IOException

//读取length个字符
//并存储到一个数组buffer,从length位置开始
//返回实际读取的字符数,如果读取前已到输入流的末尾返回-1表示已到输入流的末尾
int read(char[] cbuf, int offset, int length) throws IOException

//关闭流释放内存资源
void close() throws IOException

//跳过n个字符不读,返回实际跳过的字节数
long skip(long n) throws IOException

 

④,Writer

继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16bits);下图中深色为节点流,浅色为处理流:

技术分享

Writer基本方法:

 

//向输出流中写入一个字符数据,该字符数据为参数c的低16位
void write(int c) throws IOException

//将一个字符类型的数组中的数据写入输出流
void writer(char[] cbuf) throws IOException

//将一个字符类型的数组中的数据从指定位置(offset)开始len个字节写入到输出流
void write(char[] cbuf, int offset, int len) throws IOException

//将一个字符串中的字符写入到输出流
void write(String string) throws IOException

//将一个字符串从offset开始的length个字符写入到输出流
void write(String string, int offset, int length) throws IOException

//关闭流释放内存资源
void close() throws IOException

//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

 

五、常用的节点流和处理流

①,节点流类型

类型

  字符流 字节流
File(文件)

FileReader

FileWriter

FileInputStream

FileOutputStream

Memory Array

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

Memory String

StringReader

StringWriter

---
Pipe(管道,线程)

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream

 

 

 

 

 

 

 

 

 

 

File(访问文件)

FileInputStream和FileOutputStream分别继承自OutputStream和OutputStream,用于向文件中输入和输出字节。

FileInputStream和FileOutputStream的构造方法:

FileInputStream:
FileInputStream(File file)
Creates a FileInputStream by opening a connection to an actual file, the file named by the File object file in the file system.
FileInputStream(FileDescriptor fdObj)
Creates a FileInputStream by using the file descriptor fdObj, which represents an existing connection to an actual file in the file system.
FileInputStream(String name)
Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system.

OutputStream:
FileOutputStream(File file)
Creates a file output stream to write to the file represented by the specified File object.
FileOutputStream(File file, boolean append)
Creates a file output stream to write to the file represented by the specified File object.
FileOutputStream(FileDescriptor fdObj)
Creates a file output stream to write to the specified file descriptor, which represents an existing connection to an actual file in the file system.
FileOutputStream(String name)
Creates a file output stream to write to the file with the specified name.
FileOutputStream(String name, boolean append)
Creates a file output stream to write to the file with the specified name.

FileInputStream和FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法。

注意:

在实例化FileInputStream和FileOutputStream时要用ty-catch语句加以处理,因为可能抛出FileNotFoundException。

在读写数据时也要用try-catch语句加以处理,因为可能抛出IOException。

例子:

1,FileInputStream & FileOutputStream

FileInputStream

    public static void main(String[] args) {
        int b = 0;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java");
        } catch (FileNotFoundException e) {
            System.out.println("找不到指定文件");
            System.exit(-1);
        }
        
        try {
            long num = 0;
            while((b = fis.read()) != -1) {
                System.out.print((char)b);
                num++;
            }
            fis.close();
            System.out.println("共读取了" + num + "个字节");
        } catch (IOException e) {
            System.out.println("文件读取错误");
            System.exit(-1);
        }
    }

结果:对于中文乱码,因为是一个字节一个字节的读取,所以只读取了半个中文

控制台输出:
import java.io.*;
public class TestFileInputStream {
  public static void main(String[] args) {
    int b = 0;
    FileInputStream in = null;
    try {
      in = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java");
    } catch (FileNotFoundException e) {
      System.out.println("ÕÒ²»µ½Ö¸¶¨Îļþ");
      System.exit(-1);
    }
    
    try {
      long num = 0;
      while((b=in.read())!=-1){
        System.out.print((char)b); 
        num++;
      }
      in.close();  
      System.out.println();
      System.out.println("¹²¶ÁÈ¡ÁË "+num+" ¸ö×Ö½Ú");
    } catch (IOException e1) {
      System.out.println("Îļþ¶ÁÈ¡´íÎó"); System.exit(-1);
    }
  }
}共读取了700个字节

FileOutputStream:

    public static void main(String[] args) {
        int b = 0;
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("d:/share/java/HelloWorld.java");
            fos = new FileOutputStream("d:/share/java/io/HW.java");//没有回自动新建一个文件
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
            fis.close();
            fos.close();
        } catch (FileNotFoundException e) {
            System.out.println("找不到指定的文件");
            System.exit(-1);
        } catch (IOException e) {
            System.out.println("文件复制错误");
            System.exit(-1);
        }
        System.out.println("文件已复制");
    }

输出:可以在d:/share/java/io中看到复制的文件HW.java

2,FileReader & FileWriter

FileReader:

    public static void main(String[] args) {
        int c = 0;
        FileReader fr = null;
        try {
            fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java");
            while((c = fr.read()) != -1) {
                System.out.print((char)c);
            }
            fr.close();
        } catch (FileNotFoundException e) {
            System.out.println("找不到指定文件");
        } catch (IOException e) {
            System.out.println("读取文件出错");
        }
    }

FileWriter:

例一:

    public static void main(String[] args) {
        FileWriter fw = null;
        try {
            fw = new FileWriter(new File("d:\\unicode.dat"));
            for(int i = 0; i <= 50000; i++) {//char最大为65535
                fw.write(i);
            }
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件写入错误");
            System.exit(-1);
        }
    }

结果:D盘中的unicode.dat文件中的内容。

技术分享

例二:

    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("d:/java/io/TestFileWriter2.java");
        FileWriter fw = new FileWriter("d:/java/io/TestFileWriter2.bak");
        int b;
        while((b = fr.read()) != -1) {
            fw.write(b);
        }
        fr.close();
        fw.close();
    }

 

②,处理流

处理流需要套接在节点流和其他处理流之上使用

处理类型 字符流 字节流
Buffering

BufferReader

BufferWriter

BufferedInputStream

BufferedOutputStream

Converting between

bytes and character

InputStreamReader

OutputStreamWriter

 
Object Serialization ---

ObjectInputStream

ObjectOutputstream

Data Conversion ---

DataInputStream

DataOutputStream

Counting LineNumberReader LineNumberInputStream
Peeking ahead PushbackReader

PushbackInputStream

Printing PrintWriter PrintStream

 

 

 

 

 

 

 

 

 

 

 

 

 

1,缓冲流

缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。

J2SDK提供了四种缓冲流,其常用的构造方法:

BufferedReader
BufferedReader(Reader in)
Creates a buffering character-input stream that uses a default-sized input buffer.
BufferedReader(Reader in, int sz)
Creates a buffering character-input stream that uses an input buffer of the specified size.

BufferedWriter
BufferedWriter(Writer out)
Creates a buffered character-output stream that uses a default-sized output buffer.
BufferedWriter(Writer out, int sz)
Creates a new buffered character-output stream that uses an output buffer of the given size.

BufferedInputStream
BufferedInputStream(InputStream in)
Creates a BufferedInputStream and saves its argument, the input stream in, for later use.
BufferedInputStream(InputStream in, int size)
Creates a BufferedInputStream with the specified buffer size, and saves its argument, the input stream in, for later use.

BufferedOutputStream
BufferedOutputStream(OutputStream out)
Creates a new buffered output stream to write data to the specified underlying output stream.
BufferedOutputStream(OutputStream out, int size)
Creates a new buffered output stream to write data to the specified underlying output stream with the specified buffer size.
缓冲输入流支持其父类的mark和reset方法
BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔)
BufferedWriter提供了newLine方法用于写入一个行分隔符
对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数据立刻写出。

例一:

    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("d:\\share\\java\\HelloWorld.java");
            BufferedInputStream bis = new BufferedInputStream(fis);
            int c = 0;
            System.out.println(bis.read());
            System.out.println(bis.read());
            bis.mark(100);
            for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) {
                System.out.print((char)c + " ");
            }
            System.out.println();
            bis.reset();
            for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) {
                System.out.print((char)c + " ");
            }
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出:

47
42
 
 a l ; s k j d f ; 

 
 a l ; s k j d f ;

例二:

    public static void main(String[] args) {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\dat2.txt"));
            BufferedReader br = new BufferedReader(new FileReader("d:\\dat2.txt"));
            String s = null;
            for(int i = 1; i<=100; i++) {
                s = String.valueOf(Math.random());
                bw.write(s);
                bw.newLine();
            }
            bw.flush();
            while((s = br.readLine()) != null) {//读一行
                System.out.println(s);
            }
            bw.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出:

dat2.txt文件:

技术分享

控制台输出:

技术分享

 

2,转换流

转换流

InputStreamReader和OutputStreamWriter用于字节数据到字符数据之间的转换。

InputStreamReader需要和InputStream套接(把InputStream转换成InputStreamReader)

OutputStreamWriter需要和OutputStream套接(把OutputStreamWriter转换成OutputStream)

转换流在构造时可以指定其编码集合,例如:

InputStream is = new InputStreamReader(System.in, "IOS8859_1");

例一:

  public static void main(String[] args) {
        try {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt"));
            osw.write("miscalkjsdlasjdlajslkdalksd");
            System.out.println(osw.getEncoding());
            osw.close();
            
            osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt", true), "ISO8859_1");//true,追加
            osw.write("sadasdasdasdasd");
            System.out.println(osw.getEncoding());
            osw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

结果:

UTF8//系统默认的编码
ISO8859_1

例二:

    public static void main(String[] args) {
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            String s = null;
            s = br.readLine();
            while(s != null) {
                if("exit".equalsIgnoreCase(s))
                    break;
                System.out.println(s.toUpperCase());
                s = br.readLine();
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

输出:

add111
ADD111
exit

3,数据流

DataInputStream 和DataOutputStream分别继承自InputStream 和 OutputStream,它属于处理流,需要分别套接在InputStream 和 OutputStream类型的节点流上。

DataInputStream 和DataOutputStream提供了可以存取与机器无关的Java原始类型数据(如:int,double等)的方法。

DataInputStream 和DataOutputStream的构造方法:

DataInputStream(InputStream in)
Creates a DataInputStream that uses the specified underlying InputStream.

DataOutputStream(OutputStream out)
Creates a new data output stream to write data to the specified underlying output stream.

ByteArrayInputStream 和 ByteArrayOutputStream

例子:

    public static void main(String[] args) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();//在内存中分配了一个字节数组
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeDouble(Math.random());
            dos.writeBoolean(true);
            
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            System.out.println(bais.available());
            DataInputStream dis = new DataInputStream(bais);
            System.out.println(dis.readDouble());
            System.out.println(dis.readBoolean());
            
            dos.close();
            dis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

结果:

9
0.5620896958440097
true

 

4,Print流

Print流(只有输出流没有输入流)

PrintWriter和PrintStream都属于输出流,分别针对于字符和字节

PrintWriter和PrintStream提供了重载的print方法

Println方法用于多种数据类型的输出

PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息

PrintWriter和PrintStream有自动flush方法

构造方法:

PrintWriter(File file)
Creates a new PrintWriter, without automatic line flushing, with the specified file.
PrintWriter(File file, String csn)
Creates a new PrintWriter, without automatic line flushing, with the specified file and charset.
PrintWriter(OutputStream out)
Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream.
PrintWriter(OutputStream out, boolean autoFlush)
Creates a new PrintWriter from an existing OutputStream.
PrintWriter(String fileName)
Creates a new PrintWriter, without automatic line flushing, with the specified file name.
PrintWriter(String fileName, String csn)
Creates a new PrintWriter, without automatic line flushing, with the specified file name and charset.
PrintWriter(Writer out)
Creates a new PrintWriter, without automatic line flushing.
PrintWriter(Writer out, boolean autoFlush)
Creates a new PrintWriter.

PrintStream(File file)
Creates a new print stream, without automatic line flushing, with the specified file.
PrintStream(File file, String csn)
Creates a new print stream, without automatic line flushing, with the specified file and charset.
PrintStream(OutputStream out)
Creates a new print stream.
PrintStream(OutputStream out, boolean autoFlush)
Creates a new print stream.
PrintStream(OutputStream out, boolean autoFlush, String encoding)
Creates a new print stream.
PrintStream(String fileName)
Creates a new print stream, without automatic line flushing, with the specified file name.
PrintStream(String fileName, String csn)
Creates a new print stream, without automatic line flushing, with the specified file name and charset.

例一:

  public static void main(String[] args) {
        try {
            PrintStream ps = null;
            FileOutputStream fos = new FileOutputStream("d:\\bak\\log.dat");
            ps = new PrintStream(fos);
            if(ps != null) {
                System.setOut(ps);//把ps设置成System.out.println();不再输出在控制台了
            }
            int ln = 0;
            for(char c = 0; c <= 60000; c++) {
                System.out.print(c + "");
                if( ln++ >= 100) {
                    System.out.println();
                    ln = 0;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

结果:d:\\bak\\log.dat,log.data文件

技术分享

 

例二:

    public static void main(String[] args) {
        try {
            PrintStream ps = System.out;
            BufferedReader br = new BufferedReader(new FileReader("d:\\bak\\log.dat"));
            String s = null;
            while((s = br.readLine()) != null) {
                ps.println(s);
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:

技术分享

例三:

    public static void main(String[] args) {
        try {
            String s = null;
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            FileWriter fw = new FileWriter("d:\\bak\\logfile.log", true);//日志
            PrintWriter pw = new PrintWriter(fw);
            while ((s = br.readLine()) != null) {
                if("exit".equalsIgnoreCase(s))
                    break;
                System.out.println(s.toUpperCase());
                pw.println("--------");
                pw.println(s.toUpperCase());
                pw.flush();
            }
            pw.println("=====" + new Date() + "======");
            pw.flush();
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:

控制台:
12121212121
adasdasdasdasd
ADASDASDASDASD
exit

文件:d:\\bak\\logfile.log,logfile.log文件

技术分享

 

5,Object流

直接将Object写入或写出

transient关键字

serializable接口

externalizable接口

例一:

public class Test {

    public static void main(String[] args) {
        try {
            T t = new T();
            t.k = 18;
            FileOutputStream fos = new FileOutputStream("d:/bak/testobjectio.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(t);
            oos.flush();
            oos.close();
            
            FileInputStream fis = new FileInputStream("d:/bak/testobjectio.dat");
            ObjectInputStream ois = new ObjectInputStream(fis);
            T t2 = (T) ois.readObject();
            System.out.println(t2.i + "//" + t2.j + "//" + t2.d + "//" + t2.k);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}
class T implements Serializable {
    int i = 10;
    int j = 9;
    double d = 2.3;
    int k = 15;
}

结果:

10//9//2.3//18

例二:

用transient修饰变量k

class T implements Serializable {
    int i = 10;
    int j = 9;
    double d = 2.3;
    transient int k = 15;
}

结果:

10//9//2.3//0

transient修饰的变量k不会被写入进去,所以取出来的k为空,为默认值0

 

Java IO

标签:

原文地址:http://www.cnblogs.com/lemon-now/p/5579922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!