I/O流(二)

1. IO的含义是     InputStream  OutputStream   ,data source的含义是 数据源  。
      I------InputStream 输入流   O ------ OutputStream  输出流
      Data 数据  Source 资源   data source 数据源  IO流之输入流的源头

2. Java IO流可以分为         节点流      和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行。
      情况1:按照流向分类------输入输出
             输入流 InputStream  Reader 和输出流 OutputStream Writer
      情况2:按照内容分类-----字节和字符
             字节流  InputStream OutputStream
             字符流  Reader  Writer
      情况3:按照包含关系----节点和处理
             节点流(被包含): InputStream OutputStream  Reader  Writer
             处理流(包含) :InputStreamReader  OutputStreamWriter

3. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数据,   read()  方法给程序提供了一个从输入流中读取数据的基本方法。
   解析:此题考点------输入流读取的方法  read() 此方法发生了重载:
           Public abstract int read() throws IOException        此方法是抽象方法,含义:一个字节一个字节的读取
           Public  int read(byte[] b) throws IOException        含义:以byte[]数组为单位,进行读取
           Public  int read(byte[] b,int off,int len) throws IOException    含义:将输入流中最多 len 个数据字节读入 byte 数组

4. read方法从输入流中顺序读取源中的单个字节数据,该方法返回字节值(0-255之间的一个整数),如果到达源的末尾,该方法返回    -1      。

 Public abstract int read() throws IOException 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。

5. Java系统的标准输入对象是System.in,标准输出对象有两个,分别是标准输出System.out和 标准错误输出 System.err
      从System类的帮助文档解析可知:
  System.in   是InputStream类的实例/对象
  System.out  是PrintStream类的实例/对象
  System.err  是PrintStream 类的实例/对象

6. Java IO体系中, ObjectInputStream是字节输入流,不仅提供了存取所有Java基础类型数据(如:int,double 等)和String的方法,也提供了提供存取对象的方法。
    基础类型数据(如:int,double 等),会根据自动装箱的操作变成包装类,也是属于Object类的子类;String类等对象也是属于Object,所以从题的分析来看,不是InputStream而是ObjectInputStream.
     
7. Java IO体系中, DataOutputStream是字节输出流,提供了可以存取所有Java基础类型数据(如:int,double 等)和String的方法,但没有提供存取对象的方法。
8. 序列化是指将Java对象转换成字节序列,从而可以保存到磁盘上,也可以在网络上传输,使得不同的计算机可以共享对象。
      序列化的过程:指的是把非二进制数据转换成二进制数据的过程。  输入和输出流离不开序列化,JDK当中的类已经实现了 Serializable接口  如果自定义类想要进行输入和输出,此类必须实现Serializable接口。
9. transient的作用是 对某些成员变量不希望进行序列化
二、 选择题
1. File类中的(  B  )方法可以用来判断文件或目录是否存在。(选择一项)
A exist()
B. exists()
C. fileExist()
D. fileExists()
      判断一个文件或目录是否存在,返回值必须是boolean值,同时使用  exists()方法。
2. 在Java中,以下File类的方法中(  C  )用来判断是否是目录。(选择一项)
A isFile( )
B. getFile( )
C. isDirectory( )
D. getPath( )
3. 使用Java IO流实现对文本文件的读写过程中,需要处理下列(  B  )异常。(选择一项)
A ClassNotFoundException
B. IOException
C. SQLException
D. RemoteException
4. 在Java的IO操作中,(  BD  )方法可以用来刷新流的缓冲。(选择两项)
A void release()
B. void close()
C. void remove()
D. void flush()
      对于输出流,如果关闭流的方法和刷新方法的功能相同。
      选项A:未找到此方法,不存在。
      选项B:关闭流的方法,可以刷新缓冲区。
      选项C:未找到此方法,不存在。
     选项D:刷新缓冲区的方法。
5. 在Java中,下列关于读写文件的描述错误的是(  B  )。(选择一项)
A Reader类的read()方法用来从源中读取一个字符的数据
B. Reader类的read(int n )方法用来从源中读取一个字符的数据
C. Writer类的write(int n)方法用来向输出流写入单个字符
D. Writer类的write(String str)方法用来向输出流写入一个字符串
      选项A:表示正确  读取单个字符    public int read() throws  IOException
      选项B:Reader类不存在read(int n)方法,错误。
      选项C:表示正确  写入单个字符  public void write(int c) throws IOException
      选项D:表示正确 写入字符串   public void write(String str) throws IOException
6. 阅读下列文件定入的Java代码,共有(  C   )处错误。(选择一项)
import java.io.*;
public class TestIO {
public static void main(String []args){
String str ="文件写入练习";
FileWriter fw = null;        //1
try{
fw = new FileWriter("c:\mytext.txt");  //2
fw.writerToEnd(str);   //3
}catch(IOException e){   //4
e.printStackTrace();
}finally{
//此处省略关闭流
}
}
}

A 0
B. 1
C. 2
D. 3
      FileWriter fw = null; //声明FileWriter类   正确
      fw = new FileWriter("c:\mytext.txt");//实例化对象,\m属于转义
      字符了,此处显示错误,需要使用两个\而不是一个。
     fw.writerToEnd(str);//没有此方法,显示错误。
catch(IOException e);//捕捉异常---IOException,允许



7. 分析如下Java代码,有标注的四行代码中,有错误的是第(  D  )处。(选择一项)
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[ ] args) {
String str = "Hello World";
FileWriter fw = null;
try {
fw = new FileWriter("c:\\hello.txt"); // 1
fw.write(str);                     // 2
} catch (IOException e) {
e.printStackTrace();                // 3
} finally {
fw.close();                        // 4
}
}
}

A 1
B. 2
C. 3
D. 4
      发现此类没有任何自定义的方法,都是通过继承而来。
      此类的直接父类------OutputStreamWriter(转换流)-----直接父类—Writer,不管是继承那个父类的方法,close()方法都抛出了异常,所以在使用该方法时,必须对异常进行处理,而此题没有进行处理。

8. 以下选项中关于如下代码的说法正确的是( AD  )。(选择二项)
public class TestBuffered {
public static void main(String[] args) throws IOException {
BufferedReader br = 
new BufferedReader(new FileReader("d:/bjsxt1.txt"));
BufferedWriter bw = 
new BufferedWriter(new FileWriter("d:/bjsxt2.txt"));
String str = br.readLine();
while(str !=null){ 
bw.write(str); 
bw.newLine();
str = br.readLine();

br.close();
bw.close();
}
}
A. 该类使用字符流实现了文件复制,将d:/bjsxt1.txt复制为d:/bjsxt2.txt
B. FileReader和FileWriter是处理流,直接从文件读写数据
C. BufferedReader和BufferedWriter是节点流,提供缓冲区功能,提高读写效率
D. readLine()可以读取一行数据,返回值是字符串类型,简化了操作
      选项A:表示正确。
      选项B:FileReader和FileWriter是节点流类的子类,不属于处理流。
      选项C:BufferedReader BufferedWriter是处理流,不是节点流。
      选项D:表示正确。

9. InputStreamReader是转换流,可以将字节流转换成字符流,是字符流与字节流之间的桥梁。它的实现使用的设计模式是(  C  )。(选择一项)
A. 工厂模式
B. 装饰模式
C. 适配器模式
D. 代理模式
      选项A:工厂模式--工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
      选项B:装饰模式
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
      选项C:适配器模式
在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
      选项D:代理模式
组成:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

三、 判断题
1. 一个File对象可以代表一个文件或目录,它可以获取文件和目录属性,也可以访问文件内容。(  × )
            File类根据他的构造方法,可以代表某一个文件或目录,但是要获取文件或访问文件不是通过File,而是通过IO流完成。
2. 假设文件”a.txt”的长度为100字节,那么当正常运行语句”OutputStream f=new FileOutputStream(new File(“a.txt”));”之后,文件”a.txt”的长度变为0字节。( √ )
          public FileOutputStream(File file, boolean append)  throws FileNotFoundException
          创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。是没有第二个参数,默认的也是会把原先文件的内容清空,也就是重新  在文件的开始处进行输出内容,覆盖掉原先内容
。    
3. ByteArrayInutStream和ByteArrayOutputStream对内存中的字节数组进行读写操作,属于字节流,属于处理流而不是节点流。 (  ×  )
      此流属于字节流,因为他的直接父类是InputStream  OutputStream 通过构造方法可知,它没有无参构造方法,只有有参构造方法,但是构造方法中传入的是byte[]数组,而不是InputStream OutputStream类对象,所以它是 节点流,不是处理流。
4. 实现Serializable接口的可以被序列化和反序列化。该接口中没有定义抽象方法,也没有定义常量。(  T  )
对象所在的类只要实现了此接口,那么对象就有可序列化和反序列化的能力。此接口是一个标识接口,没有定义任何数据。
5. 序列化是指将字节序列转换成Java对象,只有实现了Serializable接口的类的对象才可以被序列化。( F  ) 
      序列化是把Java对象换成字节序列,反序列化是将字节序列转换成Java对象在网络传输中,其实传输的是字节,所以在JDK当中存在的类,基本上都实现了该接口;如果自定义类想要实现序列化,也要实现此接口。
6. 流对象使用完后,一般要调用close方法关闭,释放资源。 (  √  )
虽然在字节流当中,操作没有用到缓冲区,所以使用完流之后不写close方法也可以,但是为了规范,最好也要写上。字符流当中,必须使用close方法,否则内容无法输入输出。
四、 简答题
1. 输入流和输出流的联系和区别,字符流和字节流的联系和区别
答:
字符流和字节流是流的一种划分,按照处理流的数据单位进行的划分两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使用的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。这四个都是抽象类。
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。
字节流是最基本的,所有的InputStrem和OutputStream的子类都是字节流,主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的编码来处理,也就是要进行字符集的转化,这两个之间通过 InputStreamReader,OutputStreamWriter(转换流)来关联,实际上是通过byte[]和String来关联的。
流就像管道一样,在程序和文件之间,输入输出的方向是针对程序而言,向程序中读入东西,就是输入流,从程序中向外读东西,就是输出流。输入流是得到数据,输出流是输出数据。

2. 节点流和处理流的联系和区别。
答:节 点流和处理流是流的另一种划分,按照功能不同进行的划分。
节点流,可以从或向一个特定的地方(节点)读写数据。
处理流,对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

3. 列举常用的字节输入流和字节输出流并说明其特点,至少5对。
答:
FileInputStream  FileOutputStream  --------  与文件相关的流
DataInputStream DataOutputStream  --------  与数据相关的流
BufferedInputStream BufferedOutputStream  ------ 带缓冲区的流
ByteInputStream ByteOutputStream         ------ 字节输入输出流
StringBufferInputStream StringBufferOutputStream -----带字符串缓冲区的流
ObjectInputStream  ObjectOutputStream    ------ 对象输入输出流

4. 说明缓冲流的优点和原理。
答: 缓冲流是处理流,它不直接连接数据源/目的地,而是以一个节点流为参数,在节点流的基础上,提供一些简单操作。
先说不带缓冲的流的工作原理吧:它读取到一个字节/字符,就向用户指定的路径写出去,读一个写一个,所以就慢了。带缓冲的流的工作原理:读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写出去,从而提高了工作效率
优点:减少对硬盘的读取次数,降低对硬盘的损耗。

5. 解释下面代码的含义:
File f = new File("d:/a.txt");
FileInputStream fis = new FileInputStream(f);
int m = 0;
while((m=fis.read())!=-1){
char c = (char) m;
System.out.print(c);
}
答: 第一步 实例化File类对象,目的:通过File类构造方法,确定数据源。
     第二步 实例化FileInputStream类对象,传入File类对象
     第三步 定义一个int类型的变量,初始化值是0 目的:后面用于判断
     第四步 定义while循环
              循环条件: 只要读取的文件返回int值不是-1,说明还有内容可读, 反之,内容读取完毕,结束循环。
              循环体: 把读取的int值,通过强制转换,转换成字符并输出。

6. 序列化的定义、实现和注意事项。反序列化指的是什么?
答:(1) 序列化:
        将对象以byte流的形式写入到文件中->序列化;
        将要被序列化的对象的类要实现Serializable接口:
Public  class  User  implements  Serializable {
        
}
User实现了这个接口,代表User这个类的对象具有了将对象以byte流的形式写进文件的功能。
(2) 反序列化:
将文件中的数据以byte流的形式读到程序中来,依然是一个对象反序列化。

7. PrintStream打印流经常用于什么情况? System.out 是不是打印流?
答: PrintStream:字节打印流,是OutputStream的实现类。提供了多个重载的print,println等方法,可以方便地向文本文件中写入数据。
System.out是字节打印流(PrintStream的对象),它被称作标准的输出流,输出的目的地是标准的输出设备,即显示器。所以,当我们使用System.out.print()或System.out.println()时会向屏幕(显示器)输出数据

8. word文档能使用字符流操作吗?为什么?
答: 能,但是不建议。因为word文档不是纯文本文件,除了文字还包含很多格式信息。不能用字符流操作,可以用字节流操作
五、 编码题
1. 分别使用文件流和缓冲流复制一个长度大于100MB的视频文件,并观察效率的差异。
public class TestCopy4 {
	public static void main(String[] args) throws IOException {
		//创建输入流和输出流
		InputStream fis = new FileInputStream(new File("d:/1.mp4"));
		OutputStream fos = new FileOutputStream("d:/2.mp4");
		//使用输入流和输出流复制文件
		byte [] buf = new byte[10];
		int len = fis.read(buf);
		while(len!=-1){
			//写
			fos.write(buf, 0, len);
			//读
			len = fis.read(buf);
			//System.out.println(len);
		}		
		//关闭输入流和输出流
		fis.close();
		fos.close();
	}
}
public class TestCopy {
	public static void main(String[] args) throws IOException {
		//创建输入流和输出流
		InputStream fis = new FileInputStream(new File("d:/1.mp4"));
		OutputStream fos = new FileOutputStream("d:/2.mp4");
		BufferedInputStream bis = new BufferedInputStream(fis);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		//使用输入流和输出流复制文件
		byte [] buf = new byte[10];
		int len = bis.read(buf);
		while(len!=-1){
			//写
			bos.write(buf, 0, len);
			//读
			len = bis.read(buf);
		}		
		//关闭输入流和输出流
		bis.close();
		bos.close();
	}
}
2. 实现字符串和字节数组之间的相互转换。必如将字符串“北京尚学堂bjsxt”转换为字节数组,并将字节数组再转换回字符串。
A public class TestConvert {
	public static void main(String[] args) throws IOException {
		//准备一个字符串
	String contents=" 近日,北京尚学堂科技有限公司正式成为央视网广告合作伙伴";
		System.out.println(contents);
		//String---byte [] 
		byte [] buf = contents.getBytes();	
		//byte[]----String
		String contents2 = new String(buf, 0, buf.length);
		System.out.println(contents2);		
	
	}
}
3. 实现字节数组和任何基本类型和引用类型执行的相互转换
提示:使用ByteArrayInutStream和ByteArrayOutputStream。
public class TestByteArrayStream {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		int num = 50;
		boolean flag = true;
		User user = new User("bjsxt","bjsxt");
		//使用数据包把数据封装起来
		//各种数据类型----->byte[]  ByteArrayOutputStream		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);//包装流
		oos.writeInt(num);
		oos.writeBoolean(flag);
		oos.writeObject(user);		
		byte [] buf = baos.toByteArray();		
		baos.close();
		//byte[]----------->各种数据类型
		ByteArrayInputStream bais = new ByteArrayInputStream(buf);
		ObjectInputStream ois = new ObjectInputStream(bais);
		int num2 = ois.readInt();
		boolean flag2 = ois.readBoolean();
		User user2 = (User)ois.readObject();
		System.out.println(num2);
		System.out.println(flag2);
		System.out.println(user2);
		bais.close();


	}
}
4. 复制文件夹d:/sxtjava下面所有文件和子文件夹内容到d:/sxtjava2。
提示:涉及单个文件复制、目录的创建、递归的使用
public class CopyDir {
	/**
	 * 复制单个文件
	 * @param sourceFile 源文件
	 * @param targetFile 目标文件
	 * @throws IOException
	 */
    public static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            // 新建文件输入流
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
            // 新建文件输出流
           outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            // 缓冲数组
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            // 刷新此缓冲的输出流
            outBuff.flush();
        } finally {
            // 关闭流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }
    
    /**
     * 复制目录
     * @param sourceDir 源目录
     * @param targetDir 目标目录
     * @throws IOException
     */
public static void copyDirectiory(String sourceDir, String targetDir) 
throws IOException {
        // 检查源目录
    	File fSourceDir = new File(sourceDir);
    	if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
    		System.out.println("源目录不存在");
    		return;
    	}    	
    	//检查目标目录,如不存在则创建
    	File fTargetDir = new File(targetDir);
    	if(!fTargetDir.exists()){
    		fTargetDir.mkdirs();
    	}    		
        // 遍历源目录下的文件或目录
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new File(fTargetDir, file[i].getName());
                copyFile(sourceFile, targetFile);
            }            
            //递归复制子目录
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String subSourceDir = sourceDir + File.separator + file[i].getName();
                // 准备复制的目标文件夹
                String subTargetDir = targetDir + File.separator + file[i].getName();
                // 复制子目录
                copyDirectiory(subSourceDir, subTargetDir);
            }
        }
    }
    public static void main(String[] args) throws IOException {
    	copyDirectiory("d:/sxtjava","d:/sxtjava2");
	}
}

六、 可选题
1. 使用IO包中的类读取D盘上exam.txt文本文件的内容,每次读取一行内容,将每行作为一个输入放入ArrayList的泛型集合中并将集合中的内容使用加强for进行输出显示。
public class Test {
	public static void main(String[] args) throws IOException {
		String path="D:\\exam.txt";
		outputMethod(path);
	}
	public static void outputMethod(String path) throws IOException {
		List list = new ArrayList(); // 创建集合对象
		// 创建缓冲区对象
                BufferedReader br = new BufferedReader(new FileReader(path));	
	        String line = br.readLine(); // 读取数据每次读一行
		while (line != null) {
			list.add(line);
			line = br.readLine();
		}
		br.close();              //关闭
		for(String s:list){
			System.out.println(s);
		}
	}
}
2. 假设从入学开始所有书写的Java类代码都在d:/sxtjava文件夹下,包括多级子文件夹。使用IO流获取从入学开始,到目前为止已经写了多少行Java代码。
提示:其实就是获取d:/sxtjava文件夹及其子文件夹下的所有.java文件,使用readLine()读取其中每一行,每读取一行,行数加1。所有的文件读取完毕,得到总共已经写的Java代码行数。需要结合递归实现
 public class TestCountDir {
	private int count;
	/**
	 * 统计一个java文件的行数
	 */
    private void countLine(File sourceFile) throws IOException {
        BufferedReader br = null;       
        try {
            // 新建文件输入流
            br = new BufferedReader(new FileReader(sourceFile));
           while(br.readLine()!=null){
        	   count++;
        	   //System.out.println(count);
           }
        } finally {          
             br.close();          
        }
    }
    /**
     * 统计一个目录下所有Java文件的行数
     */
    private void countDir(String sourceDir) throws IOException {
        // 检查源目录
    	File fSourceDir = new File(sourceDir);
    	if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
    		System.out.println("源目录不存在");
    		return;
    	}      		
        // 遍历目录下的文件或目录
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
               if(file[i].getName().toLowerCase().endsWith(".java")){
            	  // System.out.println(file[i].getName());
            	   countLine(file[i]);
               }
            }            
            //递归统计代码行数
            if (file[i].isDirectory()) {
                // 准备统计的文件夹
                String subSourceDir = sourceDir + File.separator + file[i].getName();
                // 统计子目录
                countDir(subSourceDir);
            }
        }
    }
    public static void main(String[] args) throws IOException {
    	
    	TestCountDir tcd = new TestCountDir();
    	tcd.countDir("d:/sxtjava");
    	System.out.println(tcd.count);
	}
}
3. 由控制台按照固定格式输入学生信息,包括学号,姓名,年龄信息,当输入的内容为exit退出;将输入的学生信息分别封装到一个Student对象中,再将每个Student对象加入到一个集合中,要求集合中的元素按照年龄大小正序排序;最后遍历集合,将集合中学生信息写入到记事本,每个学生数据占单独一行。
 public class Student implements Comparable{
	private Integer num;
	private String name;
	private Integer age;
	//省略getter和setter方法
	//省略构造方法
	public int compareTo(Student stu) {
		return this.age-stu.age;
	}
	public String toString() {
		return "Student [age=" + age + ", name=" + name + ", num=" + num + "]";
	}
}
public class Test {
	public static void main(String[] args) {
		Set stuSet = saveStudentInfo();
		outputInfo(stuSet);
	}
	private static Set saveStudentInfo() {
		Scanner input = new Scanner(System.in);
		// 保存学生信息的TreeSet集合对象
		Set stuSet = new TreeSet();
		while (true) {
			// 输入提示
			System.out.println("请输入学生信息:(学号#姓名#年龄)");
			String inputData = input.nextLine();
			// 判断是否退出 inputData.equals("exit")
			if ("exit".equals(inputData)) {
				break;
			}
			// 将用户输入的学生信息分割为String[]
			String[] info = inputData.split("#");
			// 将输入信息封装到Student对象中
			Student stu = new Student(Integer.parseInt(info[0]), info[1],
					Integer.parseInt(info[2]));
			// 将学生对象加入集合
			stuSet.add(stu);
		}
		return stuSet;
	}
	private static void outputInfo(Set stuSet) {
		File file = new File("e:/student.txt");
		// 创建文件输出流对象
		FileWriter fw = null;
		try {
			fw = new FileWriter(file);
			Iterator it = stuSet.iterator();
			while (it.hasNext()) {
				String info = it.next().toString();
				// 将info字符串,写入记事本
				fw.write(info);
				// 完成换行功能
				fw.write("\r\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}





你可能感兴趣的:(I/O流(二))