JAVA--IO流(二)

1.LineNumberReader:
 * public int getLineNumber():获取行号
 * public void setLineNumber(int lineNumber):设置起始行号
   String readLine():读取一行
   案例:读取文件,每次读取一行打印并且加上行号
package com.edu_01;

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class LineNumberReaderDemo {
	public static void main(String[] args) throws IOException {
		//创建LineNumberReader对象
		//public LineNumberReader(Reader in)
		LineNumberReader lnr = new LineNumberReader(new FileReader("a.txt"));
		
		//默认起始行号从0开始
		//设置其实行号为从10开始
		lnr.setLineNumber(10);
		
		//一次读取一行
		String line;
		while ((line = lnr.readLine())!=null) {
			//打印每一行的行号和内容
			System.out.println(lnr.getLineNumber()+":"+line);
		}
		
		//关流
		lnr.close();
	}
}


2.操作基本数据类型的流

 * 可以操作基本类型的流对象。
 * DataInputStream:读数据
 * DataOutputStream:写数据
 * 
 案例:给流中写基本类型的数据,并且读取
 注意:
 * 读写顺序必须一致,否则数据有问题。

package com.edu_02;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		//写数据
		//write();
		read();
	}


	private static void read() throws IOException {
		//DataInputStream:读数据
		//创建对象:public DataInputStream(InputStream in)
		DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
		
		//读数据了,按什么顺序写入就必须按照什么顺序读出来
		System.out.println(dis.readByte());
		System.out.println(dis.readShort());
		System.out.println(dis.readInt());
		System.out.println(dis.readLong());
		System.out.println(dis.readChar());
		System.out.println(dis.readFloat());
		System.out.println(dis.readDouble());
		System.out.println(dis.readBoolean());
		
		//关流
		dis.close();
	}


	private static void write() throws IOException {
		//public DataOutputStream(OutputStream out)
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
		
		//给流关联的文件中写入基本类型的数据
		dos.writeByte(20);
		dos.writeShort(200);
		dos.writeInt(2000);
		dos.writeLong(20000L);
		
		dos.writeChar(97);
		dos.writeFloat(12.34F);
		dos.writeDouble(23.34);
		dos.writeBoolean(true);
		
		//关流
		dos.close();
	}


}


 
3.
 内存操作流:解决临时数据存储的问题。
 操作字节数组(演示着一个案例即可)
 ByteArrayInputStream
 ByteArrayOutputStream
 byte[] toByteArray() 将之前写入内存的流转换成字节数组
 
 操作字符数组
 CharArrayReader
 CharArrayWrite
 
 操作字符串
 StringReader
 StringWriter
 
 案例:演示
 操作字节数组
 ByteArrayInputStream
 ByteArrayOutputStream
 将数据写到流中保存在内存,并且读取
 package com.edu_03;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 *  操作字节数组(演示着一个案例即可)
	 ByteArrayInputStream
	 ByteArrayOutputStream
	 byte[] toByteArray() 将之前写入内存的流转换成字节数组
 *
 */
public class ByteArrayOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		//给内存中写数据public ByteArrayOutputStream()
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		//给内存中调用方法写数据
		baos.write("hello".getBytes());
		//将写入内存中的数据读取出来
		byte[] buf = baos.toByteArray();//调用这个方法,将之前写入内存中的数据存储到字节数组中
		ByteArrayInputStream bais = new ByteArrayInputStream(buf);//将刚才存储到字节数组中的内容关联上bais
		
		//只有这样之后,我们才可以直接从bais中读取我们想要的内容
		//一次读取一个字节
		int by;
		while ((by=bais.read())!=-1) {
			System.out.print((char)by);
		}
		//关流
		bais.close();
		baos.close();
	}


}


 
 4.
 * 打印流:
 * 字节打印流 PrintStream
 * 字符打印流 PrintWriter
 * 
 * 特点:
 * A:只能操作目的地,不能操作数据源
 * B:可以操作任意类型的数据
 * C:如果启动了自动刷新,能够自动刷新
 * D:可以操作文件的流
 * 注意:什么流可以直接操作文件?
看流对象的API,如果其构造方法同时有File和String类型的参数,就可以直接操作文件。

案例1:利用字符打印流给文件中书写数据(String类型),需要手动刷新
package com.edu_04;

import java.io.IOException;
import java.io.PrintWriter;

/**
 *  4.
 * 打印流:
 * 		字节打印流		PrintStream
 * 		字符打印流		PrintWriter
 * 
 * 特点:
 * 		A:只能操作目的地,不能操作数据源
 * 		B:可以操作任意类型的数据
 * 		C:如果启动了自动刷新,能够自动刷新
 * 		D:可以操作文件的流
 * 			注意:什么流可以直接操作文件?
			看流对象的API,如果其构造方法同时有File和String类型的参数,就可以直接操作文件。
 *
 */
public class PrintWriterDemo {
	public static void main(String[] args) throws IOException {
		//使用打印流给文件中写入hello,java,world
		//public PrintWriter(String fileName)
		PrintWriter pw = new PrintWriter("pw.txt");
		
		//给流关联的文件中写数据
		pw.write("hello");
		pw.write("java");
		pw.write("world");
		
		//刷新
		pw.flush();
		
		//3.关流
		pw.close();
		
	}

}


 * 操作任意类型的数据呢?
 * print()
 * println():如果启动了自动刷新,能够实现刷新,而且还实现了自动换行。
 * 如何启动自动刷新:利用构造
 * PrintWriter(OutputStream out, boolean autoFlush) 
 * PrintWriter(Writer out, boolean autoFlush) 
 * 
 * 如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作
案例2:利用字符流给文件中写数据(int类型,boolean类型),启动自动刷新

package com.edu_04;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterDemo2 {
	public static void main(String[] args) throws IOException {
		//创建字符打印流对象,并开启自动刷新
		//public PrintWriter(Writer out,boolean autoFlush)
		PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);
		
		//给流中写数据
		//pw.write("hello");
		//pw.write("java");
		
		//注意:如果已经开启了自动刷新功能,必须调用则 println、printf 或 format的时候,才可以实现自动刷新
		pw.println("hello");
		pw.println("java");
		pw.println("world");//调用println这个方法给文件中写数据,1.写数据  2.换行  3.刷新
		
		//可以操作任意类型的数据
		pw.println(true);
		pw.println(12.34);
		
		//关流
		pw.close();
		
	}

}


案例3:利用字符打印流复制java文件(BufferedReader+PrintWriter)
package com.edu_04;


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


public class PrintWriterDemo3 {
	public static void main(String[] args) throws IOException {
		//数据源
		BufferedReader br = new BufferedReader(new FileReader("PrintWriterDemo.java"));
		//目的地
		//PrintWriter(Writer out, boolean autoFlush) 
		PrintWriter pw = new PrintWriter(new FileWriter("copy.java"),true);
		
		//读一行写一行
		String line;
		while ((line=br.readLine())!=null) {
			pw.println(line);//1.写数据  2.换行  3.刷新
		}
		
		//关流
		pw.close();
		br.close();
		
	}


}







5.标准输入输出流
 * System类下有这样的两个成员变量:
 
 * 标准输入流:
 * public static final InputStream in
 

 案例1:利用标注输入流进行键盘录入,录入后读取流并打印在控制台

package com.edu_05;

import java.io.IOException;
import java.io.InputStream;

public class SystemIn {
	public static void main(String[] args) throws IOException {
		/**
		 * public static final InputStream in
		 */
		//将键盘录入的数据封装在了输入流中
		//Scanner sc = new Scanner(System.in);
		InputStream is = System.in;
		
		//将键盘录入的数据从输入流中读取出来
		int by;
		while ((by=is.read())!=-1) {
			System.out.print((char)by);
		}
		
		//关流
		is.close();
	}

}


 
 案例2:用IO流实现键盘录入,一次读取一行数据
分析:
  InputStream is = System.in;
BufferedReader是字符缓冲流,是对字符流进行高效操作的
所以,参数必须是字符类型
而我们现在有的是字节类型的流
请问:怎么办呢?转换流
 
 * 标准输出流:

 * public static final PrintStream out

package com.edu_05;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class SystemIn2 {
	public static void main(String[] args) throws IOException {
		/**
		 * 案例2:用IO流实现键盘录入,一次读取一行数据
		 * InputStream is = System.in;
		 * InputSreamReader isr = new InputStreamReader(is)
		 * BufferedReader br = new BufferedReader(isr); 
		 */
		//将上面的分析写为一部
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		//一次读取一行数据
		System.out.println("请输入你的姓名");
		String name = br.readLine();
		System.out.println("请输入你的年龄");
		String age = br.readLine();
		
		System.out.println(name+":"+age);
	}

}


 
 案例:解析输出语句System.out.println("helloworld");
   
   
package com.edu_05;

import java.io.PrintStream;

/**
 *  标准输出流:
 * 	public static final PrintStream out
 	案例:解析输出语句System.out.println("helloworld");
 *
 */
public class SystemOut {
	public static void main(String[] args) {
//		PrintStream ps = System.out;
//		ps.println(true);
		
		//上面两行合并为一行,底层调用的字节打印流中的方法
		System.out.println(true);
	}
}




6.
 * 合并流:SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。
    
   构造:
   SequenceInputStream(InputStream s1, InputStream s2) :将s1和s2合并成一个输入流,先读取s1后读取s2


 * 
 * 案例1:
 * 我要把DataStreamDemo.java和ByteArrayStreamDemo.java写到一个文件Copy.java
 * 
 * 数据源:
 * DataStreamDemo.java
 * ByteArrayStreamDemo.java
 * 目的地:
 * Copy.java
   
package com.edu_06;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;

public class SequenceInputStreamDemo {
	public static void main(String[] args) throws IOException {
		//创建合并流对象
		//SequenceInputStream(InputStream s1, InputStream s2) :将s1和s2合并成一个输入流,先读取s1后读取s2
		//将两个数据源合而为一
		SequenceInputStream sis = new SequenceInputStream(new FileInputStream("PrintWriterDemo.java"), new FileInputStream("SystemIn2.java"));
		//封装目的地
		FileOutputStream fos = new FileOutputStream("copy2.java");
		
		//一下读写一个字节数组
		byte[] buf = new byte[1024];
		int len;
		while ((len=sis.read(buf))!=-1) {
			//读多少写多少
			fos.write(buf, 0, len);
		}
		
		//关流
		fos.close();
		sis.close();
		
	}

}

8. 对象的序列化和反序列化
 * 序列化流:把对象按照流一样的方式写到文件或者在网络中传输。
 * 反序列化流:把文件或者网络中的流对象数据还原对象。
 * 
 * ObjectOutputStream:序列化流
   writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
   
 * ObjectInputStream:反序列化流
   Object readObject() 从 ObjectInputStream 读取对象。 
 * 
   注意:如果一个类不是实现Serializable接口无法把实例化,会报异常java.io.NotSerializableException
 * 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
 * 
 * 如何实现序列化?
 * 让对象所属类的实现序列化接口。   
   
package com.edu_07;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;


public class ObjectInputStreamDemo {
	public static void main(String[] args) throws Exception {
		//创建反序列化流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
		
		//读取文件中存储的对象,以实现反序列化
		//readObject()
		Object object = ois.readObject();
		System.out.println(object);
		
		//关流
		ois.close();
		
	}

}

package com.edu_07;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;


public class ObjectOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		//创建序列化流对象
		//public ObjectOutputStream(OutputStream out)
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
		
		//创建一个学生对象,将学生对象写入文件中
		Studnet s = new Studnet("刘德华", 50);
		oos.writeObject(s);
		// java.io.NotSerializableException
		//类通过实现 java.io.Serializable 接口以启用其序列化功能
		
		//关流
		oos.close();
		
	}

}

package com.edu_07;

import java.io.Serializable;

public class Studnet implements Serializable{
	//实现这个接口不需要实现任何方法,这个接口说白了就是仅仅给Student类,打上了一个可以被序列化的标示
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Studnet(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Studnet() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "Studnet [name=" + name + ", age=" + age + "]";
	}
	
	
	

}


9. Properties(查看api实现map接口本质是一个map集合)
 9.1
 * Properties:Properties 类表示了一个持久的属性集。属性列表中每个键及其对应值都是一个字符串。
 * 特点:Properties 可保存在流中或从流中加载。
   案例:使用map集合的put方法给集合中存储数据并且遍历
   
 
 9.2
 * Properties的特有功能:
 * A:添加元素
 * public Object setProperty(String key,String value)
 * B:获取元素
 * public String getProperty(String key)
 * public Set<String> stringPropertyNames()
 9.3
 * 可以和IO流进行结合使用:
 * 把文件中的数据加载到集合中。注意:文件中的数据必须是键值对象形式的(例如:张杰=谢娜)。
 * public void load(InputStream inStream)
 * public void load(Reader reader)

案例:创建一个键值对文件,将文件中的键值对加载到集合中,输出集合

package com.edu_08;

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

public class PropertiesDemo3 {
	public static void main(String[] args) throws IOException {
		//创建集合
		Properties prop = new Properties();
		
		//将文件中的键值对,加载到集合中
		prop.load(new FileReader("prop.txt"));
		
		//遍历集合
		Set<String> keys = prop.stringPropertyNames();
		for (String key : keys) {
			System.out.println(key+":"+prop.getProperty(key));
		}
		
	}

}


 * 把集合中的数据存储到文本文件中,并且是按照键值对形式存储的。
 * public void store(OutputStream out,String comments)
 * public void store(Writer writer,String comments)
案例:将创建的键值对集合加载到文件中
   
package com.edu_08;

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

public class PropertiesDemo4 {
	public static void main(String[] args) throws IOException {
		//创建集合
		Properties prop = new Properties();
		
		//给集合中存储数据
		prop.setProperty("liudehua", "50");
		prop.setProperty("liming", "60");
		prop.setProperty("zhangxueyou", "40");
		
		//将集合中的元素,存储到文本文件中
		prop.store(new FileWriter("prop2.txt"), "name=age");
		
	}

}


   
案例:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100” 
  
package com.edu_09;

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

public class PropTest {
	public static void main(String[] args) throws IOException {
		/**
		 * 案例:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
                                 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100” 
                                 
           zhangsan=3
           lisi=4
           wangwu=5
           1.创建集合对象
           2.将文件中的键值对加载到集合中
           3.获取多有的键的集合,遍历,判断
           4.如果存在lisi,的话,给集合中重新存储键值对lisi=100
           5.将集合中的数据存储到文件中
		 */
		//1.创建集合对象
		Properties prop = new Properties();
		
		// 2.将文件中的键值对加载到集合中
		prop.load(new FileReader("prop3.txt"));
		
		//3.获取多有的键的集合,遍历,判断
		Set<String> keys = prop.stringPropertyNames();
		
		// 4.如果存在lisi,的话,给集合中重新存储键值对lisi=100
		for (String key : keys) {
			if ("lisi".equals(key)) {
				prop.setProperty(key, "100");
			}
		}
		
		//5.将集合中的数据存储到文件中
		prop.store(new FileWriter("prop3.txt"), null);
		
	}

}


案例:我有一个猜数字小游戏的程序,请写一个程序实现在测试类中只能用5次,

      超过5次提示:游戏试玩已结束,请付费。

package com.edu_01;

import java.util.Scanner;

public class GuessNumber {
	public static void startGame(){
		int ran = (int) (Math.random()*100+1);
		Scanner sc = new Scanner(System.in);
		while (true) {
			System.out.println("请输入你猜测得数字");
			int number = sc.nextInt();
			if (number>ran) {
				System.out.println("大了");
			}else if (number<ran) {
				System.out.println("小了");
			}else if (number==ran) {
				System.out.println("猜对了");
				break;
			}
		}
	}
	

}

package com.edu_01;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropTest {
	public static void main(String[] args) throws IOException {
		//1.将文件中的键值对加载到集合中
		Properties prop = new Properties();
		prop.load(new FileReader("count.txt"));
		
		//2.拿出已经玩耍的次数做判断
		String count = prop.getProperty("count");
		//将String类型转换为int类型
		int number = Integer.parseInt(count);
		if (number>4) {
			System.out.println("次数已到,请付费");
		}else {
			//开启游戏
			GuessNumber.startGame();
			number++;
			//将自增的次数重新存储到文件中
			prop.setProperty("count", number+"");
			//将新的prop集合存储到文件中
			prop.store(new FileWriter("count.txt"), null);
		}
	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值