打印流、序列流、管道流等

一、打印流

打印流是输出信息最方便的类,主要包含字节打印流(PrintStream)和字符打印流(PrintWriter)。打印流提供了非常方便的打印功能,可以打印任何的数据类型,例如:小数、整数、字符串等。

1. PrintStream类的常用方法

// 通过一个File对象实例化PrintStream类
public PrintStream(File file) throws FileNotFoundException
// 接收OutputStream对象,实例化PrintStream类
public PrintStream(OutputStream out)
// 接收OutputStream对象,实例化PrintStream类,如果autoFlush为true时,自动刷新输出缓冲区
public PrintStream(OutputStream out, boolean autoFlush)
// 可以自动刷新,可以指定字符编码集
public PrintStream(OutputStream out, boolean autoFlush, String encoding) throws UnsupportedEncodingException
// 根据本地环境格式化输出
public PrintStream printf(String format, Object... args)
// 此方法被重载很多次,可以输出任意数据
public void print(Object obj)
// 此方法被重载很多次,可以输出任意数据后换行
2. 使用PrintStream输出信息

PrintStream printStream = null;        // 声明打印流对象
printStream = new PrintStream(new FileOutputStream(""));
printStream.print("hello ");
printStream.print("world!!!");
printStream.print("1 + 1 = " + 2);
printStream.close();
3. 格式化输出

在JDK1.5之后,Java对PrintStream类进行了扩充,增加了格式化的输出方式,直接使用printf()方法就可以完成操作,但是在进行格式化输出时需要指定其输出数据类型。

NO字符描述
1%s表示内容为字符串
2%d表示内容为整数
3%f表示内容为小数
4%c表示内容为字符
事实上,如果感觉要写好多%s、%d等字符麻烦,可以全部使用%s。

二、序列流,也称合并流

1. SequenceInputStream类的常用方法

// 初始化 SequenceInputStream,,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数
public SequenceInputStream(Enumeration<? extends InputStream> e)
// 返回文件的大小
public int available() throws IOException
2. 范例:将一个mp3文件按指定大小切割成几部分,然后根据切割后的文件还原出被切割的文件

①. 对文件按照一定的大小进行切割,需要指定源与目的,由于还要合成,所以必须要知道,文件切割了几份,文件切割前的名称。

/**
 * 文件切割
 * 
 * @param source
 *            要切割的源文件
 * @param target
 *            切割后,碎文件保存的目录
 * @throws IOException
 */
private static void slicingFile(File source, File target)
		throws IOException {
	// 读取源
	FileInputStream fileInputStream = new FileInputStream(source);
	// 目的
	FileOutputStream fileOutputStream = null; // 由于切割后的碎文件不是一个,这里不能通过具体文件名实例化
	byte[] bytes = new byte[1024 * 1024 * 2]; // 指定要切割的大小
	int len = 0;
	Properties properties = new Properties();
	// 对指定的目录进行判断
	if (!(target.exists() && target.isDirectory())) {
		target.mkdir();
	}
	int count = 1; // 文件计数机,为了给切割后碎片命名
	while ((len = fileInputStream.read(bytes)) != -1) {
		fileOutputStream = new FileOutputStream(new File(target, (count++)
				+ ".part"));
		fileOutputStream.write(bytes, 0, len);
		fileOutputStream.close();
	}
	// 将文件份数,文件名保存到.properties文件中
	File config = new File(target, count + ".properties");
	fileOutputStream = new FileOutputStream(config);
	properties.setProperty("filename", source.getName());
	properties.setProperty("partcount", String.valueOf(count));
	properties.store(fileOutputStream, "");
	fileOutputStream.close();
	fileInputStream.close();
}
②. 文件合并,先要判断合并文件是否存在,目录中存在.properties文件,从.properties文件中拿到碎片的个数,与文件目录中比对,这些都正确之后,开始合并。

/**
 * 合并文件
 * 
 * @param target
 *            要合并文件的目录
 * @throws IOException
 */
private static void merge(File target) throws IOException {
	// 判断该目录是否存在
	if (!target.isDirectory())
		throw new RuntimeException(target.getName() + "不存在");
	// 判断该目录是否有配置文件
	String[] files = target.list(new FilenameFilterByConfig());
	if (files.length != 1)
		throw new RuntimeException("后缀名为.properties的文件不存在或者不止一个");

	File config = new File(target, files[0]);
	FileInputStream fileInputStream = new FileInputStream(config);

	Properties properties = new Properties();
	properties.load(fileInputStream);

	// 获取文件名称和碎片文件个数
	String filename = properties.getProperty("filename");
	int partcount = Integer.parseInt(properties.getProperty("partcount"));

	// 对碎片文件进行过滤
	File[] partFiles = target.listFiles(new FileFilterByPartFile());
	// 对碎片数目进行判断
	if (partFiles.length != (partcount - 1))
		new RuntimeException("碎片个数错误, 不是" + (partcount - 1) + "个");
	// 对碎片名的判断
	for (int i = 0; i < (partcount - 1); i++) {
		File file = new File(target, (i + 1) + ".part");
		if (!file.exists()) {
			throw new RuntimeException(file.getName() + "不存在");
		}
	}
	// 合并
	mergeFile(target, filename, partcount);
}
public class FilenameFilterBySuffix implements FilenameFilter {
	public boolean accept(File file, String name) {
		return name.endsWith(".properties");
	}
}
public class FileFilterByPartFile implements FileFilter {
	public boolean accept(File pathname) {
		return pathname.getName().endsWith(".part");
	}
}
③. 合并文件

/**
 * 合并文件
 * 
 * @param target
 *            要合并文件的目录
 * @param filename
 *            文件名
 * @param count
 *            碎片数目
 * @throws IOException
 */
private static void mergeFile(File target, String filename, int count)
		throws IOException {
	List<FileInputStream> streams = new ArrayList<FileInputStream>();
	for (int i = 0; i < (count - 1); i++) {
		streams.add(new FileInputStream(new File(target, (i + 1) + ".part")));
	}
	// 获取枚举接口对象
	Enumeration<FileInputStream> enumeration = Collections
			.enumeration(streams);
	SequenceInputStream sequenceInputStream = new SequenceInputStream(
			enumeration);
	FileOutputStream fileOutputStream = new FileOutputStream(new File(
			target, filename));
	byte[] bs = new byte[1024];
	int len = 0;
	while ((len = sequenceInputStream.read(bs)) != -1) {
		fileOutputStream.write(bs, 0, len);
	}
	fileOutputStream.close();
	sequenceInputStream.close();
}
三、管道流

管道流的主要作用是可以进行两个线程间的通讯,分为管道输出流(PipedOutputStream)、管道输入流(PipedInputStream),如果想要进行管道输出,则必须把输出流连在输入流之上。

1. 管道流的常用方法

①. PipedOutputStream类

// 创建连接到指定管道输入流的管道输出流
public PipedOutputStream(PipedInputStream snk) throws IOException
// 将此管道输出流连接到接收者。如果此对象已经连接到其他某个管道输入流,则抛出 IOException。
public void connect(PipedInputStream snk) throws IOException
②. PipedInputStream类

// 创建 PipedInputStream,使其连接到管道输出流 src。写入 src 的数据字节可用作此流的输入。
public PipedInputStream(PipedOutputStream src) throws IOException
// 使此管道输入流连接到管道输出流 src。如果此对象已经连接到其他某个管道输出流,则抛出 IOException。
public void connect(PipedOutputStream src) throws IOException
2. 范例

public class Send implements Runnable {
	private PipedOutputStream pipedOutputStream = null; // 声明管道输出流
	public Send() {
		pipedOutputStream = new PipedOutputStream(); // 实例化输出流
	}
	public void run() {
		String str = "Hello World!!!";
		try {
			pipedOutputStream.write(str.getBytes());
			pipedOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 得到此线程的管道输出流
	public PipedOutputStream getPipedOutputStream() {
		return pipedOutputStream;
	}
}
public class Receive implements Runnable{
	private PipedInputStream pipedInputStream = null;
	public Receive () {
		pipedInputStream = new PipedInputStream();
	}
	public PipedInputStream getPipedInputStream() {
		return pipedInputStream;
	}
	public void run() {
		byte[] bytes = new byte[1024];
		int len = 0;
		try {
			len = pipedInputStream.read(bytes);
			pipedInputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("接收到的内容:" + new String(bytes, 0, len));
	}	
}
public static void main(String[] args) {
	Send send = new Send();
	Receive receive = new Receive();
	try {
		send.getPipedOutputStream().connect(receive.getPipedInputStream());  // 链接管道
	} catch (IOException e) {
		e.printStackTrace();
	}
	new Thread(send).start();
	new Thread(receive).start();
}
四、RandomAccessFile
RandomAccessFile类的主要功能是完成随机读取功能,可以读取指定位置的内容。

1. RandomAccessFile 类的常用操作方法

// 接收File类的对象,指定操作路径,但是设置时需要设置模式。“r”:只读、“w”:只写、“rw”:读写
public RandomAccessFile(File file, String mode) throws FileNotFoundException
// 不再使用File类对象表示文件,直接输入一个固定的文件路径
public RandomAccessFile(String name, String mode) throws FileNotFoundException
// 关闭操作
public void close() throws IOException
// 将内容读取到一个byte数据之中。
public int read(byte[] b) throws IOException
// 读取一个字节
public final byte readByte() throws IOException
// 读取整形数据
public final int readInt() throws IOException
// 设置都指针的位置
public void seek(long pos) throws IOException
// 将一个字符串写入文件之中,按字节的方式处理
public final void writeBytes(String s) throws IOException
// 将一个int数据写入文件,长度为4
public final void writeInt(int v) throws IOException
// 指针跳过多少个字节
public int skipBytes(int n) throws IOException
五、内存操作流(ByteArrayInputStream和ByteArrayOutputStream)

ByteArrayInputStream的主要完成将内容写入到内存之中,而ByteArrayOutputStream的功能主要是将内存中的数据输出。

范例:利用内存操作流完成一个大小写转换的程序

String str = "HELLO WORLD!";
OutputStream baos = null; // 内存输出流
InputStream bais = null; // 内存输入流
bais = new ByteArrayInputStream(str.getBytes()); // 向内村输出内容
baos = new ByteArrayOutputStream(); // 准备从内存ByteArrayInputStream读取数据
int temp = 0;
while ((temp = bais.read()) != -1) {
	char c = (char) temp; // 读取的数字变为字符
	baos.write(Character.toLowerCase(c)); // 将字符vain为小写
}
// 所有的数据全都在ByteArrayOutputStream中
String strs = baos.toString();
System.out.println(strs);
try {
	baos.close();
	bais.close();
} catch (Exception e) {
	e.printStackTrace();
}








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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值