黑马程序员-IO流(打印流、管道流、合并流)

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------

  

一、 打印流


1、概述:

 

(1)打印流包括:PrintStream和PrintWriter

(2)该流提供了打印方法,可将各种类型的数据都原样打印

 

2、字节打印流:PrintStream

      构造方法中可接收的参数类型:

(1)file对象:File

(2)字符串路径:String

(3)字符输出流:OutputStream

 

3、字符串打印流:PrintWriter

      构造方法中可接受的参数类型

(1)file对象:File

(2)字符串路径:String

(3)字节输出流:OutputStream

(4)字符输出流:Writer

 

4、代码示例:

import java.io.*;

class PrintDemo {
	public static void main(String[] args) throws IOException {
		// 键盘录入,创建读取流对象
		BufferedReader bufr = new BufferedReader(new InputStreamReader(
				System.in));
		// 使用打印流,将文件输出
		// 输出到屏幕
		PrintWriter out = new PrintWriter(new FileWriter("a.txt"), true);
		String line = null;
		while ((line = bufr.readLine()) != null) {
			if ("over".equals(line))
				break;
			out.println(line.toUpperCase());
			// out.flush();
		}
		bufr.close();
		out.close();
	}
}

 

 

二、管道流


1、概述:

管道流主要用于连接两个线程间的通信,输入输出可以直接进行连接,通过结合线程使用。

字节流:PipedInputStream,PipedOutputStream
字符流:PipedReader,PipedWriter


2、使用步骤:

(1)要先创建一个读和写的两个类,实现Runnable接口,因为是两个不同的线程,覆盖run方法,注意,需要在内部抛异常
(2)创建两个管道流,并用connect()方法将两个流连接
(3)创建读写对象,并传入两个线程内,并start执行

 

3、代码示例:

import java.io.*;

class Read implements Runnable {
	private PipedInputStream in;// 建立输入管道

	Read(PipedInputStream in) {
		this.in = in;
	}

	public void run()// 覆盖run方法,不能throw,只能try。
	{
		try {

			// 读取写入的数据
			System.out.println("开始写入数据,等待时间");// 测试用
			Thread.sleep(3000);
			byte[] buf = new byte[1024];

			System.out.println("读取前。。没有数据阻塞");
			int len = in.read(buf);
			System.out.println("读到数据。。阻塞结束");

			String s = new String(buf, 0, len);// 变成字符串

			System.out.println(s);

			in.close();

		} catch (Exception e) {
			throw new RuntimeException("管道读取流失败");
		}
	}
}

class Write implements Runnable {
	private PipedOutputStream out;// 建立输出管道

	// Write构造函数
	Write(PipedOutputStream out) {
		this.out = out;
	}

	public void run() {
		try {
			System.out.println("开始写入数据,等待6秒后。");// 测试用
			Thread.sleep(6000);
			out.write("管道流来喽~~~~".getBytes());// 字节流
			out.close();
		} catch (Exception e) {
			throw new RuntimeException("管道输出流失败");
		}
	}
}

class PipedStreamDemo {
	public static void main(String[] args) throws IOException {

		PipedInputStream in = new PipedInputStream();
		PipedOutputStream out = new PipedOutputStream();// 创建管道流

		// 将读取流(输入流)和写入流(输出流)关联起来
		in.connect(out);// 连接管道输入流和输出流

		// 创建读写对象,并创建线程对象
		Read r = new Read(in);
		Write w = new Write(out);// 创建Runnable子类对象
		new Thread(r).start();
		new Thread(w).start();// 开启线程
	}
}

/*output:
开始写入数据,等待时间
开始写入数据,等待6秒后。
读取前。。没有数据阻塞
读到数据。。阻塞结束
管道流来喽~~~~
*/


 

三、合并流

 

1、概述:

(1)SequenceInputStream可以将多个流连接成一个源

(2)构造函数:SequenceInputStream(Enumeration<? extends FileInputStream> e)

 

2、如何合并多个文件:

(1)创建集合,并将流对象添加进集合

(2)创建Enumeration对象,将集合元素加入。

(3)创建SequenceInputStream对象,合并流对象

(4)创建写入流对象,FileOutputStream,将数据写入流资源

(5)定义数组,将读取流数据存入数组,并将数组中元素写入文件中。

 

思路:

合并文件的时候,要用到集合,而Vector的效率太低,所以选择用ArrayList。
读取要用序列流SequenceInputStream。但该序列流要传入枚举类型的参数。 
而枚举是Vector中的方法,ArrayList 中没有枚举方法,只有相似的Iterator迭代器。

故可建立枚举的匿名类,复写类中的方法以返回调用Iterator的方法即可。 
 
注:匿名内部类访问的局部变量要用final修饰。  
 

代码示例:假设有三个文件,将三者合并到一个新文件中

import java.io.*;
import java.util.*;

class SequenceDemo {
	// 合并流对象
	public static void sequenceFile() throws IOException {
		FileOutputStream fos = null;
		SequenceInputStream sis = null;
		try {
			// 创建集合,存储多个文件
			ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
			for (int i = 1; i <= 3; i++) {
				al.add(new FileInputStream(i + ".txt"));
			}
			// 匿名内部类访问局部变量要final
			final Iterator<FileInputStream> it = al.iterator();
			// 创建Enumeration匿名对象
			Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
				public boolean hasMoreElements() {
					return it.hasNext();
				}

				public FileInputStream nextElement() {
					return it.next();
				}
			};
			// 合并流对象,将集合元素加入。
			sis = new SequenceInputStream(en);
			// 创建写入流对象,FileOutputStream
			fos = new FileOutputStream("7.bmp");
			byte[] b = new byte[1024 * 1024];
			int len = 0;
			// 循环,将数据写入流资源
			while ((len = sis.read(b)) != -1) {
				fos.write(b);
			}

		} catch (IOException e) {
			throw new RuntimeException("文件操作失败");
		}
		// 关闭流资源
		finally {
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				throw new RuntimeException("关闭流资源操作失败");
			}
			try {
				if (sis != null)
					sis.close();
			} catch (IOException e) {
				throw new RuntimeException("关闭流资源操作失败");
			}
		}
	}

	public static void main(String[] args) throws IOException {
		sequenceFile();
	}
}

 

3、切割流资源:

1、先关联文件FileInputStream

2、定义写入流变量:FileOutputStream

3、创建数组,并定义切割所需的大小|

4、循环读写数据,并每次创建一个新写入流,创建完后并写入文件中

5、关闭流资源

 

代码示例:

import java.io.*;

public class SplitFile {

	// 切割流对象
	public static void splitFile() throws IOException {
		// 创建全局变量
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			// 创建文件读取流
			fis = new FileInputStream("11.jpg");
			// 创建数组
			byte[] b = new byte[1024 * 1024];
			int len = 0;
			// 计数器
			int count = 1;
			// 循环写入数据
			while ((len = fis.read(b)) != -1) {
				// 每次创建一个新写入流,写入后关闭流资源
				fos = new FileOutputStream((count++) + ".part");
				fos.write(b, 0, len);
				fos.close();
			}
		} catch (IOException e) {
			throw new RuntimeException("关闭流资源操作失败");
		}
		// 关闭流资源
		finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				throw new RuntimeException("关闭流资源操作失败");
			}
		}

	}

	public static void main(String[] args) throws Exception {
		splitFile();
	}
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值