计算机存储中文:
当前平台默认编码集:GBK 一个中文两个字节;表示形式:第一个字节:一定是负数;
第二个字节:一般是负数,可能也会是正数,不会影响的结果;
举例:
public class StringDemo {
public static void main(String[] args) {
//定义一个字符串
String str = "我爱你中国" ;
//转成字节数组
byte[] bys = str.getBytes() ;
//System.out.println(bys);
//System.out.println(Arrays.toString(bys));
System.out.println(Arrays.toString(bys)) ;
//[-50, -46, -80, -82, -60, -29, -42, -48, -71, -6] 表示"我爱你中国"
}
}
字节缓冲输出流:
构造方法:public BufferedOutputStream(OutputStream out):采用的默认的缓冲区大小(足够大了),来构造一个字节缓冲输出流对象;
public BufferedOutputStream(OutputStream out,int size):指定size缓冲区大小构造缓冲输出流对象;
注意:如果使用这个构造方法 int size 小于0,那么会报出一个异常:IllegalArgumentException
方法:
void flush():刷新缓冲区的流;
面试题:字节缓冲输出流它的构造方法为什么不能直接传递路径/文件?
原因:缓冲输入流/缓冲输出流,它只是在底层内部提供一个缓冲区的数组,底层实现文件的复制/读取/写入这些操作都依赖于基本流对象来操作(InputStream/OutputStream/FileInputStream/FileOutputstream);
举例:
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws Exception {
//符合Java一种设计模式:装饰者设计模式(过滤器:Filter)
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt")) ;
//写数据
bos.write("hello".getBytes());
//释放资源
bos.close();
}
}
字节缓冲输入流:
常用方法:public BufferedInputStream(InputStream in):默认缓冲区大小构造缓冲输入流对象;
public BufferedInputStream(InputStream in,int size):指定缓冲区大小构造缓冲输入流对象;
public int read():读取;
public int read(byte[] b,int off,int len):读取;
读取的方式有两种:
一次读取一个字节,一次读取一个字节数组;
举例:
public class BufferedInputStreamDemo {
public static void main(String[] args) throws Exception {
//构造一个字节缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bos.txt"));
//读数据
//一次读取一个字节
/*
int by = 0 ;
while((by=bis.read())!=-1) {
System.out.print((char)by);
}
*/
System.out.println("-------------------------------");
//一次读取一个字节数组
byte[] bys = new byte[1024] ;
int len = 0 ;
while((len=bis.read(bys))!=-1) {
System.out.println(new String(bys, 0, len));
}
//释放资源
bis.close();
}
}
例题:
操作一个视频文件,来测试速度问题;package org.westos_02;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
*
* 存储文件
* IO流:永久存储(耗时)
* 数据库:永久存储
*
* 基本的字节流
* 文件字节输入流/文件字节输出流
* 高效的字节流(缓冲流)
*
* 操作一个视频文件,来测试速度问题
* 基本的字节流一次读取一个字节 :耗时:85772毫秒
* 基本的字节流一次读取一个字节数组 :共耗时:216毫秒
*
* 高效的字节流一次读取一个字节 :共耗时:682毫秒
* 高效的字节流一次读取一个字节数组 :共耗时:49毫秒
*
* @author Administrator
*
*
*StringBuffer:提供了一个字符串缓冲区 (可以在缓冲区中不断追加字符串)
*/
public class Test {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis() ;
// method1("e:\\abc.mp4","copy1.mp4") ;
// method2("e:\\abc.mp4","copy2.mp4") ;
// method3("e:\\abc.mp4","copy3.mp4") ;
method4("e:\\abc.mp4","copy4.mp4") ;
long end = System.currentTimeMillis() ;
System.out.println("共耗时:"+(end-start)+"毫秒");
}
//高效的流一次读取一个字节数组
private static void method4(String src, String dest) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src)) ;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest)) ;
//一次读取一个字节数组
byte[] bys = new byte[1024] ;
int len = 0 ;
while((len=bis.read(bys))!=-1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
}
//高效的字节流一次读取一个字节
private static void method3(String src, String dest) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src)) ;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest)) ;
//一次读个字节
int by = 0 ;
while((by=bis.read())!=-1) {
bos.write(by);
}
//释放资源
bis.close();
bos.close();
}
//基本的字节流一次读取一个字节数组
private static void method2(String src, String dest) throws Exception {
//封装文件
FileInputStream fis = new FileInputStream(src) ;
FileOutputStream fos = new FileOutputStream(dest) ;
//读写操作
byte[] bys = new byte[1024] ;//相当于一个缓冲区
int len = 0 ;
while((len=fis.read(bys))!=-1) {
fos.write(bys, 0, len);
}
//释放资源
fis.close();
fos.close();
}
//基本的字节流一次读取一个字节
private static void method1(String src, String dest) throws Exception {
//封装源文件和目标文件
FileInputStream fis = new FileInputStream(src) ;
FileOutputStream fos = new FileOutputStream(dest) ;
//读写操作
int by = 0 ;
while((by=fis.read())!=-1) {
//写
fos.write(by);
}
//释放资源
fis.close();
fos.close();
}
}
编码与解码:
注意:编码前后的格式要一致;
编码:将字符串变成一个字节数组;
public byte[] getBytes():平台默认编码集(默认的是Gbk);
public byte[] getBytes(Charset charset):指定编码格式;
解码:将字节数组还原成字符串;
public String(byte[] bytes):使用平台默认编码集(gbk);
public String(byte[] bytes,Charset charset):用指定的编码格式来解码;
举例:
public class StringDemo {
public static void main(String[] args) throws Exception {
//定义一个字符串
String str ="你好" ;
//编码和解码:前后必须一致
//编码
//byte[] bys = str.getBytes() ;
byte[] bys = str.getBytes("utf-8") ;//utf-8编码一个汉字三个字节:[-28, -67, -96, -27, -91, -67]
System.out.println(Arrays.toString(bys));//gbk编码一个汉字两个字节:[-60, -29, -70, -61]
System.out.println("------------------");
//解码
//public String(byte[] bytes) :使用平台默认编码集(gbk)
//String s = new String(bys) ;
//String s = new String(bys,"gbk") ;//一个中文对应二个字节
String s = new String(bys,"utf-8") ;//一个中文对应三个字节
System.out.println(s);
}
}
字符转换输入流:InputStreamReader
构造方法:InputStreamReader(InputStream in):构造一个字符转换输入流,默认编码;
public InputStreamReader(InputStream in,Charset cs):构造一个字符转换输入流,指定编码;
举例:
public class ReaderDemo {
public static void main(String[] args) throws Exception{
//需求:要读取当前项目下的osw.txt,将内容输出在控制台上
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"),"gbk") ;
//读数据
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=isr.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
//关闭资源
isr.close();
}
}
字符转换输出流:OutputStreamWriter
构造方法:public OutputStreamWriter(OutputStream out):使用默认的编码格式构造一个字符转换输出流对象;
public OutputStreamWriter(OutputStream out, Charset cs):使用指定编码格式构造一个字符转换输出流对象;
举例:
public class WriterDemo {
public static void main(String[] args) throws Exception {
//创建一个字符输出流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "gbk");
//写数据
osw.write("中国");
//释放资源
osw.close();
}
}
练习:
package org.westos_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 需求:将a.txt文件中的内容进行复制,复制到当前项目下(b.txt)
*
* 文本文件:优先采用字符流
*
* 源文件:a.txt---->Reader---->InputStreamReader---->FileReader
* 目的的文件:b.txt--->Writer-->OutputStreamWriter---->FileWriter
*/
public class CopyDemo {
public static void main(String[] args) throws Exception {
//方式1:转换流的方式
//封装源文件和目的地文件
/*InputStreamReader isr = new InputStreamReader(
new FileInputStream("a.txt")) ;
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("b.txt")) ;
//复制操作
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=isr.read(chs))!=-1) {
//写
osw.write(chs, 0, len);
}
//释放资源
osw.close();
isr.close();
System.out.println("-----------------------");*/
//方式2:使用便捷类进行操作
FileReader fr = new FileReader("a.txt") ;
FileWriter fw = new FileWriter("b.txt") ;
//一次读取一个字符数组
//一次读取一个字符数组
char[] chs2 = new char[1024] ;
int len2 = 0 ;
while((len2=fr.read(chs2))!=-1) {
//写
fw.write(chs2, 0, len2);
}
fr.close();
fw.close();
}
}
字符输入流读数据的方法:
int read(char[] chs):读取一个字符数组;
int read():读取单个字符 ;
举例:
public class ReaderDemo {
public static void main(String[] args) throws Exception {
//读取当前项目下的StringDemo.java文件
FileReader fr = new FileReader("StringDemo.java") ;
//一次读取一个字符
/*
int ch = 0 ;
while((ch=fr.read())!=-1) {
System.out.print((char)ch);
}
*/
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=fr.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
//释放资源
fr.close();
}
}
字符输出流写数据的功能:
public void write(int c)):写字符数组;
public abstract void write(char[] cbuf, int off, int len):写字符数组的一部分;
public void write(String str):写字符串;
public void write(String str,int off, int len):x写字符串的某一部分;
举例:
public class WriterDemo {
public static void main(String[] args) throws Exception {
//创建字符输出流对象
FileWriter fw = new FileWriter("fw.txt") ;
//1) 写一个字符
fw.write('a');
//一个字符:对应两个字节
//针对文本文件进行操作,单位:字节
fw.write(97);
//刷新流
fw.flush();
fw.write(98);
//2) 写一个字符数组
char[] chs = {'a','b','c','d','e'} ;
fw.write(chs);
//3) 写一个字符数组的一部分
fw.write(chs, 1, 3);
//4) 写字符串
String str = "我爱高圆圆" ;
fw.write(str); //写字符串的方法
//5) 写字符串的某一部分
fw.write("我爱高圆圆", 0, 3);
//字符流中的close:关闭该流的同时,之前一定要刷新流
fw.flush();
fw.close();
}
}
字符缓冲输入/输出流:
BufferedWrier字符缓冲输出流:文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入;字符缓冲输入流:
特有功能:public void newLine():写入一个行分隔符;
字符缓冲输出流:
特有功能:public void readLine():一次读取一行;
举例:
public class BufferedDemo {
public static void main(String[] args) throws Exception {
write();
//读数据
BufferedReader br = new BufferedReader(new FileReader("bw2.txt")) ;
//代码在重复 ,改进
String line = null ;
while((line=br.readLine())!=null) {
System.out.println(line);
}
//释放资源
br.close();
}
private static void write() throws IOException {
//字符缓冲输出流读数据
BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt")) ;
//写数据
for(int x = 0 ; x <10 ; x ++) {
//写数据
bw.write("hello"+x);
//之前的换行
//bw.write("\r\n"); //写入换行符号
bw.newLine();
//刷新
bw.flush();
}
//关闭流
bw.close();
}
}
BufferedReader的构造方法:
public BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流;
public BufferedReader(Reader in, int sz):创建一个使用指定大小输入缓冲区的缓冲字符输入流;
举例:
public class BufferedReaderDemo {
public static void main(String[] args) throws Exception {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
//读数据
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=br.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
//释放资源
br.close();
}
}
BufferedWrier的构造方法:
BufferedWriter(Writer out):默认缓冲区大小构造字符缓冲输出流对象;
BufferedWriter(Writer out,int size):指定缓冲区大小;
举例:
public class BufferedWriterdemo {
public static void main(String[] args) throws Exception {
//创建一个字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
//写数据
bw.write("hello");
bw.write("world");
//刷新流
bw.flush();
//关闭资源
bw.close();
}
}
综合练习:
public class CopyDemo {
public static void main(String[] args) throws Exception {
//源文件:StringDemo.java
//目的地文件:当前项目下copy.java
//封装文件
BufferedReader br = new BufferedReader(new FileReader("StringDemo.java")) ;
//封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java")) ;
//一次读取一个字符数组
/*
char[] chs = new char[1024] ;
int len = 0 ;
while((len=br.read(chs))!=-1) {
bw.write(chs, 0, len);
bw.flush();
}
*/
//一次读取一行
String line = null ;
while((line=br.readLine())!=null) {
//写
bw.write(line);
bw.newLine();
bw.flush();
}
//关闭资源
bw.close();
br.close();
}
}
综合练习1:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
/**
* 2. 需求:把ArrayList集合中的字符串数据存储到文本文件
*
* ` ArrayList集合存储的元素String,可以存储一些字符串
* 使用增强for遍历ArrayList
* 使用BufferedWriter(文本文件)
*
*
* 源文件:ArrayList<String>
* 目的地:BufferedWriter输出文本文件,给文件中写入字符
*
*/
public class ArrayListToFileTest {
public static void main(String[] args) throws Exception {
//创建一个ArrayList集合
ArrayList<String> list = new ArrayList<String>() ;
//添加元素
list.add("hello") ;
list.add("world") ;
list.add("java") ;
list.add("hello") ;
//创建一个字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt")) ;
//遍历
for(String s:list) {
//将集合中元素写入到流中
bw.write(s);
bw.newLine();
bw.flush();
}
//关闭资源
bw.close();
}
}
综合练习2:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 复制文本文件(5种方式分别完成)
*
* 文本文件:字符流
*
* 基本的字符流一次读取一个字符
* 一次读取一个字符数组
* 字符缓冲流一次读取一个字符
* 一次读取一个字符数组
* 一次读取一行
* @author Administrator
*
*/
public class CopyTest {
public static void main(String[] args) throws Exception {
//method1("StringDemo.java","copy.java") ;
method2();
}
private static void method2() throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader(new FileReader("StringDemo.java")) ;
BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java")) ;
//一次读取一行
String line = null;
while((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
private static void method1(String src, String dest) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(src)) ;
BufferedWriter bw = new BufferedWriter(new FileWriter(dest)) ;
//一次读取字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=br.read(chs))!=-1) {
bw.write(chs, 0, len);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
综合练习3:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
/**
*需求:有一个文本文本,需要将文本文件中的内容放到ArrayList集合中,遍历集合获取元素
*
*源文件:b.txt----->读取---->BuffferedReader
*目的地:ArrayList<String>
*
*/
public class FileToArrayListTest {
public static void main(String[] args) throws Exception {
//封装源文件
BufferedReader br = new BufferedReader(new FileReader("b.txt")) ;
//创建一个ArrayList集合
ArrayList<String> list = new ArrayList<String>() ;
//读b.txt文件的内容
String line = null ;
while((line=br.readLine())!=null) {
//将数据添加到集合中
list.add(line) ;
}
//遍历集合
for(String s:list) {
System.out.println(s);
}
//关闭流
br.close();
}
}
综合练习4:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Random;
/**
*需求:我有一个文本文件中存储了几个名称,请大家写一个程序实现随机获取一个人的名字。
*
*
* 1)封装一个文本文件:使用字符缓冲输入流读文件
* 2)创建一个ArrayList<String>
* 3)使用字符缓冲输入流readLine(),一次读取一行,就将该行数据添加到集合中
* 4)创建Random类对象
* 5)Random类对象.nextInt(集合对象.size()) ;
* 6)通过角标get(int index ):获取内容
*
*/
public class Test {
public static void main(String[] args) throws Exception {
//封装文件
BufferedReader br = new BufferedReader(new FileReader("b.txt")) ;
//创建一个集合
ArrayList<String> array = new ArrayList<String>() ;
//一次读取一行
String line = null ;
while((line=br.readLine())!=null) {
//将数据添加到集合
array.add(line) ;
}
//释放资源
br.close();
//创建Random类对象
Random r = new Random();
//获取随机数
int index = r.nextInt(array.size()) ;
//通过角标查找集合中元素
String name = array.get(index) ;
System.out.println("幸运的人是:"+name);
}
}
内存操作流:使用与临时存储文件;
内存操作输入流:byteArrayInputStream构造方法:ByteArrayInputStream(byte[] buf)
内存操作输出流:byteArrayOutputStream
构造方法:ByteArrayOutputStream()
注意:在内存操作流一个程序结束后,那么这些程序的变量,就会从内存消失(马上消失的这些数据进行读取写入);
举例:
public class ByteStreamDemo {
public static void main(String[] args) throws IOException {
//创建内存操作输出流对象
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
for(int x = 0 ; x <10 ; x ++) {
baos.write(("hello"+x).getBytes());
}
//baos.close(); 该流不需要关闭
//从内存中将内从中的数据显到控制台上
//public byte[] toByteArray():构造一个字符串
byte[] bys = baos.toByteArray() ;
//创建内存操作输入流对象
ByteArrayInputStream bais = new ByteArrayInputStream(bys) ;
//一次读取一个字节
int by = 0 ;
while((by=bais.read())!=-1) {
System.out.print((char)by);
}
}
}
数据流:针对Java基本类型的数据进行读写操作;
数据输入流:DataInputStream数据输出流:DataOutputStream
举例:
public class DataStream {
public static void main(String[] args) throws Exception {
write() ;
read() ;
}
//读
private static void read() throws Exception {
DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt")) ;
//读
int i = dis.readInt() ;
short s = dis.readShort() ;
byte b = dis.readByte() ;
double d = dis.readDouble() ;
float f = dis.readFloat();
boolean flag = dis.readBoolean() ;
char ch = dis.readChar() ;
dis.close();
System.out.println(i);
System.out.println(s);
System.out.println(b);
System.out.println(d);
System.out.println(f);
System.out.println(flag);
System.out.println(ch);
}
//写
private static void write() throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt")) ;
//给流中写入数据
dos.writeInt(10);
dos.writeShort(100);
dos.writeByte(120);
dos.writeDouble(13.34);
dos.writeFloat(12.56F);
dos.writeBoolean(true);
dos.writeChar('a');
//关闭资源
dos.close();
}
}
打印流:
字符打印流:针对文本进行操作:PrintPrintWriter;特点:只能写数据(对目的文件进行操作,且具有自动刷新功能);
PrintWriter:属于输出流;
1> 只能写数据(只能针对目的地文件进行操作),不能读数据(不能针对源文件进行操作);
2> 可以针对文件直接进行操作;
如果一个类中的构造方法里面有File对象或者String类型数据,这个类可以对文本文件直接操作(FileInputStream,FileOutputStream,FileWriter,FileReader,PrintWriter);
3> 自动刷新功能:PrintWriter(OutputStream out/Writer out,boolean autoflush):第二个参数如果是true 表示启动自动刷新功能;
4> 打印的方法:print(XXX x)/println(XXX xx);
举例:
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//创建一个字符打印流对象
PrintWriter pw = new PrintWriter(new FileWriter("pw.txt")) ;
//写数据
pw.write("hello");
pw.write("world");
pw.write("java");
pw.println("hello");//本身自动换行并且向pw.txt文件打印内容
pw.flush(); //本身在构造的时候,就可以启动自动刷新
//关闭流
pw.close();
}
}
合并流:表示其他输入流的逻辑串联;
构造方法:public SequenceInputStream(InputStream s1, InputStream s2);
public SequenceInputStream(Enumeration e);
第一种构造方式:
举例:
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
//封装源文件
InputStream in1 = new FileInputStream("StringDemo.java") ;
InputStream in2 = new FileInputStream("SystemInDemo.java") ;
//创建合并流对象
SequenceInputStream sis = new SequenceInputStream(in1, in2) ;
//创建一个字节缓冲输入流对象
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.flush(); //读图片文件的时候
}
//关闭资源
sis.close();
bos.close();
}
}
第二种构造方式:举例:
public class SequenceInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//StringDemo.java+SystemInDemo.java+PrintWriterDemo.java--->Copy.java文件中
//定义一个集合Vector
Vector<InputStream> v = new Vector<InputStream>() ;
//使用InputStream封装文件
InputStream s1 = new FileInputStream("StringDemo.java") ;
InputStream s2 = new FileInputStream("SystemInDemo.java") ;
InputStream s3 = new FileInputStream("PrintWriterDemo.java") ;
//将流对象添加到集合中
v.add(s1) ;
v.add(s2) ;
v.add(s3) ;
//特有功能
Enumeration<InputStream> 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.flush();
}
//关闭资源
bos.close();
sis.close();
}
}
标准输入 / 输出流:
InputStream in = System.inPrintStream out = Syste.out
键盘录入的两种方式:
1> Scanner
2> BufferedReader 里面包装字符转换输入流,包装System.in
举例:
public class SystemInDemo {
public static void main(String[] args) throws IOException {
//键盘录入的方式:使用流的方式
//Java的装饰者模式
BufferedReader br = new BufferedReader(new InputStreamReader (System.in)) ;
System.out.println("请输入一个字符串:");
String line = br.readLine() ;
System.out.println("您输入的字符串是:"+line);
System.out.println("请输入一个整数:");
String str = br.readLine() ;
int num = Integer.parseInt(str) ;
System.out.println("输入的整数是:"+num);
}
}
使用BufferedWriter 去包装System.out;
输出的三种方式:
举例:
public class SystemOutDemo {
public static void main(String[] args) throws IOException {
System.out.println("我爱高圆圆");
System.out.println("---------------------------");
PrintStream ps = System.out ;
//PrintStream的功能
//public void println(String x)
ps.println("我爱高圆圆");
ps.println(); //回车换行
//ps.print() ;没有该功能
System.out.println("---------------------------");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)) ;
bw.write("hello");
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("java");
bw.newLine();
bw.flush();
bw.close();
}
}
序列化流以及反序列化流:
序列化:将对象按照流的方式存储到文本文件中或者再网络中传输;
对象---->流数据 序列化流 (ObjectOutputStream);
反序列化:
将文本文件中的流对象或者网络传输中的流对象还原成对象;
流数据--->对象 反序列化流(ObjectInputStream);
注意:
1> 自定义类要实现序列化功能,必须实现接口Serializable接口;
2> 而且需要产生一个随机的ID,当实现了接口,那么程序会在类名的下边显示一个黄色警告线,鼠标移动到这个类上,那么就会显示Add generategenerated serial version ID,点击这个系统就会自动显示一个ID;(如果没有添加随机ID,那么当手动修改了这些类的属性/成员变量,将序列化版本ID改变了,系统在运行时就会显示InvalidClassException这个错误,意思是:该类的序列版本号与从流中读取的类描述符的版本号不匹配,解决:固定ID);
3> 如果有的属性不想被序列化,那么需要在定义的属性前面加上 transient,而不再需要添加public或者private等;
举例:
//定义一个Person类
class Person implements Serializable{
//产生随机的固定Id
private static final long serialVersionUID = 3929786557947102117L;
private String name ;
transient int age ;//这样这个类的属性就不会被序列化
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class ObjectDemo {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//序列化
write() ;
//反序列化
read();
}
//反序列化
private static void read() throws FileNotFoundException, IOException, ClassNotFoundException {
//创建反序列化流对象
//public ObjectInputStream(InputStream in)
ObjectInputStream in = new ObjectInputStream(new FileInputStream("oos.txt")) ;
//读
//public final Object readObject():从 ObjectInputStream 读取对象。
Object obj = in.readObject() ;
in.close();
System.out.println(obj);//Person [name=高圆圆, age=27]
}
//序列化
private static void write() throws FileNotFoundException, IOException {
//创建一个序列化流对象
//public ObjectOutputStream(OutputStream out)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt")) ;
//创建一个Person类对象
Person p = new Person("高圆圆", 27) ;
//public final void writeObject(Object obj)
oos.writeObject(p);
//关闭资源
oos.close();
}
}
属性集合类:
Properties:表示了一个持久的属性集(简称:属性集合类);Properties继承于Map集合;
作用:可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串;
举例:
public class PropertiesDemo {
public static void main(String[] args) {
//它继承Hashtable
//创建一个属性集合类对象
//Properties<String,String> prop = new Properties<String,String>() ;
Properties prop = new Properties() ;
System.out.println(prop);
System.out.println("---------------------");
//给属性集合类中的属性列表添加元素
prop.put("高圆圆", "赵又廷") ;
prop.put("文章", "马伊琍") ;
prop.put("黄晓明", "baby") ;
System.out.println(prop);
//遍历属性集合类
Set<Object> keySet = prop.keySet() ;
for(Object key :keySet) {
Object value = prop.get(key) ;
System.out.println(key+"="+value);
}
}
}
属性集合类的特有功能:
public Object setProperty(String key, String value):给属性列表中添加键和值,并且强制都使用String;
public Set<String> stringPropertyNames():遍历的功能;
public String getProperty(String key):用指定的键在此属性列表中搜索属性;
举例:游戏进度的保存和游戏加载;
举例:
public class PropertiesDemo2 {
public static void main(String[] args) {
//创建属性集合类对象
Properties prop = new Properties() ;
//添加元素
prop.setProperty("张三", "20") ;
prop.setProperty("李四", "22") ;
prop.setProperty("王五", "18") ;
//遍历
//获取所有的键的集合
Set<String> keyset = prop.stringPropertyNames() ;
for(String key:keyset) {
//通过键找值
String value = prop.getProperty(key) ;
System.out.println(key+"----"+value);
}
}
}
在流中使用:public void store(Writer writer,String comments):把集合中的数据保存文本文件中(属性集合);
public void load(Reader reader):将文本文件中的数据加载到属性集合中;
举例:
public class PropertiesDemo3 {
public static void main(String[] args) throws IOException {
MyStore();
MyLoad();
}
//将文本文件中的数据加载属性集合类中
private static void MyLoad() throws IOException {
//创建属性集合类对象
Properties prop =new Properties() ;
//public void load(Reader reader):将文本文件中的数据加载到属性集合中
FileReader fr = new FileReader("prop.txt") ;
//加载
prop.load(fr);
fr.close();
System.out.println(prop);
}
//将属性集合中的数据保存到文本文件中
private static void MyStore() throws IOException {
//创建一个属性集合类对象
Properties prop = new Properties() ;
//添加元素
prop.setProperty("张三", "20") ;
prop.setProperty("文章", "29") ;
prop.setProperty("成龙", "55") ;
//public void store(Writer writer,String comments):把集合中的数据保存文本文件中(属性集合)
FileWriter fw = new FileWriter("name.txt") ;
//将数据保存到文本文件中
prop.store(fw, "names'content");
//释放资源
fw.close();
}
}
综合练习:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/**
* 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其实为”100
1)读取文件的内容,将文件内容加载属性集合类中
2)遍历属性集合,获取所有的键的集合
3)遍历的键的时候,可以判断是否有"lisi"这样一个键
4)有的话,就更改
5)需要将当前属性集合类中的保存文本文件中
*
*/
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();
//遍历属性集合
//获取所有的键的集合
Set<String> keySet = prop.stringPropertyNames() ;
for(String key:keySet) {
//判断
if("lisi".equals(key)) {
//更改
prop.setProperty(key, "100") ;
}
}
//将属性集合中的数据保存文本文件中
FileWriter fw = new FileWriter("user.txt") ;
prop.store(fw, "content");
fw.close();
}
}