源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

JAVA IO API使用详解

  • 时间:2022-05-08 20:51 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:JAVA IO API使用详解
[b]一.理论准备 [/b]流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行,设备可以是文件、网络、内存等。流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序(小马哥说的是机器)为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流,可以将流想象成一个“水流管道”(很多资料都这么讲的),自然就出现了方向的概念。 流把I/O设备内部的具体操作给隐藏起来了。所有InputStream和Reader的派生类都有一个基本的,继承下来的,能读取单个或byte数组的read( )方法。 Java分为字节流(Stream结尾)和字符流(Reader、Write结尾),再分为输入流(InputStream、Reader)和输出流(OutputStream、Write),输入输出相对于内存而言。在读字符的时候用字符流,如文本文件、XML(我想xml明明是字母字符组成的,属于ASCII文件,为何不用stream读取呢?)等。在读二进制文件时候用字节流,如RAR、EXE等不是文本以外的文件(图片)。Buffered开头的流只是加了缓冲区,为了读写提高效率。字符流不能直接输出,需要转换成字节流才能输出(这个确实是刚知道的)! Java 2 SDK中有三种基本类型的节点:文件(file)、内存(memory)、管道(pipe)。 下面来看郑莉教材上IO章节的那个经典图片。 继承自InputStream/OutputStream的流都是用于向程序中输入/输出数据,且数据的单位都是字节(byte=8bit),如图,深色的为节点流,浅色的为处理流。 [img]http://files.jb51.net/file_images/article/201311/20131114141246.jpg?20131014141326[/img] 继承自Reader/Writer的流都是用于向程序中输入/输出数据,且数据的单位都是字符(2byte=16bit),如图,深色的为节点流,浅色的为处理流。 [img]http://files.jb51.net/file_images/article/201311/20131114141258.jpg?20131014141427[/img] [b]二.用法分析 [/b]Java IO的一般使用原则(部分来自百度文库): (1) 按数据来源(去向)分类: 是文件: FileInputStream, FileOutputStream, FileReader, FileWriter 是byte[]:ByteArrayInputStream, ByteArrayOutputStream 是Char[]: CharArrayReader, CharArrayWriter 是String: StringBufferInputStream, StringReader, StringWriter 网络数据流:InputStream, OutputStream, Reader, Writer (2) 按是否格式化输出分: 要格式化输出:PrintStream, PrintWriter (3) 按是否要缓冲分: 要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter。 (4) 按数据格式分: 二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类 纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类 (5) 按输入输出分: 输入:Reader, InputStream类型的子类;输出:Writer, OutputStream类型的子类 (6) 特殊需要: 从Stream到Reader,Writer的转换类:InputStreamReader, OutputStreamWriter 对象输入输出:ObjectInputStream, ObjectOutputStream 进程间通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter 合并输入:SequenceInputStream 更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader        (7) 决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要): 考虑最原始的数据格式是什么:是否为文本?是输入还是输出?是否需要转换流:InputStreamReader, OutputStreamWriter?数据来源(去向)是什么:文件?内存?网络?是否要缓冲:bufferedReader (特别注明:一定要注意的是readLine()是否有定义,有什么比read, write更特殊的输入或输出方法)是否要格式化输出:print。 [b]三.若干实例 [/b]还是寒假时候写的,权当复习了,折叠代码的插件找不到了,先看着吧。 1.System.in
[u]复制代码[/u] 代码如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /*  * System.in是InputStream static final的,包含了多态,叫同步式或者阻塞式  * 读取ASCII和二进制文件(图片),而字母就是ASCII字符(个人理解)。  */ public class TestSystemIn {  public static void main(String[] args) {   InputStreamReader isr = new InputStreamReader(System.in);   BufferedReader br = new BufferedReader(isr);//有readline   String s = null;   try {    s = br.readLine();    while(s!=null) {     if(s.equalsIgnoreCase("exit")) {      break;     }     System.out.println(s.toUpperCase());     s = br.readLine();    }    br.close();   }catch (IOException e) {    e.printStackTrace();   }  } }
  2.buffer
[u]复制代码[/u] 代码如下:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class TestBuffer {  public static void main(String[] args) {   try {    //查看修改日就可以判断文件是否是新建的了    BufferedWriter bw = new BufferedWriter(new FileWriter("d:/java.txt"));    BufferedReader br = new BufferedReader(new FileReader("d:/java.txt"));    String s = null;    for(int i=1; i<100; i++) {     s = String.valueOf(Math.random());     bw.write(s);     bw.newLine();//换行    }    //刷新该流的缓冲,br没有该方法    bw.flush();    while((s=br.readLine())!=null) {     System.out.println(s);    }    bw.close();    br.close();   }catch (IOException e) {    e.printStackTrace();   }  } }
    3.FileInputStream
[u]复制代码[/u] 代码如下:
import java.io.*; public class TestFileInputStream {  public static void main(String[] args) {   FileInputStream in = null;   try {    in = new FileInputStream("e:/1.txt");   }catch(FileNotFoundException e) {    System.out.println("找不到文件");    System.exit(-1);   }   //下面表示找到了文件   int tag = 0;   try {    long num = 0;    while((tag = in.read())!=-1) {     //read是字节流,若是有汉字就显示不正常了,使用reader就解决了     System.out.print((char)tag);     num++;    }    in.close();    System.out.println();    System.out.println("共读取了" + num + "字符");   }catch(IOException e1) {//read和close都会抛出IOException    System.out.println("文件读取错误");    System.exit(-1);   }  } }
     4.FileOutputStream实现复制功能
[u]复制代码[/u] 代码如下:
import java.io.*; /*  * 实现复制功能  */ public class TestFileOutputStream {  public static void main(String[] args) {   int b = 0;   FileInputStream in = null;   FileOutputStream out = null;   try {    in = new FileInputStream("d:/java.txt");    //下面的若是不存在的话会自动建立    out = new FileOutputStream("d:/my_java.txt");    while((b=in.read())!=-1) {     out.write(b);    }    in.close();    out.close();   }catch(FileNotFoundException e) {    System.out.println("找不到指定文件");    System.exit(-1);   }catch(IOException e1) {    System.out.println("文件复制错误");    System.exit(-1);   }   System.out.println("文件已复制");   } }
     5.ObjectOutputStream与Serializable
[u]复制代码[/u] 代码如下:
import java.io.*; /*  * transient(透明的),可以用来修饰成员变量,  * 当进行序列化时不予考虑,修饰int 的话,不管原来的值是多少  * 输出的就是0  */ public class TestObjectIO {  public static void main(String[] args) throws Exception {   T t = new T();   t.k = 8;   FileOutputStream fos = new FileOutputStream("d:/1.txt");   ObjectOutputStream oos = new ObjectOutputStream(fos);   oos.writeObject(t);   oos.flush();   oos.close();   FileInputStream fis = new FileInputStream("d:/1.txt");   ObjectInputStream ois = new ObjectInputStream(fis);   T tRead = (T)ois.readObject();   System.out.println(tRead.i + " " + tRead.j + " " + tRead.k);  } } class T implements Serializable {  int i = 10;  int j = 9;  double d = 2.3;  int k = 15; }
 6.转换编码方式
[u]复制代码[/u] 代码如下:
import java.io.*; /*  * 中文windows默认GBK编码方式  * 追加的内容显示为问号,不知道咋回事  */ public class TestTransForm {  public static void main(String[] args) {   try {    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:/java.txt"));    osw.write("你好123");//可以直接写入字符串,包括中文,因为外边的是字符流    System.out.println("编码方式:" + osw.getEncoding());//ISO8859_1是西欧语言,又叫latin-1,此时未考虑东方人,国标(ISO)为Unicode    osw.close();    osw = new OutputStreamWriter(new FileOutputStream("d:/java.txt",true),"ISO8859_1");//true表示追加    osw.write("这是追加的内容");    System.out.println("编码方式:" + osw.getEncoding());    osw.close();   }catch(IOException e) {    e.printStackTrace();   }  } } 7.输出重定向 [code] import java.io.*; /*  * Print流属于输出流,提供了重载的方法很多,  * PrintWriter和PrintStream不会抛异常,用户通过检测错误状态获取信息,  * 包含自动flush功能,有什么用呢,在jsp里也要输出一些东西,  * 但不必每次抛异常。  */ public class TestPrintStream {  public static void main(String[] args) {   PrintStream ps = null;   try {    FileOutputStream fos = new FileOutputStream("d:/java.txt");    ps = new PrintStream(fos);   }catch (IOException e) {    e.printStackTrace();   }   if(ps!=null) {    System.setOut(ps);//输出重定向   }   int ln = 0;   for(char c=0; c<65535; c++) {    System.out.print(c + " ");    if(ln++>100) {     System.out.println();     ln = 0;    }   }  } }
8.DataStream
[u]复制代码[/u] 代码如下:
import java.io.*; public class TestDataStream {  public static void main(String[] args) {  //先在内存里分配一个字节数组,再有一个 OutputStream,再加上一个数据流   ByteArrayOutputStream baos = new ByteArrayOutputStream();   DataOutputStream dos = new DataOutputStream(baos);   try {//写出读入    dos.writeDouble(Math.random());    dos.writeBoolean(true);    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());    System.out.println(bais.available());//共几个字节可用    DataInputStream dis = new DataInputStream(bais);    ////先写的先读(队列),下面这两个输出不可以调换,否则就先输出了double里的一个字节    System.out.println(dis.readDouble());    System.out.println(dis.readBoolean());    dos.close();    dis.close();   }catch (IOException e) {    e.printStackTrace();    }  } }
四.小问题 为什么Writer/Reader不继承自Stream呢?字符最终也要转换成二进制呀。Writer/Readre继承OutputStream/InputStream,这样的继承层次不是更好,为什么要单独做一个呢,而且Stream也有些子类能够实现字符串的读写。大神回答:单一职责。太牵强了。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部