------- android培训、java培训、期待与您交流! ----------
流按操作数据分为两种:字节流和字符流。
字符流是基于字节流,去查询对应的编码表所表示的文字,因此适用于文本的传输。
字节流为通用的流,既可以适用文本也可以适用图片等。
4个抽象基类:
字节流:InputStream,OutputStream。
字符流:Reader,Writer。
class FileWriterDemo{
public static void main(String[] args) throws IOException{
//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
FileWriter fw = new FileWriter(“demo.txt”); //该步就是在明确数据要存放的目的地。
fw.writer(“abcde”);//将字符串写入流中。
fw.flush();//刷新流对象中缓冲的数据,将数据刷到目的地中。
fw.close();//刷新后关闭流。
}
}
IO异常处理方式:
class FileWriterDemo2{
public static void main(String[] args){
FileWriter fw = null;
try{
fw = new FileWriter("demo.txt");
fw.write("abcdefg");
fw.close();
}
catch(IOException e){
System.out.println(e.toString());
}
finally{
try{
if(fw!=null)//当找不到文件异常出现时,fw没有指向对象,但还是要执行finally中的代码,这时候调用close方法会出现空指针异常。因此需要先判断一下fw是否为空,再去关闭流
fw.close();
}
catch(IOException e){
System.out.println(e.toString());
}
}
}
}
对已有文本文件的数据续写:
class FileWriterDemo3{
public satic void main(String[] args) throws IOException{
//传递一个true参数,代表不覆盖已有的文件,并在已有文件末尾处续写
FileWriter fw = new FileWriter("demo.txt", true);
fw.write("haha\r\nwawa");//windows下,换行用\r\n表示,linux下用\n表示。
fw.close();
}
}
读取文件:
class FileReaderDemo{
public static void main(String[] args){
//创建一个文件读取流对象,和指定名称的文件相关联。
//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException。
FileReader fr = ew FileReader("demo.txt");
//第一种读取方式:调用读取流对象的read方法,读取文件内容。
int ch = 0;
while((ch = fr.read()) != -1){
System.out.println("ch="+(char)ch);
}
//第二种读取方式:通过字符数组进行读取。
char[] buf = new char[1024];//定义一个字符数组,用于存储读到的字符。
int num = 0;
while((num=fr.read(buf) != -1)){//read(char[])返回读到字符的个数。
System.out.println(new String(buf,0,num));
}
}
//例:复制一个文本文件
public static void copy_1(){
FileWriter fw = null;
FileReader fr = null;
try{
fw = new FileWriter("SystemDemo.copy.txt");//最好先定义FileWriter,在硬盘中先建立一个要写入的空文件。
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf)) != -1){
fw.write(buf, 0, len);
}
}
catch(IOException e){
throw new RuntimeException("读写失败");
}
finally{
if(fr != null){
try{
fr.close();
}
catch(IOException e){
}
}
if(fw != null){
try{
fw.close();
}
catch(IOException e){
}
}
}
}
}
//缓冲区:为了提高流的读写效率而出现。
class BufferedWriterDemo{
public static void main(string[] agrs) throws IOException{
//创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率,加入了缓冲技术。只要将需要被提高的流对象作为参数传递给缓冲区的构造方法即可。
BufferedWriter bufw = new BufferedWriter(fw);
bufw.write("abcde");
bufw.newLine();//为了夸平台的输入换行符,使用此对象输出一个换行符。(Windows:\r\n,Linux:\n)
//关闭缓冲区,就是在关闭缓冲区中的流对象。所以不需要写fw.close()了
bufw.close();
}
public bufferedReaderDemo(){
//创建一个读取流对象和文件相关联。
FileReader fr = new FileReader("buf.txt");
//为了提高效率,创建字符缓冲对象。
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((String s1 = bufr.readLine()) != null){//readLine可以一次性读取一行数据,方便于对文本数据的获取,但是它读取一行后,并没有最后的换行符,需要用newLine()方法添加一个换行符。当返回null时表示读到末尾。
System.out.println("s1:" + s1);
}
bufr.close();
}
public bufferedCopyDemo(){
BufferedReader bufr = null;
BufferedWriter bufw = null;
try{
bufr = new BufferedReader(new FileReader("a.txt"));
bufw = new BufferedWriter(new FileWriter("acopy.txt"));
String line = null;
while((line = bufr.readLine())!= null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch(IOException e){
throw new RuntimeException("读写失败");
}
finally{
try{
if(bufw != null)
bufw.close();
}
catch(IOException e){
throw new RuntimeException("写入关闭失败");
}
}
}
}
readLine方法的原理:无论是读一行,或者读取多个字符。其实最终都是在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。
readLine每次从数据中读取一个字符,存到数组里,当读取到\n的时候,把所有已存的数组数据一起返回。
装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象的功能,并提供加强功能。
那么自定义的该类就称为装饰类。
示例:
class Person{
public void chifan(){
System.out.println("吃饭");
}
}
class SuperPerson{
private Person p;
SuperPerson(Person p){
this.p = p;
}
public void superChifan(){
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
class PersonDemo{
public static void main(String[] args){
//Person p= new Person();
//p.chifan();
SuperPerson sp = new SuperPerson(p);
sp.superChifan();
}
}
装饰设计模式特点:装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
装饰和继承的区别:
装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,知不是提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中。
LineNumberReader:另一个装饰类,提供了行号的设置和获取:
setLineNumber(100);//将行号起始值设为100
getLineNumber();//返回当前行号。
字节流:
InputStream OutputStream
需求:想要操作图片数据,就要用到字节流。
class FileStream{
public static void main(String[] args) throws IOException{
System.out.println("Hello World!");
}
public static void writeFile() throws IOException{
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());//将字符串转换为字节。
fos.close();
}
public static void readFile_1() throws IOException{
FileInputStream fis = new FileInputStream("fos.txt");
int ch = 0;
while((ch=fis.read()) != -1){
System.out.println((char)ch);
}
fis.close();
}
public static void readFile_2() throws IOException{
FileInputStream fis = new FileInputSteam("fos.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}
fis.close();
}
public static void readFile_3() throws IOException{
FileInputStream fis = new FileInputStream("fos.txt");
//int num = fis.available();//获取文件大小(字节数)
byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区,不用循环了,但是容量过大时会出现内存溢出,所以此方法要慎用
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
}
键盘输入流:System.in,返回InputStream对象。
*要使用字符流bufferedReader的readLine()方法获取键盘输入字节流的一行数据,应该怎样做?
class TransStreamDemo{
public static void main(String[] args) throws IOException{
InputStream in = System.in;//获取键盘录入对象
InputStreamReader isr = inputStreamReader(in);//将字节流转换为字符流。
BufferedReader bufr = new BufferedReader(isr);
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");//创建一个字符输出流。编码表为"UTF-8"
BufferedWriter bufw = new BufferedWriter(osw);
Sting line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line)){//如果输入over,退出程序。
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
流的基本规律:两个明确:
1,明确源和目的。
源:输入流。InpusStream Reader
目的:输出流。OutputStream Writer
2,操作的数据是否是纯文本。
是,字符流。
不是,字节流。
3,当体系明确后,再明确要使用哪个具体的对象。
通过设备来进行区分。
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
IO对Properties()的操作:
class SystemInfo{
public static void main(String[] args) throws IOException{
Properties prop = System.getProperties();//获得系统信息
prop.list(new PrintStream("sysinfo.txt"));//list方法可以将信息输出到指定输出流。
}
}