IO流

Posted 旺仔成长记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO流相关的知识,希望对你有一定的参考价值。

登录注册IO版本案例(掌握) 

	
	要求,对着写一遍。
	
	cn.itcast.pojo User
	cn.itcast.dao UserDao
	cn.itcast.dao.impl UserDaoImpl(实现我不管)
	cn.itcast.game GuessNumber
	cn.itcast.test	UserTest

数据操作流(操作基本类型数据的流)(理解) 

	
	1、可以操作基本类型的数据
	2、流对象名称	
		DataInputStream
			A:创建数据输出流对象
				DataOutputStream dos = new DataOutputStream(new FileOutputStream(
				"dos.txt"));
			B:写数据
				dos.writeByte(10);
				dos.writeShort(100);
				dos.writeInt(1000);
				dos.writeLong(10000);
				dos.writeFloat(12.34F);
				dos.writeDouble(12.56);
				dos.writeChar(‘a‘);
				dos.writeBoolean(true);
			C:释放资源
				dos.close();
		DataOutputStream
			A:创建数据输入流对象
				DataInputStream dis = new DataInputStream(
				new FileInputStream("dos.txt"));
			B:读数据
				byte b = dis.readByte();
				short s = dis.readShort();
				int i = dis.readInt();
				long l = dis.readLong();
				float f = dis.readFloat();
				double d = dis.readDouble();
				char c = dis.readChar();
				boolean bb = dis.readBoolean();
			C:释放资源
				dis.close();

内存操作流(理解) 

	
	1、有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
	2、三种
		A:操作字节数组
			ByteArrayInputStream
					//将写入的流转化为字符数组
					byte[] bys = baos.toByteArray();
					//创建对象
					ByteArrayInputStream bais = new ByteArrayInputStream(bys);
					//读数据
					int by = 0;
					while ((by = bais.read()) != -1) {
						System.out.print((char) by);
					}
			ByteArrayOutputStream
					// 创建对象
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					// 写数据
					for (int x = 0; x < 10; x++) {
						baos.write(("hello" + x).getBytes());
					}
					// 释放资源
					// 通过查看源码我们知道这里什么都没做,所以根本需要close()
					// baos.close();
		B:操作字符数组
			CharArrayReader
			CharArrayWriter
		C:操作字符串
			StringReader
			StringWriter

打印流(掌握) 

	
	1、字节打印流 PrintStream,字符打印流 PrintWriter
	2、特点:
		A:只操作目的地,不操作数据源(只能写不能读)
		B:可以操作任意类型的数据
		C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
		D:可以直接操作文件
			问题:哪些流可以直接操作文件呢?
						FileInputStream
						FileOutputStream
						FileReader
						FileWriter
						PrintStream
						PrintWriter
			流分为基本流(能直接读写文件)和高级流(在基本流基础上提供一些其它功能)
			看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
	3、复制文本文件
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);	//第二参数启动刷新
		
		String line = null;
		while((line=br.readLine())!=null) {
			pw.println(line);	//println自动刷新功能
		}
		
		pw.close();
		br.close();

标准输入输出流(理解) 

	
	1、System类下面有这样的两个字段
		in 标准输入流
		out 标准输出流
	2、三种键盘录入方式
		A:main方法的args接收参数
		B:System.in通过BufferedReader进行包装
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		C:Scanner
			Scanner sc = new Scanner(System.in);
	3、输出语句的原理和如何使用字符流输出数据
		A:原理
			System.out.println("helloworld");
			
			PrintStream ps = System.out;
			ps.println("helloworld");
		B:把System.out用字符缓冲流包装一下使用
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

随机访问流(理解) 

	
	RandomAccessFile类不属于流,是Object类的子类。
	但它融合了InputStream和OutputStream的功能。
	支持对文件的随机访问读取和写入。
	1、可以按照文件指针的位置写数据和读数据。
	2、案例:
		
		A:创建随机访问流对象
				RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");	//第一个参数是文件路径,第二个参数是操作文件的模式。
				//模式有四种,我们最常用的一种叫"rw",这种方式表示我既可以写数据,也可以读取数据 
		B:写数据
				raf.writeChar(‘a‘);
		C:读数据
				char ch = raf.readChar();
		D:获取和改变文件指针的位置
				raf.getFilePointer();
		E:设置指针位置
				raf.seek(4);

合并流(理解) 

	
	1、把多个输入流的数据写到一个输出流中。
	2、构造方法:
		A:SequenceInputStream(InputStream s1, InputStream s2) 
		B:SequenceInputStream(Enumeration<? extends InputStream> e) 
	3、例子:
		public class SequenceInputStreamDemo2 {
			public static void main(String[] args) throws IOException {
				// 需求:把下面的三个文件的内容复制到Copy.java中
				// ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java

				// SequenceInputStream(Enumeration e)
				// 通过简单的回顾我们知道了Enumeration是Vector中的一个方法的返回值类型。
				// Enumeration elements()
				Vector v = new Vector();
				InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
				InputStream s2 = new FileInputStream("CopyFileDemo.java");
				InputStream s3 = new FileInputStream("DataStreamDemo.java");
				v.add(s1);
				v.add(s2);
				v.add(s3);
				Enumeration en = v.elements();
				SequenceInputStream sis = new SequenceInputStream(en);
				BufferedOutputStream bos = new BufferedOutputStream(
						new FileOutputStream("Copy.java"));

				// 如何写读写呢,其实很简单,你就按照以前怎么读写,现在还是怎么读写
				byte[] bys = new byte[1024];
				int len = 0;
				while ((len = sis.read(bys)) != -1) {
					bos.write(bys, 0, len);
				}

				bos.close();
				sis.close();
			}
		}

序列化流(理解) 

	
	1、可以把对象写入文本文件或者在网络中传输。对象 -- 流数据(ObjectOutputStream)
	2、如何实现序列化呢(NotSerializableException:未序列化异常)?
		implements Serializable	让被序列化的对象所属类实现序列化接口。
		该接口是一个标记接口。没有功能需要实现。
	3、注意问题(InvalidClassException):
		把数据写到文件后,在去修改类,不写再读,会产生一个问题。
		如何解决该问题呢?
			实际开发中,需要修改类但还需要使用以前写过的数据,不能重新写入。怎么办呢?
			在类文件中,给出一个固定的序列化id值。
			点击黄色警告线 Add generated serial version ID, 这样也可以解决黄色警告线问题
		我一个类中可能有很多的成员变量,有些我不想进行序列化。请问该怎么办呢?
			使用transient关键字声明不需要序列化的成员变量(private transient int age;)
	4、面试题:
		什么时候序列化?
		如何实现序列化?
		什么是反序列化?
			反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 -- 对象(ObjectInputStream)

Properties(理解) 

	
        1、 属性集合类。是一个可以和IO流相结合使用的集合类。
		可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
		是Hashtable的子类,说明是一个Map集合。
			Properties prop = new Properties();

			// 添加元素
			prop.put("it002", "hello");
			prop.put("it001", "world");
			prop.put("it003", "java");

			// System.out.println("prop:" + prop);

			// 遍历集合
	2、特有功能
		A:public Object setProperty(String key,String value);	//添加元素
		B:public String getProperty(String key);	//获取元素
		C:public Set stringPropertyNames();	//获取所有键的集合
		D:例子
			public class PropertiesDemo2 {
			public static void main(String[] args) {
				// 创建集合对象
				Properties prop = new Properties();

				// 添加元素
				prop.setProperty("张三", "30");
				prop.setProperty("李四", "40");
				prop.setProperty("王五", "50");

				// public Set stringPropertyNames():获取所有的键的集合
				Set set = prop.stringPropertyNames();
				for (String key : set) {
					String value = prop.getProperty(key);
					System.out.println(key + "---" + value);
				}
			}
			}
	3、和IO流结合的方法
		把键值对形式的文本文件内容加载到集合中
		public void load(Reader reader)
		public void load(InputStream inStream)

		把集合中的数据存储到文本文件中
		public void store(Writer writer,String comments)
		public void store(OutputStream out,String comments)
		注意:这里的集合指的是properties集合
		例子:
			public class PropertiesDemo3 {
			public static void main(String[] args) throws IOException {
				// myLoad();

				myStore();
			}

			private static void myStore() throws IOException {
				// 创建集合对象
				Properties prop = new Properties();

				prop.setProperty("林青霞", "27");
				prop.setProperty("武鑫", "30");
				prop.setProperty("刘晓曲", "18");
				
				//public void store(Writer writer,String comments):把集合中的数据存储到文件
				Writer w = new FileWriter("name.txt");
				prop.store(w, "helloworld");
				w.close();
			}

			private static void myLoad() throws IOException {
				Properties prop = new Properties();

				// public void load(Reader reader):把文件中的数据读取到集合中
				// 注意:这个文件的数据必须是键值对形式
				Reader r = new FileReader("prop.txt");
				prop.load(r);
				r.close();

				System.out.println("prop:" + prop);
			}
			}
	4、案例:
		A:根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100
		B:写一个程序实现控制猜数字小游戏程序不能玩超过5次

NIO(了解) 

	
	1、JDK4出现的NIO,对以前的IO操作进行了优化,提高了效率。但是大部分我们看到的还是以前的IO。
	2、JDK7的NIO的使用	
		Path:路径
		Paths:通过静态方法返回一个路径
			public static Path get(URI uri)
		Files:提供了常见的功能
			复制文件:
				public static long copy(Path source,OutputStream out)
			把集合中的数据写到文本文件:
				public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)
	3、例子:
		public class NIODemo {
			public static void main(String[] args) throws IOException {
				// public static long copy(Path source,OutputStream out)
				// Files.copy(Paths.get("ByteArrayStreamDemo.java"), new
				// FileOutputStream(
				// "Copy.java"));

				ArrayList array = new ArrayList();
				array.add("hello");
				array.add("world");
				array.add("java");
				Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
			}
		}

以上是关于IO流的主要内容,如果未能解决你的问题,请参考以下文章

在 .net 中处理 pcm wav 流

此应用小部件片段中所有意图 (PendingIntents) 的逻辑流

JavaSE 一些技巧 04——IO流各种流常用代码整理

猜数小游戏升级版(IO流实现,对IO流进行加强理解运用)

利用IO(文件字符流)打印代码本身

JAVA IO流相关代码(Serializable接口,管道流PipedInputStream类,RandomAccessFile类相关代码)