java I/O流

来源:互联网 发布:特色课程优化基本设想 编辑:程序博客网 时间:2024/06/18 03:27

I/0分类

在I/O流中分为两大类:一类是节点流,一类是处理流。

节点流:以文件、网络资源以及内存区域作为源和目的的流,文件流的源和目的是文件,而数组流的源和目的都是内存。

处理流:也叫过滤流,使用一个输入流或者输出流作为链接创建的,也就是对流进行一个包装。

I/ODemo源码下载

节点流

文件字节流

字节流也就是使用byte作为读写单位。
/** * @Decription TODO 文件字节输入流  * @date 2016年10月14日 下午8:06:17 */public int  fileOutputStreamTest(){int len = 0;try {//创建文件对象File  file  = CreateFile.byteSourceFile();//创建输出流对象FileOutputStream out = new FileOutputStream(file);//输出内容String str = "this is a file output stream";//写入文件--byte[]数组out.write(str.getBytes());len = str.getBytes().length;//关闭输出流out.close();} catch (IOException e) {e.printStackTrace();}return len;}/** * @Decription TODO 文件字节输出流  * @date 2016年10月14日 下午8:06:27 */public void fileInputStreamTest(){//先写入文件int len = fileOutputStreamTest();//创建文件对象File  file  = CreateFile.byteSourceFile();try {//创建文件输入流对象FileInputStream in = new FileInputStream(file);//用一个byte数组存储读取到的数据byte[] byteArr = new  byte[len];//索引变量int n =0;//将输入读取到byte数组中while( ( n=in.read(byteArr,0,len)) != -1){//字符串读System.out.println(new String(byteArr,0,n));}//输入流关闭in.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
输出结果:this is a file output stream

文件字符流

字符流使用char作为读写单位
/** * @Description TODO 文件字符输入流 * @date 2016年10月16日 下午2:34:12 */public void  fileReaderTest(){File file = CreateFile.charSourceFile(); FileReader reader = null;try {reader = new FileReader(file);//设置一个可存储1M大小的char数组char[] accept = new char[512];int n = 0;while ((n = reader.read(accept, 0, accept.length)) !=-1){System.out.println(new String(accept,0,n));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {reader.close();} catch (IOException e) {e.printStackTrace();}}}/** * @Description TODO 文件字符输出流 * @date 2016年10月16日 下午2:34:12 */public void  fileWriterTest(){File file = CreateFile.charSourceFile(); FileWriter writer = null;try {writer = new FileWriter(file);writer.write("这是一个文件字符输出流");//对于writer流,write方法会首先将数据写入缓冲区,每当缓冲区溢出是,缓冲区的内容才会被写入到目的地//调用flush方法或者关闭当前流都会立刻将数据写入目的地writer.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {writer.close();} catch (IOException e) {e.printStackTrace();}}}
数组流的源和目的都是内存,可以使用数组流和对象流来进行对象克隆

字节数组流

/** * @Decription TODO 字节数组输出流 * @date 2016年10月14日 下午8:34:33 */public byte[] byteArrayOutputStreamTest(){//定义一个字符串常量String str = "this is a byte array output stream";//ByteArrayOutputStream(int size)设置缓冲区大小//默认ByteArrayOutputStream()初始化一个32byte缓冲区,在无参构造方法中是使用this(32)来调用的ByteArrayOutputStream(int size//设置一个16字节的缓冲区,这是20字节的字符串ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(16);//byte数组返回变量,用来复制缓冲区的数据byte[] back = null;try {//write(int b)将b转换成byte插入到最后一个元素之后//write(byte[] b,int off,int len)从数组b索引为值为off写入长度为len的元素到缓冲区,当输入的字节数大于缓冲区时,缓冲区容量自动增加。byteOutput.write(str.getBytes());//输出写入缓冲区的byte数组System.out.println(byteOutput.toString());//返回缓冲区的byte数组back = byteOutput.toByteArray();} catch (IOException e) {e.printStackTrace();} finally{try {byteOutput.close();} catch (IOException e) {e.printStackTrace();}}return back;}/** * @Decription TODO 字节数组输入流 * @date 2016年10月14日 下午8:34:33 */public void byteArrayInputStreamTest(){//获取已在内存中的数组byte[] outByte = byteArrayOutputStreamTest();//指定输入流的源ByteArrayInputStream byteIn = new ByteArrayInputStream(outByte);//定义一个数组byte[] inbyte = new byte[outByte.length];try {int n = 0;//读完最后一个字节或抛出异常结束read方法体//执行一次执行一次read()方法,pos++,所以如果使用read()判断下一个位置是否有数据就读取不到第一个数据while ((n = byteIn.read(inbyte,0,outByte.length)) != -1){//打印数组内容,注意只打印已经读到的内容。System.out.println(new String(inbyte,0,n));}} finally{try {byteIn.close();} catch (IOException e) {e.printStackTrace();}}}

字符数组流

/** * @Description TODO 字符数组输入流测试 * @date 2016年10月16日 上午11:14:52 */public void charArrayReaderTest(){//定义一个字符数组char[] charArr = charArrayWriterTest();//指定字符数组输入流的源(已经在内存分配具体空间)CharArrayReader reader = new CharArrayReader(charArr);//定义一个接收的字符数组char[] acceptArr = new char[charArr.length];try {//读取内容while (reader.read(acceptArr,0,charArr.length) != -1){//打印目的数组System.out.println("打印目的数组"+Arrays.toString(acceptArr));}} catch (IOException e) {e.printStackTrace();} finally{//关闭流reader.close();}}/** * @Description TODO 字符数组输出流 * @date 2016年10月16日 下午2:35:33 * @return */public char[] charArrayWriterTest(){String  str = "这是一个字符数组流";//定义一个源字符数组char[] charArr =str.toCharArray();//初始化一个5个字符大小的缓冲区CharArrayWriter writer = new CharArrayWriter(5);//用来复制缓冲区的数据char[] inputData = null;try {//写入缓冲区writer.write(charArr);//获得缓冲区中的数据inputData = writer.toCharArray();System.out.println("缓冲区中的数组:"+Arrays.toString(inputData));} catch (IOException e) {e.printStackTrace();} finally{writer.close();}return inputData;}/** *  * @Description TODO  随机流既不是InputStream的子类也不是OutputStream的子类,可以讲一个文件作为源和目的进行读写。 *      随机流指向文件是不刷新新文件 * @date 2016年10月16日 下午4:45:03 */public void randomAccessFileTest(){File file = CreateFile.datFile();RandomAccessFile inAndOut = null;//参数mode的有r读、rw读写,至于rws和rwd模式还不知怎么去用//看到这个|=赋值符号: a = a|b 即ab按位取或try {inAndOut = new RandomAccessFile(file, "rw");String  str = "这是一个随机流"; //7x2 = 14 byte//byteArr是str的byte表示,随机流与数据流都可以不在关心数值是多少字节的,按照指定的逻辑去读写就行了//也可以使用str.getBytes()来获取str的byte数组表示,这里实验时粘贴过来的byte[] byteArr = new byte[]{-113,-39,102,47,78,0,78,42,-106,-113,103,58,109,65};//写500个字符串进去for (int i = 0; i < 500; i++ ) {inAndOut.write(byteArr);}StringBuffer buf = new StringBuffer();//读取循环次数500 * 7,一个字符串是7个char字符串组成for ( int i = 0; i < 500 * 7; i++){//读取位置inAndOut.seek(i*2);//每个字符串开始插入一个提示if( i%7 == 0){buf.append("\n第"+i+"个字符串:");}buf.append(inAndOut.readChar());}System.out.println(buf.toString());} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();} finally{try {//关闭流inAndOut.close();} catch (IOException e) {e.printStackTrace();}}}

随机流

/** *  * @Description TODO  随机流既不是InputStream的子类也不是OutputStream的子类,可以讲一个文件作为源和目的进行读写。 *      随机流指向文件不刷新文件 * @date 2016年10月16日 下午4:45:03 */public void randomAccessFileTest(){File file = CreateFile.datFile();RandomAccessFile inAndOut = null;//参数mode的有r读、rw读写,至于rws和rwd模式还不知怎么去用//看到这个|=赋值符号: a = a|b 即ab按位取或try {inAndOut = new RandomAccessFile(file, "rw");String  str = "这是一个随机流"; //7x2 = 14 byte//也可以使用str.getBytes()来获取str的byte数组表示,这里实验时粘贴过来的byte[] byteArr = new byte[]{-113,-39,102,47,78,0,78,42,-106,-113,103,58,109,65};//写500个字符串进去for (int i = 0; i < 500; i++ ) {inAndOut.write(byteArr);}StringBuffer buf = new StringBuffer();//读取循环次数500 * 7,一个字符串是7个char字符串组成for ( int i = 0; i < 500 * 7; i++){//读取位置inAndOut.seek(i*2);//每个字符串开始插入一个提示if( i%7 == 0){buf.append("\n第"+i+"个字符串:");}buf.append(inAndOut.readChar());}System.out.println(buf.toString());} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();} finally{try {//关闭流inAndOut.close();} catch (IOException e) {e.printStackTrace();}}}


处理流

缓冲输入流有两个构造方法:InputStream in;InputStream in , int size。第二个构造方法可以设置缓冲数组的大小,而不设置数组大小时默认创建一个8192大小的byte数组,显然设置一个比较合适的初始值能降低空间占用。

缓冲字节流

/** * @Description TODO 缓冲字节输入流 * @date 2016年10月16日 下午2:45:44 */public void bufferedInputStreamTest(){File file = CreateFile.byteSourceFile();BufferedInputStream bufIn = null;try {bufIn = new BufferedInputStream(new FileInputStream(file),10);byte[] byteIn = new byte[1024];int n = 0;while((n = bufIn.read(byteIn, 0, byteIn.length)) != -1){System.out.println(new String(byteIn ,0 ,n));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e1) {e1.printStackTrace();} finally{try {//只需要关闭包装的流,底层流会自动关闭;不关闭流可造成别的程序无法使用。bufIn.close();} catch (IOException e) {e.printStackTrace();}}}/** * @Description TODO 缓冲字节输出流 * @date 2016年10月16日 下午3:06:54 */public void bufferedOutputStream(){File file = CreateFile.byteSourceFile();BufferedOutputStream bufOut = null;try {bufOut = new BufferedOutputStream(new FileOutputStream(file));String strOut = "这是一个缓冲字节输出流";bufOut.write(strOut.getBytes());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {bufOut.close();} catch (IOException e) {e.printStackTrace();}}}

缓冲字符流

/** * @Description TODO 缓冲输入流 * @date 2016年10月16日 下午2:43:00 */public void bufferedReaderTest(){File file = CreateFile.charSourceFile();BufferedReader reader = null;try {Reader fileReader = new  FileReader(file);reader = new BufferedReader(fileReader);String strIn = null;while ((strIn = reader.readLine()) !=null){System.out.println( strIn+"\n" );}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {reader.close();} catch (IOException e) {e.printStackTrace();}}}/** * @Description TODO 缓冲输出流 * @date 2016年10月16日 下午2:43:46 */public void bufferedWriterTest(){File file = CreateFile.charSourceFile();BufferedWriter bufWriter =null;try {FileWriter fileWriter = new FileWriter(file);//默认8kb的缓冲区bufWriter = new BufferedWriter(fileWriter);bufWriter.write("这是第一个缓冲输出流");//将数据强制写入文件bufWriter.flush();//查看数据是否插入(肯定是插入了的)bufferedReaderTest();//换行bufWriter.newLine();bufWriter.write("这是第二个缓冲输出流");//查看数据是否插入(肯定是没有插入了的)bufferedReaderTest();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally{try {bufWriter.close();//查看数据是否全部写入bufferedReaderTest();} catch (IOException e) {e.printStackTrace();}}}

inputStreamReader和OutputStreamWriter

/** * @Description TODO inputStreamReader是字节流到字符流桥梁,将字节流按照参数字符集解码读取出来 *    较为常见的是与BufferReader一起使用 * @date 2016年10月17日 下午7:43:06 */public void inputStreamReaderTest(){File file = CreateFile.charSourceFile();BufferedReader reader = null;try {InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8");reader = new BufferedReader(isr);while (reader.readLine() !=null) {System.out.println(reader.readLine());} //关闭流reader.close();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/** * @Description TODO OutputStreamWriter是字符流到字节流的桥梁, *    将字符流按照参数的字符编码写入文件中 * @date 2016年10月17日 下午7:46:42 */public void outputStreamWriterTest(){File file = CreateFile.charSourceFile();BufferedWriter writer =  null;try {//编码和解码的字符集不一样会乱码,gb2312与GBK是兼容的OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file), "gb2312");writer = new BufferedWriter(osw);for (int i = 0; i < 50; i++) {writer.write("这是一个OutputStreamWriter");//插入换行符writer.newLine();}//刷新文件writer.flush();//关闭流writer.close();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}


数据流

数据流不关心数据在实际存储时占多少个字节,在读取的时候按照特定的读取方法就能读出来。
/** * @Description TODO 数据输出流测试 * @date 2016年10月17日 下午5:43:14 */public void  dataOutputStreamTest(){File file = CreateFile.byteSourceFile();DataOutputStream  dataOut = null;try {OutputStream out = new FileOutputStream(file);dataOut = new DataOutputStream(out);int b = 252;dataOut.writeInt(b);dataOut.writeBoolean(true);//char字符复制使用单引号String str = "这是一个数据输出流";dataOut.writeUTF(str);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {dataOut.close();} catch (IOException e) {e.printStackTrace();}}}/** * @Description TODO 数据输入流测试方法 * @date 2016年10月17日 下午5:36:54 */public void dataInputStreamTest(){File file = CreateFile.byteSourceFile();DataInputStream  dataIn = null;try {InputStream in = new FileInputStream(file);dataIn = new DataInputStream(in);System.out.println(dataIn.readInt());System.out.println(dataIn.readBoolean());System.out.println(dataIn.readUTF());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {dataIn.close();} catch (IOException e) {e.printStackTrace();}}}


对象流

public void objectOutputStreamTest(){//将文件对象写入文件中File file = CreateFile.datFile();Book book = new Book("java编程思想","帅哥",22.00,false);try {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));oos.writeObject(book);oos.close();System.out.println("对象输出流写入成功!");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public void objectInputStreamTest(){File file = CreateFile.datFile();try {//将对象写入文件中ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));Book book = (Book) ois.readObject();System.out.println("name:" + book.name);System.out.println("author:" + book.author);System.out.println("price:" + book.price);System.out.println("isBorrowed:" + book.isBorrowed);ois.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}

使用数组和对象流实现对象克隆

Book类
public class Book implements Serializable {private static final long serialVersionUID = 1L;// 被transient修饰的成员不会被序列化,使用对象流要保证对象序列化,也要保证对象的成员被序列化transient String name;String author;boolean isBorrowed;double price;public Book() {}public Book(String name, String author, double price, boolean isBorrowed) {this.name = name;this.author = author;this.price = price;this.isBorrowed = isBorrowed;}/** * @Description TODO 自定义反序列话name字段 * @date 2016年10月17日 下午8:19:43 */private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {// 把jvm能反序列换的成员饭反序列话s.defaultReadObject();// 反序列话namethis.name = s.readUTF();}/** * @Description TODO 保存数组实例的状态到对象输出流中 * @date 2016年10月17日 下午9:17:01 * @param s * @throws java.io.IOException */private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {// 把jvm能序列化的成员序列化s.defaultWriteObject();// 虚拟化names.writeUTF(this.name);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((author == null) ? 0 : author.hashCode());//Generate Hashcode() and equals() 不允许设置transient字段参与hashcode的计算,所以自己加一个result = prime * result + ((name == null) ? 0 : name.hashCode());result = prime * result + (isBorrowed ? 1231 : 1237);long temp;temp = Double.doubleToLongBits(price);result = prime * result + (int) (temp ^ (temp >>> 32));return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Book other = (Book) obj;//Generate Hashcode() and equals() 不允许设置transient字段参与equals比较,所以自己加一个if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name)) {return false;}if (author == null) {if (other.author != null)return false;} else if (!author.equals(other.author))return false;if (isBorrowed != other.isBorrowed)return false;if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))return false;return true;}}


对象克隆实现
/** * @Decription TODO 使用数组和对象流实现对象克隆 * @date 2016年10月17日 下午11:29:37 */public void objectClone(){try {//定义一个book对象Book book = new Book("java2实用教程","耿祥义",39.50,false);//先将对象写入内存中,相当于拷贝了一份ByteArrayOutputStream byteOut = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(byteOut);oos.writeObject(book);//从内存中读取出来转换成Book对象ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());ObjectInputStream ois = new ObjectInputStream(byteIn);Book bookClone = (Book) ois.readObject();//不重写equals方法会使用java.lang.Object默认的equals方法(直接判断两个对象的地址值是否相等,显然不符合这里我们的逻辑),//所以Book重写equals方法if (bookClone.equals(book)) {if(bookClone != book)System.out.println("克隆成功");elseSystem.out.println("克隆失败");} else{System.out.println("克隆失败");}//关闭流oos.close();byteOut.close();ois.close();byteIn.close();} catch (IOException e) {e.printStackTrace();}catch (ClassNotFoundException e) {e.printStackTrace();}}






0 0
原创粉丝点击