Java学习笔记六(I/O流)

 

 1.介绍

在实际开发过程中经常会用到数据的输入/输出操作,本篇博客着重分析一下,java中经经常使用到的有关IO操作的类。而在java中能够将经常使用的流分为两个部分:字节流和字符流。



1.流的抽象基类


字节流 字符流
输入流 InputStream Reader
输出流 OutPutStream Writer

正如上图表格所看到的。字符和字节流都有自己的基类,其余的都是继承基类的扩展流的操作。以下会着重的解说一下。(仅仅要会了字符流,字节流与其操作一样,仅仅只是操作的文件类型不一致而已)



 2.字符流

专门用于读写文本数据。凡是能够用记事本打开的文件比如txt、java、html都数据字符流的操作范围

1.字符输出流——FileWriter

字符输出流一般应用的是FileWriter,然后调用其构造函数,传递字符串的文件名称,将字符写在这个文件里。其次调用父类方法Write(String str)写字符串。在这里须要注意的是字符流写数据,不会直接写在目的文件里。而是写在内存中,必须走一个方法,刷新。将内存中的数据刷新到目的文件里,字符流写数据必须刷新。一般调用的是Void Flush()方法,最后用完后须要关闭流对象。

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package com.IO;

import java.io.FileWriter;
import java.io.IOException;


public class FileWriterDemo1 {

	public static void main(String[] args) {
		FileWriter fw = null;
		try {
			//採用这样的形式的话。每次都会覆盖曾经的数据信息
//			fw=new FileWriter("c:\exception.txt");
			//採用这样的构造器的话,将会採用追加的形式加入数据。
			//查询本机默认编码表示GBK
			fw=new FileWriter("c:\exception.txt",true);
			
			fw.write("abd");
			fw.flush();
			fw.write("弄H啊哦吗");
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("文件写入失败");
			
		}finally{
			try {
				//必须在这里进行推断否则,报错。可能会报空指针的异常信息。

if(fw!=null){ fw.close(); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭资源失败"); } } } } </span></span>


FileWriter写文本文件操作例如以下

单个字符的形式。调用的父类Write(int c)方法

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.Io.iostream;

import java.io.*;
class FileWriterDemo1 
{
	public static void main(String[] args) 
	{
		
		
	//创建输出流对象
		  FileWriter fw = null;
		try{
		  fw = new FileWriter("c:\1.txt");
		  fw.write("abc");
		  fw.flush();
		  fw.write("adb");
		  //将内存中的数据刷新到文件里
		  fw.flush();
		}catch(IOException e){
		   e.printStackTrace();
		   throw new RuntimeException("写入数据失败");
		}finally{
            try{
			  if(fw!=null) 
    		    fw.close();
			}catch(IOException e){
			   e.printStackTrace();
			   throw new RuntimeException("关闭流对象失败");
			}
			
		}
	}
}
</span></span>


字符数组的形式,调用的方法例如以下

~write(char[] ch)传递整个字符数组

~write(char[] ch,int off,int len)写数组的一部分,off開始下标。len个数

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream;
/*
 * FileWriter以数组的形式写入文件
 * 
 */
import java.io.*;
public class FileWriterDemo2 {
	public static void main(String[] args) throws IOException {
		//调用此输出流的构造函数,将会以追加的形式写入到文件内容中
		FileWriter fw = new FileWriter("c:\demo.txt",true);
	
		fw.write(97);
		
		char[] ch= {'a','b','c'};
		fw.write(ch,1,1);
		fw.write("sefser");
		fw.flush();
		fw.close();
	}
}
</span></span>

注意,假设要想文件里追加写入内容,而不是覆盖原来的内容的话。仅仅需在创建输入流对象的时候,调用其FileWriter(String fileName, boolean append)构造方法就可以


2.字符输入流

字符输入流一般应用的是FileReader读取文本文件。然后调用其构造方法,创建输入流对象。传递字符文件名称,比如new FileReader('文件名称')。读取一个字符 int read()方法。每次仅仅读取一个字符,然后指定的read()方法,会自己主动的向后读取一个,读到末尾的时候,将会返回-1

读取单个字符

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream;
/*
 * 採用字符输入流对象。进行读取文件操作
 */
import java.io.*;

public class FileReaderDemo {
	public static void main(String[] args) throws IOException{
		//创建输入流对象
		FileReader fr = new FileReader("c:\demo.txt");
		//调用Read方法。每次仅仅读取一个字符操作
		int x = 0;
		while((x = fr.read())!=-1){
			System.out.print((char)x);
		}
		fr.close();
	}
}

 </span></span>

读取字符数组操作

int read(char[] cbuf):读取方法,传递字符数组。返回值int代表有效读取的字符个数,此方法读取效率高

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.itcast.iostream;
/*
 * 採用字符输入流对象进行字符数组的读取
 */
import java.io.*;
public class FileReaderDemo1 {
	public static void main(String[] args) throws IOException{
		FileReader fr = new FileReader("c:\demo.txt");
		//创建一个字符数组
		char[] ch = new char[1024];//通常是1024的倍数
		int x = 0 ;
		while(( x  = fr.read(ch))!=-1){
			//String(char[] value, int offset, int count) 
			System.out.print(new String(ch,0,x));
		}
		fr.close();
	}
}
</span></span>


拷贝文件操作

利用字符流的输入和输出流,来操作文件的复制功能

第一种方式,读一个字符,写一个字符

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream;
/*
 * 採用字符流来实现复制的功能
 */
import java.io.*;
public class CopyText {
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		//创建字符输入和输出流的对象
		FileReader fr = null;
		FileWriter fw = null;
		try{
			//分别调用其构造函数
			fr = new FileReader("c:\demo.txt");
			fw = new FileWriter("d:\demo.txt");
			//定义变量来报错单个字符读取的值
			int len = 0 ;
			while((len = fr.read())!=-1){
				fw.write(len);
				fw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException("复制失败");
		}finally{
			try{
				if(fw!=null)
					fw.close();
			}catch(IOException e){
				throw new RuntimeException("关闭写入流失败");
			}finally{
				try{
					if(fr!=null)
						fr.close();
				}catch(IOException e){
					throw new RuntimeException("关闭输入流失败");
				}
			}
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}
}
</span></span>

另外一种方法:读一个字符数组。写一个字符数组

<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream;
/*
 *採用输入和输出流完毕复制的功能操作
 */
import java.io.*;
public class CopyText2 {
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		//分别创建字符输入和输出流对象
		FileReader fr = null;
		FileWriter fw = null;
		try{
			//分别调用其构造函数实例化
			fr = new FileReader("c:\e.html");
			fw = new FileWriter("d:\1.html");
			//定义要读取的字符数组
			char[] ch = new char[1024];
			int len = 0 ;
			while((len = fr.read(ch))!=-1){
				fw.write(ch,0,len);
				fw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException("复制失败");
		}finally{
			try{
				if(fw!=null)
					fw.close();
			}catch(IOException e){
				throw new RuntimeException("关闭输出流失败");
			}finally{
				try{
					if(fr!=null)
						fr.close();
				}catch(IOException e){
					throw new RuntimeException("关闭输入流失败");
				}
			}
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}
}
</span></span>


注意:利用读取字符数组的形式,效率会快非常多


 3.缓冲流

在读写的时候。也能够採取缓冲流的形式对字符或者字节进行缓冲,从而实现字符、数组和行的高效读写操作。


字符 字节
缓冲输入流 BufferedReader BufferedInputStream
缓冲输出流 BufferedWriter BufferedOutputStream

主要是在缓冲流中能够採取读取一行方式。来操作源文件。

全部的操作都是一致的,都是通过构造方法的形式,传递字符或者字节流,比如BufferedReader(Reader r),来传递进去FileReader,通过String ReadLine()方法来读取文件的一行,当读到文件末尾的时候,将返回null值

<span style="font-family:SimSun;font-size:18px;">package com.IO;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * 字符输入流。BufferedReader,读取文本一行的功能
 */
public class BufferedReaderDemo {

	public static void main(String[] args) throws IOException {
		
		//建立字符输入流缓冲区对象,传递字符输入对象
		BufferedReader bfr=new BufferedReader(new FileReader("c:\1.txt"));
		
		//開始读取文本一行。返回string
		String line=bfr.readLine();
		System.out.println(line);

	}

}
</span>


其余的BufferedInputStream、BufferedOutPutStream、BufferedReader、BufferedWriter使用方法一致。參照上面写法就可以。

採用缓冲流实现文件复制的效果。


<span style="font-family:SimSun;font-size:18px;">package com.IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.management.RuntimeErrorException;

/*
 * 利用字符流缓冲区来赋值
 * 读写行,写换行
 */
public class CopyTest2 {
	public static void main(String[] args) {
		// 匿名对象的形式。创建流对象和缓存去对象

		BufferedReader bfr = null;

		BufferedWriter brw = null;

		try {
			bfr = new BufferedReader(new FileReader("c:\1.txt"));
			brw = new BufferedWriter(new FileWriter("c:\2.txt"));
			// 读取一行,写一行,写换行
			String line = null;
			while ((line = bfr.readLine()) != null) {
				brw.write(line);
				//进行换行的功能
				brw.newLine();
				brw.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("复制失败");
		}finally{
			try {
				if(bfr!=null){
					bfr.close();
				}
			} catch (IOException e2) {
				throw new RuntimeException("写入关闭失败");
			}finally{
				try {
					if(brw!=null){
						brw.close();
					}
				} catch (IOException e3) {
					throw new RuntimeException("读入关闭失败");
				}
			}
		}
	}

}
</span>



 4.转换流

Java中的转换流一般有两个各自是,OutPutStreamWriter、InputStreamReader。是字符流通向字节流的桥梁。


 

正如上图所看到的,通过缓冲流就能够把字节流转换成为字符流来处理,通过缓冲区一包装,就能够读取行的操作了。

<span style="font-family:SimSun;font-size:18px;">package com.IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class TranseDemo3 {
	public static void main(String[] args) throws IOException {
		/*//控制台输入的字节流
		InputStream in=new FileInputStream("c:\1.java");
		//创建转换流对象,传递字节输入流
		InputStreamReader isr=new InputStreamReader(in);
		//既然已经将in转换成了字符流isr,能够使用字符流缓冲区对象BufferedReader,行读取
		BufferedReader bfr=new BufferedReader(isr);
		
		OutputStream out=System.out;
		OutputStreamWriter  osw=new OutputStreamWriter(out);
		BufferedWriter bfw=new BufferedWriter(osw);*/
		
		BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter brw=new BufferedWriter(new OutputStreamWriter(System.out));
		String line=null;
		while ((line=bfr.readLine())!=null) {
			brw.write(line);
			brw.flush();
			brw.newLine();
		}
		
		brw.close();
		bfr.close();
		
		
		
	}
}
</span>










原文地址:https://www.cnblogs.com/bhlsheji/p/5344094.html