Java中IO流的介绍

之前学习Java_SE时候对于Java中IO这一块简略看,之后看Java_Web时候总会用到一些流,所以今天查查资料浏览众多高人博客,整理了一番,希望大家多给意见
package cn.iotest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.SequenceInputStream;
import java.io.Writer;
import cn.iotest.User;

import org.apache.commons.io.IOUtils;
import org.junit.Test;

public class Demo1 {
	// File类相关操作
	/**
	 * 创建一个新文件,boolean file.createNewFile() 运行结果为true
	 * 
	 * @throws IOException
	 */
	@Test
	public void test1() throws IOException {
		String filename = "D:/newfile.txt";
		File file = new File(filename);
		System.out.println(file.createNewFile());
	}

	/**
	 * File中的两个常量File.pathSeparator,File.separator 下例结果为 ; \
	 */
	@Test
	public void test2() {
		System.out.println(File.pathSeparator);
		System.out.println(File.separator);
	}

	/**
	 * 保持代码健壮,因为在Windows下分隔符是\,但是在Linux中就不一定了,所以用静态常量最安全 下例结果也为true
	 * 再提一句,有可能有些朋友对'\'和'/'迷糊的,其实'\'和'/'是一个意思,电脑都能读懂,
	 * 但是单个'\'是转义字符的意思,所以用'\'时需要打两个,也就是'\\' "D:/new.txt" 等同于 "D:\\new.txt"
	 * 
	 * @throws IOException
	 */
	@Test
	public void test3() throws IOException {
		String filename = "D:" + File.separator + "new.txt";
		File file = new File(filename);
		System.out.println(file.getName() + "\n" + file.toString() + "\n"
				+ file.getPath());

	}

	/**
	 * 删除一个文件:file.exists(),file.delete() 先判断存不存在,存在再删除 下例结果为true
	 */
	@Test
	public void test4() {
		String filename = "D:" + File.separator + "newfile.txt";
		File file = new File(filename);
		if (file.exists())
			System.out.println(file.delete());
	}

	/**
	 * 创建一个文件夹file.isDirectory(),file.mkdir() 下例结果为true
	 */
	@Test
	public void test5() {
		String filename = "D:" + File.separator + "newfile";
		File file = new File(filename);
		if (!file.isDirectory()) {
			System.out.println(file.mkdir());
		}
	}

	/**
	 * 列出指定目录的所有文件(文件名形式) 结果为 JTattoo.jar libquaqua.jnilib libquaqua64.jnilib
	 * quaqua.jar
	 */
	@Test
	public void test6() {
		String filename = "D:" + File.separator + "lookandfeel";
		File file = new File(filename);
		if (file.isDirectory()) {
			String[] list = file.list();
			for (String i : list) {
				System.out.println(i);
			}
		}
	}

	/**
	 * 列出指定目录的所有文件(包括隐藏文件,用路径形式)file.listFiles() D:\lookandfeel\JTattoo.jar
	 * D:\lookandfeel\libquaqua.jnilib D:\lookandfeel\libquaqua64.jnilib
	 * D:\lookandfeel\quaqua.jar 这里直接在控制台输出对象其实是默认调用了对象的toString方法,而且该方法也已经被 重写了
	 */
	@Test
	public void test7() {
		String filename = "D:" + File.separator + "lookandfeel";
		File file = new File(filename);
		if (file.isDirectory()) {
			File[] list = file.listFiles();
			for (File i : list) {
				System.out.println(i);
			}
		}
	}

	/**
	 * 使用RandomAccessFile写入文件 此时打开new.txt,结果是乱码。用处再议
	 * 
	 * @throws IOException
	 */
	@Test
	public void test8() throws IOException {
		String filename = "D:" + File.separator + "new.txt";
		File file = new File(filename);
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		raf.write(12);
		raf.writeBoolean(true);
		raf.writeFloat(12.3f);
	}

	// 字节流
	/**
	 * 向文件写入字符串out.write(bytes) 字符转字节,再输出到文件中
	 * 
	 * @throws IOException
	 * 
	 */
	@Test
	public void test9() throws IOException {
		String filename = "D:" + File.separator + "new.txt";
		File file = new File(filename);
		OutputStream out = new FileOutputStream(file);
		String word = "写入的话";
		byte[] bytes = word.getBytes();
		out.write(bytes);
		out.close();
	}

	/**
	 * 添加新内容 new FileOutputStream(file,true)表示为追加,而不是重写
	 */
	@Test
	public void test10() throws IOException {
		String filename = "D:" + File.separator + "new.txt";
		File file = new File(filename);
		OutputStream out = new FileOutputStream(file, true);
		String word = "写入";
		byte[] bytes = word.getBytes();
		for (int i = 0; i < bytes.length; i++) {
			out.write(bytes[i]);
		}
		out.close();
	}

	/**
	 * 读取文件内容 IOUtils为commons-io的一个jar包,其中IOUtils.toByteArray(in)直接返回读取数据的
	 * byte数组 输出结果为“写入的话写入”
	 * 
	 * @throws IOException
	 */
	@Test
	public void test11() throws IOException {
		String filename = "D:" + File.separator + "new.txt";
		File file = new File(filename);
		InputStream in = new FileInputStream(file);
		byte[] bytes = IOUtils.toByteArray(in);
		in.close();
		System.out.println(new String(bytes));

	}

	// 字符流
	/**
	 * 字符流和字节流在读写上面唯一的区别是一个是读写char,一个是读写byte
	 * 
	 * 还有一点,字节流不通过缓冲区操作文件,字符流通过缓冲区操作文件 可以试一下二者在写入信息时都不执行close()操作,结果是字节流有效,字符流无效
	 * 但刷新一下缓冲区一样有效
	 * 
	 * @throws IOException
	 */
	@Test
	public void test12() throws IOException {
		String fileName = "D:" + File.separator + "new.txt";
		File f = new File(fileName);
		char[] ch = new char[100];
		Reader read = new FileReader(f);
		int count = read.read(ch);
		read.close();
		System.out.println("读入的长度为:" + count);
		System.out.println("内容为" + new String(ch, 0, count));
	}

	// 字符流转化为字节流
	// 主要介绍OutputStreamWriter和InputStreamReader
	/**
	 * 字符输出流转化为字节输出流 可能不好理解,简单来说就是你存的是字符,但是最后转化为了字节存储
	 * 字节送给writer,然后writer再通过转换将数据转为字节传给指定outputStream
	 * 
	 * 最后结果为hello,看清楚,我们输入的是String也就是char[]
	 * 
	 * @throws IOException
	 */
	@Test
	public void test13() throws IOException {
		Writer writer = new OutputStreamWriter(new FileOutputStream("D:"
				+ File.separator + "test13.txt"));
		writer.write("hello");
		writer.close();
	}

	/**
	 * InputStreamReader无非是用将数据以字节流读入,最后用char[]接收,不浪费篇幅了
	 */
	/**
	 * 博主最近学习时接触到outputStreamWriter类,给大家说一下,觉得有启发的看官就收着 没啥用就跳过
	 * 将该类用于SAX解析器解析XML文档进行XML回写的相关操作
	 * XML回写用的是XMLWriter类,需求的是一个Writer子类,但是相关类是不提供编码设置的,
	 * 也就是说必须使用指定默认编码,这不扯淡么!这时就要用outputStreamWriter类来设置
	 * 编码了,就是带编码格式的outputStreamWriter构造器
	 */
	// @Test
	// public void test14(Object user){
	// //省去部分代码,此处没导dom4j的jar包,没找到相关类而已
	// XMLWriter writer;
	// try {
	// /**
	// * 将输入的信息以utf-8的编码方式转化为字节输出流保存起来,format是一个格式规范器
	// */
	// writer = new XMLWriter(new OutputStreamWriter(
	// new FileOutputStream(path),"UTF-8"), format);
	// writer.write(doc );//doc为Document文档对象
	//
	//
	// }
	/**
	 * PrintStream(装饰流)
	 * 打印流最主要的是区别,打印流可以选择控制台也可以选择文件作为目的地。 例如:System.out.println就是把目的地选择为了控制台。
	 * 当然如果输出到文件,如果使用打印流则是将打印流指定到输出流管道, 实现输出的还是输出流。因此,如果目的地是文件,选择输出流较好。
	 * 
	 * 结果为: append13 c
	 * 
	 * @throws IOException
	 */
	@Test
	public void test14() throws IOException {
		PrintStream ps = new PrintStream(new FileOutputStream("D:"
				+ File.separator + "test14.txt"));
		ps.append("append");
		byte[] bytes = "write".getBytes();
		ps.println(13);
		ps.print('c');
	}

	/**
	 * 使用OutputStream向屏幕输出数据 只需要构造OutputStream output = System.out; 其他操作相同即可
	 * 
	 * @throws IOException
	 */

	/**
	 * BufferedReader,只能接受字符流的缓冲区,将System.in转换为字符流(装饰流)
	 * 
	 * BufferedReader buf = new BufferedReader( new
	 * InputStreamReader(System.in));
	 */
	@Test
	public void test15() throws IOException {
		BufferedReader buf = new BufferedReader(
				new InputStreamReader(System.in));
		System.out.println("请输入你要输出的信息");
		String words = buf.readLine();
		System.out.println("您输出的信息是" + words);
		buf.close();
	}

	/**
	 * 合并流 SequenceInputStream(没有SequenceOutputStream)
	 * 将两个字节输入流按前后顺序合并为一个字节输入流,其他操作可以对合并流进行(装饰流)
	 * @throws IOException 
	 */
	@Test
	public void test16() throws IOException{
		InputStream in1 = new FileInputStream("D:"+ File.separator + "test16_1.txt");
		InputStream in2 = new FileInputStream("D:"+ File.separator + "test16_2.txt");
		OutputStream out = new FileOutputStream("D:"+ File.separator + "test16_out.txt");
		SequenceInputStream seq = new SequenceInputStream(in1, in2);
		byte[] temp = null;
		int count;
		//读,IOUtils.toByteArray()是封装好的将输入流的数据转化为byte数组
		temp = IOUtils.toByteArray(seq);
		//写
		out.write(temp);
	}
	/**
	 * 最后说一下序列化与反序列化,一个类想要能被序列化,首先要实现Serializable接口
	 * 这个接口里面没有任何方法,只要声明,就说明这个类能够被序列化,具体什么是序列化
	 * 先来看看ObjectInputStream和ObjectOutputStream两个类(装饰流)
	 * ObjectOutputStream用来将对象转化为二进制数据进行存储
	 * ObjectInputStream用来将数据进行转化为对象
	 * 
	 * 下例输出结果为
	 * User [username=张三, age=21]
	 * 
	 * 
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 * @throws ClassNotFoundException 
	 */
	@Test
	public void test17() throws FileNotFoundException, IOException, ClassNotFoundException{
		File file = new File("D:"+ File.separator + "test17.txt");
		ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream(file));
		objout.writeObject(new User("张三",21));//这时写进的是二进制数据
		ObjectInputStream objin = new ObjectInputStream(new FileInputStream(file));
		Object user = objin.readObject();//写到这里时记得导入相应对象的包,由于返回Object类型,他是不会提醒你的
		//至于这一块JVM是怎么认出读出的数据是User对象的,可能序列化时候有唯一标识吧,这里我也不清楚它怎么实现的
		System.out.println(user.toString());
	}
	/**
	 * 再来简略谈谈Externalizable接口,Serializable接口默认实现全部属性序列化
	 * 注意!序列化时只有属性被序列化
	 * 而继承Externalizable接口则可以由我们自己定实现哪些属性被序列化
	 * 并且这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,
	 * 这是因为在反序列话的时候会默认调用无参的构造函数。
	 * 
	 * 该接口有两个方法需要实现,一个就是序列化,一个就是反序列化
	 * 
	 */
	/**
	 * 对于Externalizable接口,实现太过麻烦,对于不想被序列化的属性
	 * 我们只需要加上关键字transient即可
	 * transient关键字的意义简单说就是被修饰的成员不会被本地化
	 * 例如账号的密码可以用这个修饰
	 */
	/**
	 * IO流简单说道这里,有一些较偏的我也没有整理(博主也起步学习不久)。越努力,越幸运
<span style="white-space:pre">	</span>	 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值