JavaSE学习笔记之-----IO流

目录:

一、什么是IO流

二、流的分类

  1、节点流

  2、处理流

    2.1缓冲流

    2.2转换流

    2.3数据流

    2.4Print流(打印流)

    2.5 Object流(对象流)

一、什么是IO流

    IO流即是输入(Input)输出(Output)流,输入和输出的方向是针对程序而言的,比如现在要读取文件内容,那么就是输入流,是对于程序而言的。流其实就是传输数据用的,流位于java.io包当中,最主要的就是字符流和字节流,Java当中字符是两个字节。关于流的类都继承自下面抽象类


注意这几个是抽象类,无法实例化。


二、流的分类

    一般按照处理数据单位分为字节流和字符流,这里按照功能分类,分成节点流和处理流。

1、节点流


可以看到节点流有处理文件的,有处理内存数组(Memory Array)的,内存字符串的、以及Pipe管道的。

下面以处理File为例,先介绍字节流:

/**
 * 读取路径下的文件内容,显示在控制台
 */
package com.zhoucy.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestFileInputStream {
	public static void main(String[] args) {
		
		int b = 0;
		FileInputStream in = null;
		
		try{
			in = new FileInputStream("e:/java/io/DataTest.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++;
			}
			System.out.println();
			System.out.println("共读取了"+num+"个字节");
			in.close();
		} catch (IOException e) {
			System.out.println("文件读取错误");
			System.exit(-1);			
		}
	}
}

输出结果就不贴了,就是将文件内容打印出来。


/**
 * 输入参数args[0]、args[1],将前面的文件拷贝到后面的文件中
 * 完成复制拷贝的功能
 */
package com.zhoucy.io;

import java.io.*;

public class TsetFileOutputStream {
	public static void main(String[] args) {
		int b = 0;
		long num = 0L;
		FileInputStream in = null;
		FileOutputStream out = null;
		
		try{
			in = new FileInputStream(args[0]);
			out = new FileOutputStream(args[1]);
			while((b=in.read())!=-1){
				out.write(b);				
			}
			in.close();
			out.close();
		} catch (IOException e) {
			System.out.println("something is wrong!");
			System.exit(-1);
		}
		System.out.println("文件已复制");
	}
}

该例在eclipse中运行,先在 Run<<Run Configurations<<Arguments中设置好传给main的参数,多参数用空格隔开。运行结果是在指定的args[1]路径下复制一份args[0]路径下指定的文件。

下面用字符流完成相同拷贝功能:

package com.zhoucy.io;

import java.io.*;

public class TestFileReader {
	public static void main(String[] args) {
		
		int b = 0;
		FileReader fr = null;
		FileWriter fw = null;
		
		try{
			fr = new FileReader(args[0]);
			fw = new FileWriter(args[1]);
			while((b=fr.read())!=-1){
				fw.write(b);
			}
			fr.close();
			fw.close();
		} catch (FileNotFoundException e) {
			System.out.println("找不到指定文件");
		} catch (IOException e1) {
			System.out.println("文件读取错误");
		}
		System.out.println("文件复制成功");
		
		
	}
}

同样是将指定路径下的文件复制一份到args[1]指定的路径下。


2、处理流

    2.1 缓冲流

    缓冲流要套接在相应的节点流上,对读写的数据提供缓冲的功能,提高读写效率,并且在缓冲流上,有一些新的方法可供使用。


    BufferedReader提供了readLine方法,用以读取一行字符串,BufferedWriter提供了newLine用于写入一个行分隔符。对于输出的缓冲流,会将泻出去的数据先在内存中缓存,使用flush方法会使内存中的数据立刻写出。

package com.zhoucy.io;

import java.io.*;
public class TestBufferStream {
  public static void main(String[] args) {
    try {
      FileInputStream fis = 
         new FileInputStream("e:/java/io/test.java");
      BufferedInputStream bis = 
         new BufferedInputStream(fis);
      int c = 0;
      System.out.println((char)bis.read());
      System.out.println((char)bis.read());
      bis.mark(30);//做标记
      for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
        System.out.print((char)c+" ");
      }
      System.out.println(); 
      bis.reset();//回到做标记的地方(类似于C文件指针归位)
      for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
        System.out.print((char)c+" ");
      }
      bis.close();
    } catch (IOException e) {
    	e.printStackTrace();
    	}
  }
}

    上例是读取test.java这个文件里面的内容,使用缓冲流,套接在字节流上。其中mark和reset方法是成对使用的,mark先标记一下,类似于C语言的文件指针,先标记在调用mark的地方,后面调用reset的时候,使文件指针回到调用mark标记的地方,(java里应该不叫文件指针,但是原理感觉一样)mark后面的参数,是表示,标记以后,继续读取内容,但是不能超过mark的参数指定的字符数,超过以后,mark标记就失效了,reset也就没用了。

    test.java内容是:

class Animal {
	String name;
	Animal(String name) {
		this.name = name;
	}
	public void info() {
		System.out.println("I am Animal");
	}
}


    读取的结果是:



    下面举一个字符缓冲流例子:

package com.zhoucy.io;

import java.io.*;

public class TestBufferedReWr {
	public static void main(String[] args) {
	
		FileReader fr = null;
		FileWriter fw = null;
		
		try{
			fr = new FileReader("e:/java/io/br.txt");
		fw = new FileWriter("e:/java/io/br.txt");
			BufferedReader br = new BufferedReader(fr);
			BufferedWriter bw = new BufferedWriter(fw);
			String s;
			for(int i=0;i<100;i++){
				s = String.valueOf(Math.random());
				bw.write(s);
				bw.newLine();
			}
			bw.flush();
			for(int i=0;i<10;i++) {
				s = br.readLine();
				System.out.println(s); 
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

    该例是往br.txt文件当中写入100行随机数,再从br.txt文件当中读取10行打印到控制台。

执行完以后,br.txt有100行随机数据,打印台信息如下:


    2.2 转换流

    

    用于将字节数据转换成字符数据,下例:

/**
 * 输入英文字符串,转成大写输出
 * 输入exit退出
 */
package com.zhoucy.io;

import java.io.*;

public class TestTransForm {
	public static void main(String[] args) {
		
		try{
			//从控制台输入
			InputStreamReader isr = new InputStreamReader(System.in);
			//转成字符流
			BufferedReader br = new BufferedReader(isr);
			String s;
			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.3 数据流

    

package com.zhoucy.io;

import java.io.*;
public class TestDataArray {
  public static void main(String[] args) {
    ByteArrayOutputStream baos = 
                        new ByteArrayOutputStream(); 
    DataOutputStream dos = 
                        new DataOutputStream(baos);
    try {
      dos.writeDouble(Math.random());
      dos.writeBoolean(true);
      ByteArrayInputStream bais = 
          new ByteArrayInputStream(baos.toByteArray());
      //返回该字节数组剩余的字节数8+1等于9字节
      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 (IOException e) {
      e.printStackTrace();
    }
  }
}


    2.4 打印流


这两项的输出操作不会抛出异常,并且有自动flush功能。

例1:往指定文件打印

package com.zhoucy.io;

import java.io.*;
public class TestPrintStream1 { 
  public static void main(String[] args) {
    PrintStream ps = null;
    try {
      FileOutputStream fos = 
              new FileOutputStream("e:/java/io/dat1.txt");
      ps = new PrintStream(fos);
    } catch (IOException e) {
      e.printStackTrace();
    }
    if(ps != null){
      System.setOut(ps);//往指定的流里面打印
    }
    int ln = 0;
    for(char c = 0; c <= 100; c++){
      System.out.print(c+ " ");
      if(ln++ >=30){ 
      	System.out.println(); 
      	ln = 0;
      }
    }
  }
}



例2:打印指定文件的内容到控制台

//打印文件内容
package com.zhoucy.io;

import java.io.*;
public class TestPrintStream2 {
public static void main(String[] args) {
  String filename = args[0];
  if(filename!=null){
  	list(filename,System.out);
  }
}
public static void list(String f,PrintStream fs){
  try {
    BufferedReader br = 
                new BufferedReader(new FileReader(f));
    String s = null; 
    while((s=br.readLine())!=null){
      fs.println(s);            
    }
    br.close();
  } catch (IOException e) {
    fs.println("无法读取文件");
  }
}
}

结果就不贴了,把参数传给args[0]就行了。

例3:把用户在控制台所做的操作打印到日志文件当中去,程序功能还是输入字母串就输出大写字母串,但是把用户的所有输入和日期记录到后台日志文件。

//将控制台做的操作打印记录到log文件里面
package com.zhoucy.io;

import java.util.*; 
import java.io.*;
public class TestPrintStream3 {
public static void main(String[] args) {
  String s = null;
  BufferedReader br = new BufferedReader(
                      new InputStreamReader(System.in));
  try {
    FileWriter fw = new FileWriter
                         ("e:/java/io/_log.log", true); //Log4J
    PrintWriter log = new PrintWriter(fw);
    while ((s = br.readLine())!=null) {
      if(s.equalsIgnoreCase("exit")) break;
      System.out.println(s.toUpperCase());
      log.println("-----");
      log.println(s.toUpperCase()); 
      log.flush();
    }
    log.println("==="+new Date()+"==="); 
    log.flush();
    log.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}
}




    2.5 Object流(对象流)

import java.io.*;

public class TestObjectIO {
	public static void main(String args[]) throws Exception {
		T t = new T();
		t.k = 8;
		FileOutputStream fos = new FileOutputStream("d:/share/java/io/testobjectio.dat");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(t);
		oos.flush();
		oos.close();
		
		FileInputStream fis = new FileInputStream("d:/share/java/io/testobjectio.dat");
		ObjectInputStream ois = new ObjectInputStream(fis);
		T tReaded = (T)ois.readObject();
		System.out.println(tReaded.i + " " + tReaded.j + " " + tReaded.d + " " + tReaded.k);
		
	}
}

class T 
	implements Serializable//标记性接口,没有方法,告知编译器,表示该类可以被序列化
{
	int i = 10;
	int j = 9;
	double d = 2.3;
	//transient修饰的成员变量在序列化的时候不予考虑,
	//序列化之后输出对象,该值为0
	transient int k = 15;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值