java IO 学习日志

程序中所有的数据都是以“流”的方式进行传输和保存的,程序需要数据要使用输入流读取数据,程序需要将一些数据保存起来时,就要使用输出流。

按处理的数据类型分:

  • 字节流:主要操作 byte 数据类型,以 byte 数组为主,主要的操作类是OutputStream类 和 InputStream类
  • 字符流:主要操作char 数据类型,以char,char[],String为主,主要的操作类是Writer 和 Reader.

按流向分:

  • 输入流:程序从输入流读取数据源,数据源包括外界(键盘,文件,网络....),即将数据源读入到程序的通信通道。
  • 输出流:程序向输出流写入数据, 将程序中的数据输出到外界(显示器,打印机,文件,网络...)等通信通道。  

1.字节输出流:OutputStream(抽象类)

OutputStream 是整个IO 中字节输出流的最大父类(抽象类),要使用此类,则必须通过其子类实例化对象。

OutputStream 定义如下:

public abstract class OutputStream implements Closeable, Flushable

OutputStream 常用方法:

public void close() throws IOException                          //关闭输出流
public void flush() throws IOException                          //刷新缓冲区
public void write(byte[] b) throws IOException                  //将一个byte数组写入数据流
public void write(byte[],int off,int len) throws IOExcetption   //将一个指定范围的byte数组写入数据流
public abstract void write(int b) throws IOException            //将一个字节数据写入数据流

OutputStream 子类 FileOutputStream 实现向文件中写入字符串

/**
 * 向文件中写入字符串
 * 
 * @author lyh
 *
 */
public class OutputStreamDemo1 {
	public static void main(String args[]) throws Exception {
		File file = new File("d:" + File.separator + "OutputStreamDemo-test.txt");
		//恢复现场
		if(file.exists()) file.delete();
		
		OutputStream out = null;
		out = new FileOutputStream(file);
		String str = "Hello world !!";
		// 只能输出byte数组,所以将字符串变为byte数组
		byte[] b = str.getBytes();
		// 将内容输出
		// out.write(b);

		// 以循环的方式输出内容
		for (int i = 0; i < b.length; i++) {
			out.write(b[i]);
		}
		// 关闭输出留
		out.close();
		// 追加新内容
		out = new FileOutputStream(file, true);
		String str2 = "追加Hello world second!!!";
		out.write(str2.getBytes());
		// 换行,追加内容
		String str3 = "\r\n this is new line";
		out.write(str3.getBytes());
		out.close();

	}
}

2.字节输入流: InputStream(抽象类)

InputStream 定义如下:

public abstract class InputStream extends Object implements Closeable
InputStream 类的常用方法:
public int avaiable() throws IOException      //取得输入文件的大小
public void close() throws IOException        //关闭输入流
public abstract int read() throws IOException //以数字的方式读取内容
public int read(byte[] b) throws IOException  // 将内容读到byte[] 数组,同时返回读入的个数

InputStream 子类 FileInputStream 实现读取文件中的数据

/**
 * 通过read() 读取数据
 * 
 * @author lyh
 *
 */
public class InputStreamDemo1 {
	public static void main(String args[]) throws Exception {
		File file = new File("d:" + File.separator + "OutputStreamDemo-test.txt");
		InputStream in = null;
		in = new FileInputStream(file);
		// 用循环的方法为byte b[] 赋值
		/*byte b[] = new byte[(int) file.length()];
		for (int i = 0; i < b.length; i++) {
			b[i] = (byte) in.read();
		}
		 */
		int len = 0;
		byte b[] = new byte[1024];
		int temp = 0;                   // 接收读取的每一个内容
		while ((temp = in.read()) != -1) {
			b[len] = (byte) temp;      // 将每次读取的内容给temp,如果temp不等于-1,表示文件没有读完
			len++;
		}
		in.close(); // 关闭流
		System.out.println("内容是:" + new String(b));
	}
}

3.字符输出流 Writer(抽象类)

Writer (抽象类):

public abstract class Writer extends Object implements Appendable, Closeable,Flushable

Writer类常用方法

public abstract void close() throws IOException    //关闭输出流
public void write(String str) throws IOException   //将字符串输出
public void write(char[] cbuf) throws IOException  //将字符数组输出
public abstract void flush() throws IOException    //强制性清空缓存
(Writer的子类,转换流) OutputStreamWriter的子类 FileWriter 实现向文件中写入数据
public class WriteDemo1 {
	public static void main(String args[]) throws Exception {
		File f1 = new File("D:" + File.separator + "writeDemo.txt");
		Writer out = null;
		out = new FileWriter(f1);
		String str = "Hello World";
		out.write(str); // 写入内容
		out.close();
		// 追加内容
		out = new FileWriter(f1, true); // 将append的值设置为true
		String str2 = "\r\n Hello world agant!!!";
		out.write(str2);
		out.close();

	}
}

4.字符输入流 Reader

Reader(抽象类)

public abstract class Reader extends Object implements Readable,Closeable
Reader类常用方法
public abstract void close() throws IOException //关闭输入流
public int read() throws IOException //读取单个字符
public int read(char[] cbuf) throws IOException //将字符读到字符数组中,返回读入的长度
(Reader的子类,转换流)InputStreamReader的子类 FileReader类实现从文本中读取数据
public class ReaderDemo1 {
	public static void main(String args[]) throws Exception{
		File f1 = new File("D:"+File.separator+"writeDemo.txt");
		if(!f1.exists()){
			System.out.println("文件:"+f1+"不存在");
		}else{
			Reader reader = null;
			reader = new FileReader(f1);
			char c[]=new char[1024];
			//方法1
			//int len = reader.read(c);
			//方法2 利用for循环为char c[] 赋值
			int len = 0;
			int temp = 0;
			while((temp = reader.read())!=-1){
				c[len] =(char)temp;
				len++;
			}
			reader.close();
			System.out.println("内容为:"+ new String(c,0,len));
		}
			
	}
}
字节流与字符流的区别:

  实际上字节流操作不会用到缓冲区(内存),是在文件本身直接操作,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。如若在不关闭操作流的前提下(实际开发中不允许操作为流后不关闭流),用字节流和字符流分别向 type.txt, char.txt文件中写入数据"abc",直接打开文件,会发现type.txt中已被写入数据abc,而char.txt文件却没有,只有在用字符流调用flush(),强制性地将缓冲区中的内容输出,才能在char.txt中看到内容(关闭字符流时会强制性地将缓冲区中的内容输出)。

FileWriter并不直接是Writer的子类,而是OutputStreamWriter的子类,而FileReader也不直接是Reader的子类,是InputStreamReader的子类,从这俩个类的继承关系就能看出,不管是使用字符流还是字节流,实际上最终都是以字节流的方式在操作输入/输出流。

使用字符流好还是字节流好?

当然是具体情况具体分析,但是,所有文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符只有在内存中才会形成,所以在实际的开发中,字节流会应用得比较多一些。

5.转换流-OutputStreamWriter and InputStreamReader

OutputStreamWriter: 是Writer 的子类 ,将输出的字符流变为字节流,即将一个字符流的输出对象变为字节流输出对象。

InputStreamReader:  是Reader的子类,将输入的字节流变为字符流,即将一个字节流的输入对象变为字符流输入对象。

6.内存操作流 ByteArrayOutputStream,ByteArrayInputStream

    内存操作流一般在生成一些临时文件是才会使用,如果是直接使用将临时文件保存在文件的话,则代码执行完后还得删除这个临时文件,所以在此场景中使用内存操作流是最合适的。

ByteArrayInputStream 常用方法:

public ByteArrayInputStream(byte[] buf) //将全部内容写入内存中
public ByteArrayInputStream(byte[] buf,int offset,int length) //将指定范围的内容写入到内存中
ByteArrayOutputStream 常用方法:
public ByteArrayOutputStream() //创建对象
public void write(int b)   //将内容从内存中输出

 内存操作流实现大写字母转换为小写字母

public class ByteArrayDemo {
	public static void main(String args[]){
		String str = "THIS IS A TEST FOR BYTEARRAYDEMO!";
		ByteArrayInputStream in = null;
		ByteArrayOutputStream out = null;
		in = new ByteArrayInputStream(str.getBytes());
		out = new ByteArrayOutputStream();
		
		int temp = 0;
		while((temp=in.read())!=-1){
			out.write(Character.toLowerCase(temp));
		}
		String result = out.toString();
		
		try{
			in.close();
			out.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		
		System.out.println("转换后的结果为  "+result);
	}
}

7.管道流- 管道输出流(PipedOutputStream),管道输入流(PipedInputStream) 

  管道流主要作用于两个线程之间的通信,如果要进行管道输出,则必须把输出流连在输入流上。

管道流实现两个线程的通信

class Send implements Runnable{             //实现Runnable接口
	private PipedOutputStream out= null;
	public Send(){
		this.out = new PipedOutputStream();  //实例化输出流
	}
	public void run(){
		String str = "Hello , this is out speacking!";
		try{
			this.out.write(str.getBytes());   //输出信息
		}catch(IOException e){
			e.printStackTrace();
		}
		
		try{ 
			out.close();                       //关闭流   
		}catch(IOException x){
			x.printStackTrace();
		}
	}
	
	public PipedOutputStream getOut(){
		return out;
	}
}

class Recevie implements Runnable{
	private PipedInputStream in = null;
	public Recevie(){
		this.in = new PipedInputStream();
	}
	public void run(){
		byte b[] = new byte[1024];
		int len = 0;
		try{
			len = this.in.read(b);           //接收数据
		}catch(IOException e){
			e.printStackTrace();
		}
		
		try{
			this.in.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		
	System.out.println("接收到的内容为:" + new String(b,0,len)); 	
		
	}
	public PipedInputStream getIn(){
		return in;
	}
}

public class PipedDemo {
	public static void main(String args[]) {
		Send s = new Send();
		Recevie r = new Recevie();
		try{
			s.getOut().connect(r.getIn());     //连接管道
		}catch(IOException e){
			e.printStackTrace();
		}
		new Thread(s).start();
		new Thread(r).start();
	}
}

8.打印流 

   打印流提供了非常方便的的打印功能,可以打印任何的数据类型,如小数,整数,字符串等。

  字节打印流 PrintStream 是 OutputStrram 的子类,其常用方法有:

public PrintStream(File file) throws FileNotFoundException  //通过一个File对象实例化PrintStream类
public PrintStream(OutputStream out)  //接收OutputStram对象,实例化PrintStram类
public PrintStream printf(Locate I,String format,Object..args)  //根据指定的Locate进行格式化输出
public PrintStream printf(String format,Object..args)  //根据本地环境格式化输出
public void print(boolean b)  //此方式被重载很多次,输出任意数据
public void println(boolean b) //此方式被重载很多次,输出任意数据后换行
PrintStream实现格式化输出:
public class PrintDemo {
	public static void main(String arg[]) throws Exception{
		PrintStream ps = null;
		ps = new PrintStream(new FileOutputStream(new File("d:"+File.separator+"text.txt")));
		ps.print("hello ");
		ps.println("world !!!");
		ps.println("1+1="+ 2);
		/**
		 * 格式化输出
		 * %s 表示输出字符串
		 * %c 表示输出字符
		 * %d 表示输出整数
		 * %f 表示输出小数
		 */
		String name = "李白";       //字符串
		int age = 30;              //整数
		float score = 55.34f;      //小数
		char sex = 'M';            //字符
		ps.printf("name:%s;age:%d;score:%f;sex:%c",name,age,score,sex);
		ps.close();
	}
}
**************************test.txt 结果内容为**********************************************
hello world !!!
1+1=2
name:李白;age:30;score:55.340000;sex:M

**********************************************************************************************

9.字符缓存流 BufferedReader,BufferedWriter

   BufferedReader类用于从缓存区中读取数据,所有的输入字节数据都放在缓冲区中。

   BufferedReader类常用方法

public BufferedReader(Reader in)  //接收一个Reader类的实例
public String readLine() throws IOException //一次性将缓冲区中内容全部读出
BufferedReader 实现接收键盘的输入,将信息打印出来
public class BufferedReaderDemo {
	public static void main(String args[]){
		BufferedReader buf = null;	
		//由于System.in是字节流,而new BufferedReader()的参数为字符流,所以需要用转换流将字节流转换成字符流
		buf = new BufferedReader(new InputStreamReader(System.in)); 
		String str = null;
		System.out.print("请输入内容:");
		try{
			str=buf.readLine();                  //读取输入内容
		}catch(IOException e){
			e.printStackTrace();
		}
		System.out.println("输入的内容为:"+ str);
	}
}




 

  














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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值