【JAVA基础知识总结】Java I/0流概述以及使用方法

一. I/O流概述

   输入输出处理是程序设计中非常重要的一部分,从键盘中读数据或从文件中读写数据等等。

     java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。

        而Java 语言中I/O流分类:
     分为输入流(Input Stream) 和输出流(Output Stream)
     分为节点流(Node Stream) 和处理流(Processing Stream)
     分为字符流(Character Stream) 和字节流(Byte Stream)


I/O中的Exception

  进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。  

  如:FileNotFoundException, EOFException, IOException

 

java.io包中有关文件处理包括:

            类:File、FileInputStream、FileOutputStream、RamdomAccessFile和FileDescription

                接口:FilenameFilter

1. 字节流:

  从InputStream和OutputStream派生出来的一系列类,以字节(byte)为基本处理单位

2. 字符流:

  从Reader和Writer派生出来的一系列类,以16位的Unicode码表示的字符为基本处理单位

3. 对象流:

  ObjectInputStream、ObjectOutputStream

4. 其他

     文件处理:

    文件处理:

      File、RandomAccessFIle

    接口:

      DataInput、DataOutput、ObjectInput、ObjectOutput

 

二. 文件描述

  类File:并不代表磁盘上的文件,可以理解为文件的路径,但是比String形式的路径更为安全。

  1)文件或目录的生成

    public File(String path); // 如果path是路径,则该File对象表示的是目录;如果path是文件名,则该表示的是文件

    public File(String path, String name); // path是路径名,name是文件名

    public File(File dir, String name); // dir是路径名,name是文件名

  2)文件名的处理

    String getName(); // 得到一个文件的名称(不包括路径)

    String getPath(); // 得到一个文件的路径名

    String getAbsolutePath(); // 得到一个文件的绝对路径名

    String getParent(); // 得到一个文件的上一级目录名

    String renameTo(File newName); // 将当前文件名更名为给定文件的完整路径

  3)文件属性测试

    boolean exists(); // 测试当前FIle对象所指示的文件是否存在

    boolean canWrite(); // 测试当前文件是否可写

    boolean canRead(); // 测试当前文件是否可读

    boolean isFile(); // 测试当前文件是否是文件

    boolean isDirectory; //  测试当前文件是否是目录

  4)普通文件信息和工具

    long lastModified(); // 得到文件最近一次修改的时间

    long length(); // 得到文件的长度,以字节为单位

    boolean delete(); // 删除当前文件

  5)目录操作

    boolean mkdir(); // 根据当前对象生成以一个由该对象指定的路径

    String list(); // 列出当前目录下的文件。

           // File假如是一个Directory,可以通过list()方法得到这个目录下所有的文件和目录的名称数组。

          // 一种是没有参数,一种是实现FilenameFilter接口的参数。

   

     FilenameFilter接口,能够过滤得到指定类型的文件或者目录,其中必须重写accept(File file,String path)方法

eg: 列出C:\MyProjects下后缀为.java的文件

import java.io.*;


public class FileFilterTest {
public static void main(String args[]) {
File dir = new File("C://MyProjects"); // 用File对象表示一个目录
Filter filter = new Filter("java"); // 生成一个名为java的过滤器
System.out.println("list java files in directory" + dir);


String files[] = dir.list(filter); // 列出目录dir下,文件名后缀名为java的所有文件


for (int i = 0; i < files.length; i++) {
File f = new File(dir, files[i]); // 为目录dir下的文件或目录创建一个File对象
if (f.isFile())
System.out.println("file " + f);
else
System.out.println("sub dirctory " + f);
}
}
}


class Filter implements FilenameFilter { // 必须重写accept(File file,String path)方法
String extent;


Filter(String extent) {
this.extent = extent;
}


public boolean accept(File dir, String name) {
return name.endsWith("." + extent); //返回文件的后缀名
}
}

输出结果

二. I/O流详述

1. 字节流

InputStream类

  a) 从流中个读取数据

    int read(); // 读取一个字节,返回实际所读字节

    int read(byte b[]); // 读取字节数为b的长度,并存放在字节数组b中,返回值为实际读取的字节的数量

    int read(byte b[], int off, int len); // 读取len个字节,放置在以下标off开始的字节数组b中,返回值为实际读取的字节的数量

    int available(); // 返回值为流中尚未读取的字节的数量

    long skip(long n); // 读指针跳过n个字节不读,返回值为实际跳过的字节数量

  b) 关闭流:

    close(); // 流操作完毕后必须关闭

  c) 使用输入流中的标记:

    void mark(int readlimit); // 记录当前读指针所在位置,readlimit表示读指针读出readlimit个字节后标记的指针位置才失效

    void reset(); // 把读指针重新指向用mark方法所记录的位置

    boolean markSupported(); // 当前的流是否支持读指针的记录功能

 

OutputStream类

  a) 输出数据:

    void write(int b); // 往流中写一个字节b

    void write(byte b[]); // 往流中写一个字节数组b

    void write(byte b[], int off, int len); // 把字节数组b中下标off开始,长度为len的字节写入流中

    flush(); // 刷空输出流,并输出所有被缓存的字节,由于某些流支持缓存的功能,该方法将把缓存中所有内容强制输出到流中

  b) 关闭流:

    close(); // 流操作完毕后必须关闭

 

过滤流(包装流)

  过滤流在读写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流

  防止多个线程同时对一个I/O流进行操作带来的意想不到的结果。

  类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类

   a) 使用过滤流的步骤:

    连接到某个输入输出流上,通过在构造方法的参数中指定所要连接的输入输出流上来实现

    FilterInputStream(InputStream in);

    FilterOutputStream(OutputStream out);

   b) 几种常见的过滤流

    BufferedInputStream和BufferedOutputStream 缓冲流,用于提高输入输出处理的效率

    DataInputStream和DataOutputStream 不仅能读写数据流,而且读写各种java语言的基本类型

    LineNumberInputStream 除了对输入处理的支持外,可以记录当前的行号

    PushbackInputStream 提供了一个方法可以把刚读的字节退回到输入流中,以便重新再读一遍

    PrintStream 打印流的作用是吧java语言的内构类型以其字符表示形式动到相应的输出流

 

2. 字符流

字符流的处理

  java提供16位Unicode码表示的字符流的类,即以Reader和Writer为基类派生出的一系列类

  Reader和Writer:这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成实例。

 

Reader类:是处理所有字符流输入类的父类

  a) 读取字符

    public int read() throws IOException; // 读取一个字符,返回值为读取的字符

    public int read(char cbuf[]) throws IOException; // 读取一系列字符到cbuf数组,返回值为实际读取的字符数量

    public abstract int read(char cbuf[], int off, int len) throws IOException; // 读取len个字符,存入off开始的cbuf中,返回实际读取的    // 的字数,必须由子类实现

   b) 标记流

    public boolean markSupported(); // 判断当前流是否支持做标记

    public void mark(int readAheadLimit) throws IOException; // 给当前流作标记,最多支持readAheadLimit个字符的回溯

    public void reset() throws IOException; // 将当前流重置到做标记处

  c) 关闭流

    public abstract void close() throws IOExeption;

 

Writer类:是处理所有字符流输出类的父类

  a) 向输出流写入字符

    public void write(int c) throws IOException; // 将整型值c的低16位写入输出流

    public void write(char cbuf[]) throws IOException; // 将cbuf数组写入输出流

    public abstract void write(char cbuf[], int off, int len); // 将字符数组cbuf中的从索引off开始的len个字符写入输出流

    public void write(String str) throws IOException; // 将字符串str中的字符写入输出流

    public void write(String str, int off, int len) throws IOException; // 将字符串str中从索引off开始处的len个字符写入输出流

    flush() 刷空输出流,并输出所有被缓冲的字节

  b) 关闭流

    public abstract void close() throws IOException;

 

java.io包中用于处理字符流的最基本的类:InputStreamReader OutputStreamWriter,此外还有FileReader和FileWriter

  a) 生成流对象

      public InputStreamReader(InputStream in); // in是字节流,即将字节流转换成字符流来处理

      public InputStreamReader(InputStream in, String enc) throws UnsupportedEncodingExceptio; // enc是编码方式:ISO8859-1,UTF-8,UTF-16

      public OutputStreamWriter(OutputStream out); // out是字节流

      public OutputStreamWriter(OutputStream out, String enc) throws UnsupportedEncodingException; // enc是编码方式

  b) 读写字符

    基本与Reader和Writer一致

  c) 获取当前编码方式

    public String getEncoding();

  d) 关闭流

    public void close() throws IOException;

 

BufferedReader和BufferedWriter

  a) 生成流对象

    public BufferedReader(Reader in); 

    public BufferedReader(Reader in, int sz); // sz为缓冲区的大小

    public BufferedWriter(Writer out); 

    public BufferedWriter(Writer out, int sz); 

  b) 读写字符

    增加对整行字符的处理

    public String readline() throws IOException; // 读一行字符

    public void newLine() throws IOException; // 写一行字符

代码如下:

// 从键盘读入数字,并输出
import java.io.*;


public class NumberInput {
public static void main(String args[]) {
try {
InputStreamReader ir;
BufferedReader in;
ir = new InputStreamReader(System.in);
// 从键盘接受一个字符串的输入,并创建了一个字符输入流的对象
in = new BufferedReader(ir); // 用字符输入流ir创建一个BufferedReader对象
String s = in.readLine(); // 从输入流in中读入一行
System.out.println("Input value is: " + s);
int i = Integer.parseInt(s); // 转换成int
i *= 2;
System.out.println("Input value changed after doubled: " + i);
}
catch (IOException e) {
System.out.println(e);
}
}
}


3. 对象流

  串行

    对象通过描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)

    a) 串行化方法:

      java.io包中,接口Serializable用来作为对象串行化的工具,只有实现了Serializable的对象才可以被串行化

      串行化步骤:

1. 定义一个可串行化的对象


          public class Student implements Serializable {...}


        2. 通过ObjectInputStream和ObjectOutputStream这两个对象流存取可串行化对象


          Student stu = new Student();


          FileOutputStream fo = new FileOutputStream("data.ser");


          ObjectOutputStream so = new ObjectOutputStream(fo);


          try {


            so.writeObject(stu);


            so.close();


          } catch (IOException e) {


            System.out.println(e);


          }


          FileInputStream fi = new FileInputStream("data.ser");


          ObjectInputStream si = new ObjectInputStream(fi);


          try {


            stu = (student)si.readObject();


            si.close();


          } catch (IOException e) {


            System.out.println(e);


          }

注意事项:

1. 只能保存非静态成员变量,不能保存任何成员方法和静态成员变量,保存的只是变量的值,对于变量的任何修饰符都无法保存

2. transient关键字,对于某些瞬时对象(Thread对象,FileInputStream对象),无法保存,必须用transient关键字表明

3. 定制串行化,缺省机制为按名称升序,想定制就要重写writeObject()和readObject()

 

4. 其他常用的流

管道流

  用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入

  在使用管道前,管道输出流和管道输入流必须进行连接。

  a) 构造方法连接

    PipedInputStream(PipedOutputstream src);

    PipedOutputStream(PipedInputStream snk);

  b) connect方法进行连接

    类PipedInputStream中定义为:

    void connect(PipedOutputSream src);

    类PipedOutputStream中定义为:

      void connect(PipedInputSream snk);

 

小结: 

字节流:

  抽象类 InputStream OutputStream
  跟数据源直接接触的类: FileInputStream FileOutputStream
  装饰类: BufferedInputStream: 提供了缓冲功能 BufferedOutputStream: 提供缓冲功能

  重要方法:
    read();
    read(byte[] b);
    read(byte[] b, int off, int len);

    write(int b);
    write(byte[] b);
    write(byte[] b, int off, int len);

字符流:

  抽象类 Reader Writer
  跟数据源直接接触的类 FileReader FileWriter
  装饰类 BufferedReader: 缓冲,readLine() BufferedWriter: 缓冲

  重要方法:
    read(char[] cbuf);
    read(char[] cbuf, int off, int len);
    read(CharBuffer target);

    write(char[] cbuf);
    write(char[] cbuf, int off, int len);
    write(int c);
    write(String str);
    write(String str, int off, int len);

对象流
  需要被序列化的对象必须实现Serializable接口
  调用ObjectOutputStream的writeObject()方法,通过装饰FileOutputstream
  调用ObjectInputStream的readObject()方法,通过装饰FileInputStream


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值