1:打印流(掌握)
(1)特点:
A:打印流可以输出任意类型数据。
B:如果启用了自动刷新,在调用println()方法的时候,可以自动刷新并换行。
C:可以直接操作文件。
哪些流对象可以直接操作文件呢?

看其构造方法,同时有File和String构造参数的。


字节打印流:PrintStream  1.0  (输出流)

System.out 是一个流对象

为其他的输出流添加了功能

单向流:

 

字符打印流: PrintWriter   1.1   (都是单向流)

 

package cn.itcast_01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/*
 * 需求:把当前项目路径下的PrintWriterDemo.java内容复制到项目路径下的Copy.java中。
 * 要求使用字符打印流输出数据,并使用打印流的自动刷新和换行特性。
 * 
 * 数据源:
 * 		PrintWriterDemo.java -- 字符输入流 -- Reader -- FileReader -- BufferedReader
 * 目的地:
 * 		Copy.java -- 字符输出流  -- Writer -- FileWriter -- BufferedWriter -- PrintWriter
 */
public class CopyFile {
	public static void main(String[] args) throws IOException {
		// 封装数据源
		BufferedReader br = new BufferedReader(new FileReader(
				"PrintWriterDemo.java"));
		// 封装目的地
		PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);

		String line = null;
		while ((line = br.readLine()) != null) {
			pw.println(line);
		}

		pw.close();
		br.close();
	}
}



注意:打印流仅仅提供了输出功能。没有对应的读取功能。

 

为什么要学习打印流?

打印流可以输出任意类型

如果启用了自动刷新,在调用println()方法时,后自动刷新。

可以直接对文件进行操作。

哪些流对象可以直接操作文件?

看其构造方法,是否同时能传递File和String类型的参数

 

Println()功能:在启用了自动刷新以后,不仅可以直接输入数据,还带有换行



(2)案例:

通过打印流改进文本文件的复制。


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);
		}


		pw.close();
		br.close();



2:可变参数(掌握)


(1)在定义功能的时候,可能不知道将来需要多少个参数,java就提供了一种可变参数的用法。


(2)格式:


修饰符 返回值类型 方法名(形式参数... 变量名) {




}




A:变量名本质是一个数组。


B:如果有多个参数,可变参数一定是最后一个。


package cn.itcast_02;


/*
 * JDK5的新特性:可变参数
 * 		修饰符 返回值类型 函数名(形式参数... 变量) {
 * 
 * 		}
 * 
 * 		注意:这里的变量其本质是该形式参数类型的一个数组。
 * 			这里会把调用这的数据自动封装成一个数组。
 * 			如果一个方法中有可变参数,并且有多个形式参数,可变参数在后面。
 */
public class ArgsDemo {
	public static void main(String[] args) {
		int a = 10;
		int b = 20;


		int result = sum(a, b);
		System.out.println(result);


		int c = 30;
		result = sum(a, b, c);
		System.out.println(result);


		int d = 40;
		result = sum(a, b, c, d);
		System.out.println(result);


		// 我现在要写一个功能,将来供别人使用。
		// 而别人没有告诉我要求多少个数据的和。
		// 他说可能在2-100个数据之间的数据和。
		// 怎么办?我们就想到了直接写两个数据和到100个数据的函数都提供了。
		// 这样工作量太大了。
		// 这个时候,针对这种形式参数个数不明确的现象,java就提供了一种特殊的形式参数类型:可变参数。
		int e = 50;
		result = sum(a, b, c, d, e);
		System.out.println(result);


		result = sum(a, b, c, d, e, 324, 64, 234, 754, 435);
		System.out.println(result);
	}


	// 看到这种用法,会自动把数据封装成一个数组
	public static int sum(int a, int... x) {
		// System.out.println(x); // [I@1db05b2
		// System.out.println("-------------------------");
		int sum = 0;
		for (int i : x) {
			sum += i;
		}
		return sum;
	}


	// public static int sum(int a, int b, int c, int d) {
	// return a + b + c + d;
	// }
	//
	// public static int sum(int a, int b, int c) {
	// return a + b + c;
	// // return sum(sum(a, b), c);
	// }
	//
	// public static int sum(int a, int b) {
	// return a + b;
	// }
}





(3)应用:


A:asList(...)


package cn.itcast_02;

import java.util.Arrays;
import java.util.List;

/*
 * public static <T> List<T> asList(T... a):把数组转成集合。
 * 注意:
 * 		A:这里的数组应该是引用类型。
 * 		B:转换后的集合的长度是固定的。不能做增删操作,但是可以做修改操作。
 */
public class ArrayToListDemo {
	public static void main(String[] args) {
		// Integer[] arr = { 1, 2, 3 };
		// List<Integer> list = Arrays.asList(arr);
		// List<Integer> list = Arrays.asList(1, 2, 3);
		// for (Integer i : list) {
		// System.out.println(i);
		// }

		List<String> list = Arrays.asList("hello", "world", "java");
		// UnsupportedOperationException
		// list.add("android");
		// list.remove(1);
		// list.set(1, "android");
		for (String str : list) {
			System.out.println(str);
		}
	}
}





B:sum(...)



package cn.itcast_02;

/*
 * public PrintWriter printf(String format,Object... args):把后面的数据按照前面的格式输出。
 * 格式怎么写,有没有什么规则?
 * 		%d
 */
public class PrintfDemo {
	public static void main(String[] args) {
		// System.out.printf("helloworld");

		// MissingFormatArgumentException
		// System.out.printf("%f", 100.123);
		// System.out.println();
		// System.out.printf("%.2f", 100.123);

		// 我要写一个表达式
		// 10+20=30
		// 30+40=70
		// System.out.println("10+20=30");
		int a = 30;
		int b = 40;
		int c = 70;
		System.out.printf("%d+%d=%d", a, b, c);
	}
}




3:Properties(理解)


(1)是Hashtable的子类。内置了IO流的操作。


(2)特有功能:


A:添加


Object setProperty(String key, String value) 


B:获取


String getProperty(String key)  


String getProperty(String key, String defaultValue)  


Set<String> stringPropertyNames() 


(3)和IO流结合的功能:


A:list 把集合中的数据写到文本文件。只能使用打印流。


B:load 把文本文件中的数据加载到集合。


C:store 把集合中的数据写到文本文件。


(4)案例:


查找user.properties这个文件中有没有姓名为lisi这个人,如果有,修改值为40。


package cn.itcast_03;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

/*
 * 需求:我现在有一个文本文件user.txt。里面有一些键值对数据,键是姓名,值是年龄。
 * 	         要求查找姓名为"lisi"的这个人是否存在,如果存在,就修改年龄为40
 *
 * 分析:
 * 		A:创建一个集合对象
 * 		B:把数据从文本文件中加载到集合中
 * 		C:遍历集合,判断数据,并修改集合数据
 * 		D:把集合中的数据重新存储到文件中
 */
public class PropertiesTest {
	public static void main(String[] args) throws IOException {
		// 创建一个集合对象
		Properties prop = new Properties();

		// 把数据从文本文件中加载到集合中
		FileReader fr = new FileReader("user.txt");
		prop.load(fr);
		fr.close();
		// System.out.println("prop:"+prop);

		// 遍历集合,判断数据,并修改集合数据
		Set<String> set = prop.stringPropertyNames();
		for (String key : set) {
			if ("lisi".equals(key)) {
				prop.setProperty(key, "40");
				break;
			}
		}
		// System.out.println("prop:"+prop);

		// 把集合中的数据重新存储到文件中
		FileWriter fw = new FileWriter("user.txt");
		prop.store(fw, null);
		fw.close();
	}
}



4:序列化流(理解)


(1)就是把对象按照流一样的操作。方便网络传输。


(2)序列化流和反序列化流


ObjectOutputStream


writeObject(Object obj)


ObjectInputStream


readObject()


(3)什么是序列化?如何实现序列化?什么是反序列化?

把对象像流一样的操作、让该对象的类实现序列化接口、把流数据解析成一个对象


(4)实现序列化接口的类是可以被序列化流操作的。



package cn.itcast_04;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/*
 * 序列化:把对象按照流一样的操作。
 * 如何实现序列化:让对象所属的类实现序列化接口。
 * 反序列化:把流数据还原成对象。
 * 
 * A:看到类实现序列化接口,你要知道:这个类的对象可以当作流一样的使用。
 * B:看到类实现序列化接口时,如果想解决黄色警告线,可以点击鼠标生成一个id值。
 *   并且,这样做以后,在类中做一些简单的改动,不会影响将来数据的读取。
 */
public class ObjectStreamDemo {
	public static void main(String[] args) throws IOException,
			ClassNotFoundException {
		//wirte();
		read();
	}

	private static void read() throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				"oo.txt"));
		Object obj = ois.readObject();
		ois.close();

		System.out.println(obj);
	}

	private static void wirte() throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				"oo.txt"));
		Person p = new Person("汪峰", 40);
		oos.writeObject(p);
		oos.close();
	}
}