JAVA SE(二十一)—— I/O 流2(文件流:字符流、字节流、转换流、缓冲流、对象流)

一、IO流基本概念

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。 即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流与操作系统建立连接,将数据传过去,这种方式就是流的传递

二、IO流分类

1、根据处理数据类型的不同分类
(1)字节流
(2)字符流

2、根据数据流向不同分类
(1)输入流:只能进行读操作
(2)输出流:只能进行写操作

三、字节流

1、字节输出流 OutputStream
(1)此抽象类是表示输出字节流的所有类的超类,其子类:FileOutputStream 表示字节输出流(写入)。

(2)OutputStream的方法
① 构造方法:FileOutputStream(File file):

FileOutputStream fos = new FileOutputStream( "d:\\test\\java.txt");

这个构造方法会在指定路径创建指定文件,如上例会在 d:\test 目录下创建 java.txt 文件。

write()方法

  • write(int b):写入单个数据
  • write(byte[ ] b):写入整个字节数组
  • write(byte[ ] b,int off , int len) :写入字节数组的某一部分,int off 表示偏移量,int len 是要写入的字节长度。

Demo:

import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream( "d:\\test\\java.txt" , true);
		// write(int b) 方法
		fos.write(99);
		// write(byte[] b) 方法
		String str = "abcdefg";
		byte[ ] b = str.getBytes( );
		fos.write(b);
		// write(byte[ ] b,int off , int len) 方法
		fos.write(b, 1, 3);
		fos.close( );
	}
}
运行结果为:
cabcdefgbcd
对应代码中三次写入一次为:c  abcdefg  bcd 

③ 追加模式
追加模式顾名思义就是每次写入不覆盖之前的数据,而是以追加形式写在原有数据的末尾,其构造方法为FileOutputStream(String name ,boolean append)
当append为true时是追加模式,false时为覆盖模式,不写的时候默认是覆盖模式。

FileOutputStream fos = new FileOutputStream( "d:\\test\\java.txt" , true);

④ close() 方法
close() 方法表示关流,对应代码执行完之后必须关流。

2、字节输入流 InputStream
(1)此抽象类是表示输入字节流的所有类的超类,子类:FileInputStream 表示字节输入流(读取)。

(2)InputStream的方法
① 构造方法:FileInputStream(String path)

FileInputStream fis = new FileInputStream( "d:\\test\\java.txt");

②read() 方法

  • read():读取单个数据
  • read(byte[] b):读取整个字节数组
  • read(byte[] b,int off,int len):读取字节数组的某一部分数据

如下Demo:

import java.io.FileInputStream;
import java.io.IOException;
public class Demo {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream( "d:\\test\\java.txt");
		// read() 方法
		int read = fis.read( );
		System.out.println( read );
		byte read1 = (byte) fis.read( );
		System.out.println( read1 );
		
		// read(byte[] b) 方法
		byte[ ] bytes1 = new byte[3];
		int read2 = fis.read( bytes1 );
		System.out.println( read2 );
		
		// read(byte[] b,int off,int len) 方法
		byte[ ] bytes2 = new byte[3];
		int read4 = fis.read(bytes2);
		String  read3 = new String ( bytes2 , 1 , read4 );
		System.out.println( read3 );
		//关流
		fis.close();
	}
}

注意:read() 方法每次读取后会自动往后推移。

3、案例演示
(1)Demo:输入流异常处理

public class Demo1 {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("text.txt");
			byte[] bytes = new byte[3];
			int read = -1;
			while((read = fis.read(bytes)) != -1) {
				System.out.println(new String(bytes, 0, read));
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			try {
				if(fis != null) {
					fis.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
}

(2)Demo:字节流完成文件的复制
① 第一种:

public class Copy {
	public static void main(String[] args) throws IOException {
		//绑定数据源
		FileInputStream fis = new FileInputStream("d:\\test1\\demo.txt");
		//明确数据输出目的文件夹
		FileOutputStream fos = new FileOutputStream("d:\\test2\\demo.txt",true);
		int read = -1;
		while((read = fis.read()) != -1) {
			fos.write(read);
		}
		fis.close();
		fos.close();
	}
}

② 第二种:

public class Copy {
	public static void main(String[] args) throws IOException {
		//绑定数据源
		FileInputStream fis = new FileInputStream("d:\\test1\\demo.txt");
		//明确数据输出目的文件夹
		FileOutputStream fos = new FileOutputStream("d:\\test2\\demo.txt",true);
		byte[] bytes = new byte[10];
		int read = -1;
		while((read = fis.read(bytes)) != -1) {
			fos.write(bytes, 0, read);
		}
		fis.close();
		fos.close();
	}
}

(3)4、统计一个文件test…Java文件中有多少个字母”a”和”A”的个数

public class CountAa {
	public static void main(String[] args) throws Exception {		
		FileInputStream fis = new FileInputStream("d:\\test.java");
		BufferedInputStream bis = new BufferedInputStream(fis);
		int read = -1;
		byte z;
		int count = 0;
		while((read = bis.read() )!= -1){
			if(read == 65 || read == 97){
				count++;
			}
		}
fis.close();
		bis.close();
		System.out.print("文件中A和a出现的总次数是:"+count);
	}
}

四、字符流

1、字符输出流(写出)FileWriter
(1)FileWriter的主要方法
① 构造方法 FileWriter(File file)

FileWriter fw = new FileWriter("d:\\text");

② 字符写入方法

  • write(int c):写出单个字符
  • write(char[] c):写入整个字符数组
  • write(char[] cbuf, int off, int len):写入字符数组的某一部分

Demo1:

public class Demo1 {
	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("d:\\text",true);
		//write(int c)
		fw.write(99);
		fw.write("你好");
		//write(char[] c)
		char[] ch = {'我', '在', '写', '入', '数', '据'};
		fw.write(ch);
		//fw.write(cbuf, off, len);
		char[] ch1 = {'我', '也','在', '写', '入', '数', '据'};
		fw.write(ch1, 1, 3);
		//关流
		fw.close();
	}
}

2、字符输入流(读取) FileReader
(1)FileReader的主要方法 ① 构造方法FileReader(File file)`

FileReader fr = new FileReader("d:\\text\\demo.txt");

② 读取方法

  • read():读取单个字符。
  • read(char[] cbuf):读入整个字符数组。
  • read(char[] cbuf, int off, int len):读入字符数组的某一部分。

Demo2:

public class Demo2 {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("d:\\text\\demo.txt");
		char[] ch = new char[3];
		int read =  -1;
		while((read = fr.read()) != -1) {
			System.out.println((char)read);
		}
		fr.close();
	}
}

3、案例演示
(1)Demo:字符流完成文件复制
① 第一种

public class Copy {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("d:\\text1\\demo.txt");
		FileWriter fw = new FileWriter("d:\\text2\\demo.txt",true);
		int read =  -1;
		while((read = fr.read()) != -1) {
			fw.write((char)read);
		}
		fr.close();
		fw.close();
	}
}

② 第二种

public class Copy {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("d:\\text1\\demo.txt");
		FileWriter fw = new FileWriter("d:\\text2\\demo.txt",true);
		char[] ch = new char[3];
		int read =  -1;
		while((read = fr.read(ch)) != -1) {
			fw.write(ch);
		}
		fr.close();
		fw.close();
	}
}

(2)在D盘下创建一个HelloWorld.txt文件,判断他是文件还是目录,是目录则再创建一个目录IOTest,并将HelloWorld.txt移动到IOTest目录下去,之后遍历IOTest这个目录下的文件。

public class JavaIO {
	public static void main(String[] args) throws IOException {
		File file = new File("d:\\HelloWorld.txt");
		//创建文件
		file.createNewFile();
		if(file.isFile()) {
			File file1 = new File("d:\\IOTest");
			//创建文件夹
			file1.mkdir();
			 FileReader fr = new FileReader(file);
			 FileWriter fw = new FileWriter(file1 + "\\" + file.getName(),true);
			 int read = -1;
			 while((read = fr.read()) != -1) {
				 fw.write(read);
			 }
			 findFile(file1);
			 fw.close();
			 fr.close();
			 //删除原路径的HelloWorld.txt文件
			 file.delete();
		}else {
			System.out.println(file + "是一个文件目录");
		}
	}
	//递归
	public static void findFile(File file) {
		File[] files = file.listFiles();
		for(File f: files) {
			if(f.isDirectory()) {
				//输出这个文件夹名,然后递归调用
				System.out.println(f);
				findFile(f);
			}else if(f.isFile()) {
				//输出这个文件名
				System.out.println(f);
				if(f.getName().equals("HelloWorld.txt")) {
				}
			}
		}
	}
}

五、转换流

1、InputStreamReader(InputStream,String charsetName) in 表示字节输入流 charsetName 表示字符编码的名字: utf-8 、gbk utf-8有一个默认bom头文件,占三个字节:?
InputStreamReader: 字节流通向字符流的桥梁
OutputStreamWriter: 字符流通向字节流的桥梁

public class Demo1{
	public static void main(String[] args) {
		FileInputStream fis = null;
		InputStreamReader isr = null;
		try {
			fis = new FileInputStream("D:\\测试\\123.txt");
			isr = new InputStreamReader(fis,"UTF-8");
			char[] ch = new char[10];
			int read = -1;
			while ((read = isr.read(ch)) != -1) {
				System.out.print(new String(ch, 0, read));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(isr != null) {
					isr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

2、转换流完成文件的复制

public class Demo2{
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("D:\\测试\\123.txt");
		InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
		FileOutputStream fos = new FileOutputStream("D:\\测试\\test1.txt",true);
		OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
		
			char[] ch = new char[1024];
			int read = -1;
			while ( ( read = isr.read(ch) ) != -1) {
				osw.write(ch, 0, read);
			}
			osw.close();
			isr.close();
			isr.close();
			fis.close();
	}
}

六、缓冲流

1、缓冲字节流
(1)缓冲字节输入流 BufferedInputStream

  • 构造方法 BufferedInputStream(InputStream in)
  • 读入方法Demo read(byte[] b, int off, int len)

(2)缓冲字节输出流 BufferedOutputStream

  • 构造方法Demo BufferedOutputStream(OutputStream out)
  • 写出方法Demo write(byte[] b, int off, int len)
  • 写出去 默认缓冲大小8kb,8*1024

(3)转换字节流完成文件的复制

public class Test9 {
	//转换字节流
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream( "D:\\Test1\\HelloWorld.txt" );
		BufferedInputStream bis = new BufferedInputStream(fis);
		FileOutputStream fos = new FileOutputStream( "D:\\Test1\\IOtest\\HelloWorld.txt" );
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int read = -1;
		while ( ( read = bis.read( ) ) != -1 ) {
			bos.write(read);
		}
		bos.close();
		fos.close();
		bis.close();
		fis.close();
	}
}

(4)缓冲流与字节流比较

public class Test1 {
	//字节流与缓冲流比较
	public static void main(String[] args) throws IOException {
		//复制开始时间,下同
		long start = System.currentTimeMillis();
		//调用copy_1()方法,下同
		copy_1( new File ("D:\\Test1\\Test3\\q.zip"), new File("D:\\Test1\\Test3_1\\q.zip"));
		//复制结束时间,下同
		long end = System.currentTimeMillis();
		System.out.println( "耗时1" + ( end - start ) );
		
		long start2 = System.currentTimeMillis();
		copy_2( new File ("D:\\Test1\\Test3\\q.zip"), new File("D:\\Test1\\Test3_2\\q.zip"));
		long end2 = System.currentTimeMillis();
		System.out.println( "耗时" + ( end2 - start2 ) );
		
		long start3 = System.currentTimeMillis();
		copy_3( new File ("D:\\Test1\\Test3\\q.zip"), new File("D:\\Test1\\Test3_3\\q.zip"));
		long end3 = System.currentTimeMillis();
		System.out.println( "耗时" + ( end3 - start3 ) );
		
		long start4 = System.currentTimeMillis();
		copy_4( new File ("D:\\Test1\\Test3\\q.zip"), new File("D:\\Test1\\Test3_4\\q.zip"));
		long end4 = System.currentTimeMillis();
		System.out.println( "耗时" + ( end4 - start4 ) );
	}
	
	//不加缓冲:一次读取一个字节
	public static void copy_1( File oldfile , File newfile ) throws IOException {
		FileInputStream fis = new FileInputStream(oldfile);
		FileOutputStream fos = new FileOutputStream(newfile);
		int read = -1;
		while ( ( read = fis.read( ) ) != -1 ) {
			fos.write(read);
		}
		fis.close();
		fos.close();
	}
	//不加缓冲:一次读取一个字节数组
	public static void copy_2( File oldfile , File newfile ) throws IOException {
		FileInputStream fis = new FileInputStream(oldfile);
		FileOutputStream fos = new FileOutputStream(newfile);
		int read = -1;
		byte[] bytes = new byte[1024];
		while ( ( read = fis.read(bytes) ) != -1 ) {
			fos.write(bytes, 0, read);
		}
		fis.close();
		fos.close();
	}
	//加缓冲:一次读取一个字节
	public static void copy_3( File oldfile , File newfile ) throws IOException {
		FileInputStream fis = new FileInputStream(oldfile);
		BufferedInputStream bis = new BufferedInputStream(fis);
		FileOutputStream fos = new FileOutputStream(newfile);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int read = -1;
		while ( ( read = bis.read( ) ) != -1 ) {
			bos.write(read);
		}
		fis.close();
		fos.close();	
	}
	//加缓冲:一次读取一个字节数组
	public static void copy_4( File oldfile , File newfile ) throws IOException {
		FileInputStream fis = new FileInputStream(oldfile);
		BufferedInputStream bis = new BufferedInputStream(fis);
		FileOutputStream fos = new FileOutputStream(newfile);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int read = -1;
		byte[] bytes = new byte[1024];
		while ( ( read = bis.read(bytes) ) != -1 ) {
			bos.write(bytes, 0, read);
		}
		fis.close();
		fos.close();
	}
}

2、缓冲字节流
(1)缓冲字符输入流 BufferedReader

  • 构造方法 BufferedReader(Reader in)
  • 读取方法 readLine():一次读取一行,读到末尾返回null

(2)缓冲字符输出流 BufferedReader

  • 构造方法 BufferedWriter(Writer out)
  • 写出方法 write(int c)

(3)Demo1:缓冲字符流完成文件的复制

public class Demo1 {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader( "D:\\Test1\\HelloWorld.txt" );
		BufferedReader br = new BufferedReader(fr);
		FileWriter fw = new FileWriter( "D:\\Test1\\IOtest\\HelloWorld.txt" );
		BufferedWriter bw = new BufferedWriter(fw);
		String line = null;
		while ( ( line = br.readLine() ) != null ) {
			bw.write(line);
			bw.newLine();
		}
		br.close();
		bw.close();
	}
}

(4)Demo2:统计一个文件目录下所有Java文件的所有代码行数。

public class Demo2 {
	public static int count = 0;
	public static void main(String[] args) throws IOException {
		File file = new File("d:\\test");
		find(file);
		System.out.println("所有java文件的代码总行数为:" + count);		
	}
	public static void find(File file) throws IOException {
		File[] listFiles = file.listFiles();
		for(File f: listFiles) {
			if ( f.isDirectory()) {
				find(f);
			}else if(f.isFile() && f.getName().endsWith(".java")) {
				count(f);
			}
		}
	}
	public static void count( File file) throws IOException {
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String line = null;
		while((line = br.readLine()) != null) {
			count++;
		}
		br.close();
		fr.close();
	}
}

七、对象流

1、对象的序列化与反序列化以及对象流
对象要进行序列化,必须要实现serializable接口 这种接口叫做标记性接口,里面什么东西都没有。
(1)对象的序列化: 将对象转换成字节数组的方式储存

(2)对象的反序列化:将字节数组转换成对象

(3)作用

  • 可以将对象持久化保存
  • 实现对象的远程调用

(4)应用
分布式系统

2、对象流 Object
(1)对象输出流 ObjectOutputStream

  • 构造方法 ObjectOutputStream()
  • 写入方法 writeObject()

(2)对象输入流 ObjectInputStream

  • 构造方法 ObjectIutputStream()
  • 读取方法 readObject()

(3)Demo:对象流完成写入再读取

public class Test3{
	//对象流
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		FileInputStream fis = new FileInputStream( "D:\\Test1\\HelloWorld.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		FileOutputStream fos = new FileOutputStream( "D:\\Test1\\HelloWorld.txt" );
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		//写入
		Student student = new Student( "zhangsan" , 18 , "nan" );
		Student student2 = new Student( "zhangsan" , 18 , "nan" );
		Student student3 = new Student( "zhangsan" , 18 , "nan" );
		Student student4 = new Student( "zhangsan" , 18 , "nan" );
		Student student5 = new Student( "zhangsan" , 18 , "nan" );
		oos.writeObject(student);
		oos.writeObject(student2);
		oos.writeObject(student3);
		oos.writeObject(student4);
		oos.writeObject(student5);
		//读取
		Object ro = ois.readObject();
		Student s = (Student)ro;
		System.out.println(s);
		//关流
		ois.close();
		oos.close();
	}
}

发布了40 篇原创文章 · 获赞 0 · 访问量 353

猜你喜欢

转载自blog.csdn.net/baidu_27414099/article/details/104425556