黑马程序员——Java字符流、字节流IO流

                    黑马程序员——Java字符流、字节流Io流
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、
<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
一、IO流的概念
      1.程序中所有的数据都是以流的形式输入或保存的,程序需要数据的时候用输入读取流,要保存一些数据用输出流完成
      2.java中对数据的操作是通过流的方式进行的,用来处理设备之间的数据传输,JAVA用于操作流的对象都在IO包中。
 注意:程序中所有输入输出都是以流的形式保存,流中其实保存的全部是字节文件。    
二、流的分类:
流栈操作数据分为两种:字节流和字符流
按流向分为 输入流输出流。




字节流的抽象基类: InputStream  OutputStream
字符流的抽象基类: Reader Writer


IO流用于操作数据
需求:硬盘上生成一个文件
找到一个用于操作文件的 Writer子类对象 FileWriter


package com.study.io;


import java.io.*;
import java.io.IOException;


public class FileWriterDemo {


/**
* @param args
*/
public static void main(String[] args)throws IOException {

//1.先创建FilerWriter对象,该对象一创建就明确被操作的文件
//该文件创建在指定目录下,如果该目录有同名文件,将覆盖。
FileWriter f=new FileWriter("demo.txt");
  //调用write方法,将字符写入流中
f.write("hell,world");

//刷新流
f.flush();
f.write("你好");
f.close();//关闭流,会刷新流中的缓存数据



}


}


硬盘文件读取:Reader 子类FileReader


package com.study.io;


import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;


public class FileReadDemo {


/**
* @param args
* @throws FileNotFoundException 
*/
public static void main(String[] args) throws IOException {

//1.创建读取字符流对象,确保读取的文件存在,否则报IoException 异常
FileReader fr=new FileReader("demo.txt");   

int ch=0;


while((ch=fr.read())!=-1){  //循环读取字符流,读完后返回-1
System.out.print((char)ch);

}
//用Reader中的Read方法读取字符。
int ch1=fr.read();
System.out.print(ch1);
int ch2=fr.read();
System.out.print(ch2);
int ch3=fr.read();
System.out.print(ch3);


        fr.close();//关闭流
}


}
打印:hell,world你好-1-1-1


练习:读取一个文件,打印在控制台
package com.study.io;


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


public class FileReaderDemo1 {


/**
* @param args
*/
public static void main(String[] args)throws IOException{

FileReader fr=new FileReader("Test3.java");   
//使用数组读取文本数据
//read(char[]) 返回的是读取的个数

  char [] buf=new char[1024];  //字符数组进行读取
  int len=0;  //读取个数
  
  while((len=fr.read(buf))!=-1){  //循环读取字符流,读完后返回-1
System.out.print(new String(buf,0,len)); //读到哪打印哪

}
  
 // int num=fr.read(buf);//读取到的字符存储到数组中
  
 // System.out.print(num+""+new String(buf,0,num));

       fr.close();
}


}


需求:将硬盘的文件进行复制,如D盘复制到G盘
分析步骤:1.G盘创建一个文件,用于存储D盘复制过来的数据
          2. 定义读取流与D盘文件的关联
     3. 不断的读取完成数据存储


package com.study.io;


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


    public class CopyFile {


   public static void main(String[] args)throws IOException{
    //1.读取一个已有的文件
   
    FileReader fr=new FileReader("Test3.java");  //当前已有文件(D 盘)
   
    //2.创建一个目的,用于存储复制过来的数据
   
    FileWriter fw=new FileWriter("G://Test3.java");
   
    //3.不断的循环读取,
    int ch=0;
    while((ch=fr.read())!=-1){
    fw.write(ch);  //数据写入目的地
   
   
    }
    fr.close();
    fw.close();
  }
}
第二种方式:方便,专业


package com.study.io;


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


    public class CopyFile {
   
    private static final int BUFER_SIZE=1024; //定义字符常量
   public static void main(String[] args)throws IOException{
   
   
    FileReader fr=null;  //外部先定义好引用
    FileWriter fw= null;   
    try {
    fr=new FileReader("Test3.java");
    fw=new FileWriter("G://Test3.java");
    //创建临时容器,存放用于缓存读取的数据
    char [] buf=new char[BUFER_SIZE]; //缓冲区
   
    int len=0;
    while((len=fr.read(buf))!=-1){
    fw.write(buf,0,len); //写那个字符
   
    }
} catch (Exception e) {
System.out.print("读写失败");
throw new RuntimeException("读取失败");
}finally{
if(fr!=null){ //流还存在,关闭流
try {
fr.close();
} catch (Exception ex) {
ex.printStackTrace();

}
if(fw!=null){
try {
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}

}
        
   
   
    }
   
  }


字符流缓存区:提高书写读取效率
BufferWriter
BufferedReader
特点:缓冲区要结合流才可以使用,在创建缓冲区之前,必须要有流对象。在流的基础上对流的功能进行了增强。
BufferWriter步骤:
1.创建一个字符写入流对象
FileWriter fw=new FileWriter("a.txt");
2.将需要被提高效率的流对象作为参数传递给缓冲区的构造函数
bufferedWriter bufw=new BufferedWriter(fw);
buff.write("asdasdas");
bufw.newLine();//换行符,跨平台的
3.将缓冲区刷新,数据刷新到目的地中
bufw.flush();
4.关闭缓冲区,就是在关闭缓冲区中的流对象


package com.study.io;


import java.io.*;


public class StringBufferWriter {


/**
* @param args
*/
private static final String LINE_SEPARATOR=System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("demo.txt");

//为了提高写入效率,使用字符流缓存区。
//创建字符流写入缓冲区对象,并指定要被缓存的流对象相关联
        
BufferedWriter bufw=new BufferedWriter(fw); //存入fw写入流


//bufw.write("abed"+LINE_SEPARATOR+"hello");
//bufw.write("dddd");
//bufw.newLine();

for(int i=1;i<=4;i++){
bufw.write("hao123"+i);
bufw.newLine();
bufw.flush();
}

//使用缓冲区的方法刷新到目的地中
bufw.flush();

//关闭缓冲区,关闭缓冲区流对象
bufw.close();


}


}


打印:
hao1231
hao1232
hao1233
hao1234


用缓冲区方法读取BufferReader读写文件


package com.study.io;


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


public class BufferTest {


public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("demo.txt");
BufferedReader bufr=new BufferedReader(fr);

FileWriter fw=new FileWriter("copy.txt"); //写入

BufferedWriter bufw=new BufferedWriter(fw);

String line=null;

while((line=bufr.readLine())!=null){//缓冲区一次读取一行数据,读到末位返回null.

bufw.write(line);
bufw.newLine();
bufw.flush();

}

int ch=0;
while((ch=fr.read())!=-1){
bufw.write(ch);
}
bufr.close();
bufw.close();
   }
}
其实readLine()方法无论是读取一行还是多个字符,最终硬盘上都是用read()方法一个个读取。


装饰设计模式:对一组对象功能进行增强,扩展性增强,就可以使用该模式解决问题:例如面试穿西装,装扮一下
装饰类有一个构造方法


package com.study.io;


public class PersonDemo {


/**
* @param args
*/
public static void main(String[] args) {
Person p=new Person();
p.chifan();

SuperPerson p1=new SuperPerson(p);
           p1.Superchifan();


}


}
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.print("抽一根");
}
}
注意:
装饰模式比继承模式要灵活,避免继承臃肿,降低类与类之间的关系。
装饰类和被装饰类同属于一个体系,如同一个接口父类




字节流:
输入流:InputStream 
输出流:OutputStream


FileInputStream:从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。
FileInputStream 用于读取诸如图像数据之类的原始字节流。


FileOutputStream:文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。 
想要操作图片数据,要用到字节流
package com.study.io;


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


public class FileStream {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {

//readFile_1();
//readFile_2();
readFile_3();
//writeFile();


}
public static void readFile_3()throws IOException{
//1.创建字节流读取对象
FileInputStream fi=new FileInputStream("abc.txt");

//System.out.print(fi.available());  //数据大了,会崩溃
int num=fi.available();//字节流个数
byte [] buf=new byte[fi.available()]; //定义一个刚刚好的缓冲区,不要循环了
fi.read(buf);
   System.out.println("num:"+num);
fi.close();

}

public static void readFile_2()throws IOException{
//1.创建字节流读取对象
FileInputStream fi=new FileInputStream("abc.txt");

//System.out.print(fi.available());  //数组大了,会崩溃
byte [] buf=new byte[1024];

int len=0;
while((len=fi.read(buf))!=-1){
System.out.print(new String(buf,0,len));  //一次性打印
}
fi.close();

}
public static void readFile_1()throws IOException{
//1.创建字节流读取对象
FileInputStream fi=new FileInputStream("abc.txt");

System.out.print(fi.available());  //数组大了,会崩溃
int ch=0;
while((ch=fi.read())!=-1){
System.out.println((char)ch);
}
fi.close();

}
public static void writeFile()throws IOException{  //字节流写
//创建字节流输出对象,指定文件关联
FileOutputStream fo=new FileOutputStream("abc.txt");
//写入数据,直接写入目的地。。
fo.write("abcde".getBytes());

//fo.flush();
fo.close();
}


}
练习:复制一个图片,例如F盘test.jpg复制的G盘test.jpg
分析:1.用字节流读取对象和图片关联
      2.用字节流写入流对象创建一个图片文件,用来接收复制过来的图片数据
      3.循环读写,完成数据存储
 4.关闭资源


package com.study.io;


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


public class CopyPic {


/**
* @param args
* @throws IOExceptionn 
*/
public static void main(String[] args) throws IOException {

FileInputStream fi=null;
FileOutputStream fo=null;

try {
 fi=new FileInputStream("F://test.jpg");  //原始文件路径
 fo=new FileOutputStream("G://test.jpg");  //目标路径
byte[] buf=new byte[1024];

int len=0;
while((len=fi.read(buf))!=-1){ 
System.out.print(new String(buf,0,len));
fo.write(buf,0,len);

}
} catch (IOException e) {
throw new RuntimeException("复制文件失败");
}

         finally{
        try {
if(fi!=null){
fi.close();
}
} catch (Exception e2) {
throw new RuntimeException("输入文件失败");
}
        try {
if(fo!=null){
fo.close();//关闭输出流
}
} catch (Exception e3) {
throw new RuntimeException("输出文件失败");
}
         }
}


}


复制MP3  :使用Buffered缓存区,提高效率
分析:缓冲区就是封装了一个数组,对外提供更多方法对数组访问,操作的就是数组的角标。
BufferedInputStream bfis=new BufferedInputStream();//先把文件存入缓存区
BufferedOutputStream bfos=new BufferedOutputStream();//再缓存区输出到目的地
package com.study.io;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class CopyMp3 {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
Copy_1();


}
public static void Copy_1() throws IOException{

BufferedInputStream bfis=new BufferedInputStream(new FileInputStream("G://音乐/迪克牛仔 - 放手去爱.mp3"));//源文件
BufferedOutputStream bfos=new BufferedOutputStream(new FileOutputStream("F://迪克牛仔 - 放手去爱.mp3")); //目的地

try {
byte[] buf=new byte[1024*4];
int len=0;
while((len=bfis.read())!=-1){
System.out.print(new String(buf,0,len));
bfos.write(buf,0,len);
}
} catch (Exception e) {
throw new RuntimeException("复制文件失败");
}finally{
try {
if(bfis!=null){
bfis.close();
}
} catch (Exception e2) {
throw new RuntimeException("输入文件失败");
}
try {
if(bfos!=null){
bfos.close();
}

} catch (Exception e2) {
throw new RuntimeException("输出文件失败");
}
}

}


}




读取键盘录入: System.out :对应标准输出设备,控制台
               System.in  :键盘
当键盘录入一行数据后,就打印改数据
package com.study.io;


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


public class ReadIn {


/**
* @param args
*/
public static void main(String[] args)throws IOException{

//创建缓冲区容器
StringBuilder sb=new StringBuilder();
//键盘读取流
InputStream in=System.in;

/*
int by=in.read();
int by1=in.read();


System.out.println(by);
System.out.print(by1);
*/
/* int ch=0;
while((ch=in.read())!=-1){
System.out.println(ch);
}
*/
//定义变量,记录读取字节
int ch=0;
while((ch=in.read())!=-1){//键盘输入  ch=in.read();
//存储钱判断是否是换行标记,标记不用存储
if(ch=='\r'){
continue;
}
if(ch=='\n'){
String s=sb.toString();
if("OK".equals(s)){
break;
System.out.println(s.toUpperCase());
sb.delete(0, sb.length());
}else{
sb.append((char)ch);
}
}
}

}






}




转换流:字符流+编码表(GBK)
1.文本文件需要明确具体编码时,必须转换流


读取转换流:InputStreamReader  [将字节转换成字符的桥梁]
写入转换流:OutputStreamWriter [将字符转换成字节的桥梁]


2.操作文件字节流对象
FileInputStream
FileOutputStream
BufferedFileInputStream
BufferedFileOutputStream


3.字符流和字节流之间的转换动作:
FileReader fr=new FileReader("a.txt");
InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt")); //操作文件字节流
InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt"),"GBK"); //转换流




FileWriter fw=new FileWriter("a.txt");  //目的
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("a.txt"));
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK");


案例:1.获取键盘录入
package com.study.io;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;


public class TransStreamDemo {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {

//1.字节流
InputStream in=System.in;//键盘输入
int ch=in.read();

System.out.println(ch);

        //将字节转换 成字符的桥梁,转换流

InputStreamReader isr=new InputStreamReader(in);

System.out.println((char)ch);


//字符流

BufferedReader bufr=new BufferedReader(isr);
OutputStream out=System.out;

OutputStreamWriter osw=new OutputStreamWriter(out);

   BufferedWriter bufw=new BufferedWriter(osw);
   
   String line=null;
   while((line=bufr.readLine())!=null){
    if("OK".equals(line)){
    break;
    //System.out.println();
   
   
    }
    bufw.write(line.toUpperCase());
    bufw.newLine();
    bufw.flush();
   }
   
  
}


}




案例2,键盘录入,在控制台输出,over停止输入
package com.study.io;


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


public class TransStreamDemo2 {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
//键盘录入常见写法

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

//输出流
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out) );
       
String line=null;
while((line=bufr.readLine())!=null){
if("over".equals(line)){
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();

}

bufr.close();
}


}
基本数据类型流
package com.study.io;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;


public class DateStreamDemo {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {

//readDate();
//writeDate();

//dataUTFDemo();
//writeUTFDemo();
/*
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
  osw.write("过得还好吗?");
  osw.close();
*/
 readUTFDemo();
 
}
public static void readUTFDemo() throws IOException{

DataInputStream dis=new DataInputStream(new FileInputStream("utfdata.txt"));
             String s=dis.readUTF();
          System.out.println(s);
             dis.close();

}
  public static void writeUTFDemo() throws IOException{
 DataOutputStream dos=new DataOutputStream(new FileOutputStream("utfdata.txt"));
                  dos.writeUTF("很不好");
                  dos.close();
 
  }
public static void dataUTFDemo() throws IOException{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("utfdata.txt"));
                   dos.writeUTF("你好");
                   dos.close();
}
public static void readDate() throws IOException{
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));

int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();

System.out.println("num"+num);
System.out.println("b"+b);
System.out.print("d"+d);

dis.close();
}
public static void writeDate() throws IOException{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(123);
dos.writeBoolean(true);
dos.writeDouble(11223.456);

dos.close();
}



}
File类:将文件系统中的文件和文件夹封装成了对象。提供了更多的属性和行为可以对这些文件和文件夹进行操作。


创建File对象方式
1.将a.txt封装成FIle对象,可以将已有的和未出现的文件或者文件夹封装成对象。
File f=new File("D:\\abc\a.txt");
2.第一个参数代表的是目录,第二个参数代表的是目录下的文件。
File f=new File("D:\\abc","b.txt"); 
3.将路径封装成对象
File f=new File("D:\\abc");
4.调用路径对象 
File f=new File(D,"a.txt"); 


File 常用方法
                                                                                                       
1.创建                                                                                                             
  boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false                             
                          和写入流不一样,写入流创建文件会覆盖已经存在的文件。                                    
                                                                                                         
   File f=new File("a.txt");                                                                                      
   f.createNewFile();                                                                                             
   创建一级目录                                                                                                   
   File dir=new File("abc");                                                                                      
   dir.mkdir();                                                                                                   
   创建多级目录                                                                                                   
   dir.mkdirs();                                                                                                  
                                                                                                                  
2.删除                                                                                                            
   boolean f.delete(); 删除失败,返回false,可能不能删除                                                          
   void deleteOnExit();在程序退出时,删除指定文件。必须删除。不会失败                                             
                                                                                                                  
3.判断 :在判断文件对象是都是文件或者目的时候,必须要先判断该文件对象封装的内容是否存在。                         
   File f=new File("a.txt");                                                                                      
   f.canExecute();是否能执行。                                                                                    
   f.exits();返回boolean  文件是否存在                                                                            
   是否是目录                                                                                                     
   f.isDirectory();                                                                                               
   是否是文件                                                                                                     
   f.isFile();                                                                                                    
   是否是隐藏的                                                                                                   
   f.isHidden();                                                                                                  
   是否是绝对路径                                                                                                 
   f.isAbsolute();                                                                                                
                                                                                                                  
4.获取信息。                                                                                                      
   getName()   //获取名称                                                                                         
   getpath()    //获取路径                                                                                        
   getAbsolutePath() //获取绝对路径                                                                               
   getParent() //获取绝对路径下的父路径,如果获取的是相对路径返回null,如果相对路径中由上一级目录,该目录就是结果?
   lastModified()//获取最后一次修改时间                                                                           
   length();//获取体积大小                                                                                        
                                                                                                                                                                                                               
案例:
package com.study.io;


import java.io.File;
import java.io.IOException;


public class FileDemo {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
FileMethod();
CreateNewFile();
CreateNewFile1();
 
}
//1.创建对象
  public static void FileMethod(){
// 创建文件封装成对象,可以将已有的和未出现的文件或者文件夹封装成对象。
File f1=new File("D:\\abc\\a.txt");
//第一个参数代表的是目录,第二个参数代表的是目录下的文件
//File f2=new File("D:\\abc","b.txt");
// 将路径封装成对象
File d=new File("D:\\abc");
//调用路径对象
File f3=new File(d,"c.txt");
  }


  //2.创建文件夹
  public static void CreateNewFile() throws IOException{
// 创建文件,指定目录创建文件,如果该文件已经存在,则不建立,返回false
File f=new File("D:\\abc\\hell.txt");
            f.createNewFile();
           // f.deleteOnExit();//退出时会删掉
            f.canExecute();// 文件可执行
            f.exists();//判断文件是否存在
           
  }
//3.创建文件夹目录
  public static void CreateNewFile1() throws IOException{
// 创建文件目录
File dir=new File("D:\\test\\hao");
   //创建一级目录
            // dir.mkdir();
             //创建多级目录
            dir.mkdirs();
           
  }


}
5.其他                                                                                                            
                                                   
  1. listRoots();返回 File 数组,列出可用的文件系统根(盘符) 
   例子:
    File[] files=File.listRoots();
     for(File f: files)
     {
              System.out.print(f);
     }


  2.list():返回当前目录下所有文件,包括目录
    public static void ListTest(){
 File dir=new File("D:\\abc\\test");
 String[] names=dir.list();//调用list方法的file对象必须封装了一个目录,那个目录必须存在


      for(String name:names){
      System.out.println(name);
      }
  }


  3. 只显示.bmp结尾的文件(使用到过滤)
      list(FilenameFilter Filter) 返回String[]  指定目录中满足指定过滤器的文件和目录
       File dir=new File("abc");


     String[] names=f.list(new FilenameFileter()


           public boolean accept(File dir,String name)
               {
                  return name.endsWith(".bmp");
                  }
     )
     for(String name: names)
     {
               System.out.println(name);
     }
  4. listFiles();返回当前路径下的文件对象。(不包括子目录)
      
     FIle dir=new File("D:\\"); 
     File[] files=dir.listFiles();
     for(File f : files)
      {
        System.out.print(f);
      } 
      
  递归使用:函数自己调用自己
  需求:列出目录下的文件或者文件夹,包含子目录内容,也就是列出指定目录下的所有内容。
  因为目录中还有目录,只要使用同一个列出目录功能的函数即可,也就是函数调用自己本身。
 package com.study.io;


import java.io.File;


public class TestDigui {


/**
* @param args
*/
public static void main(String[] args) {
//创建目录对象
File dir=new File("D:\\abc");
showDir(dir);
}
public static void showDir(File dir){  //传人File对象
System.out.println(dir);
File [] fl=dir.listFiles();//获取当前路径下的文件对象,存入数组

for(int i=0;i<fl.length;i++){
if(fl[i].isDirectory()){ //判断下面是否是目录,
showDir(fl[i]);//再调用自己方法
}else{
System.out.print(fl[i]);
}
}
}


}
 


打印结果:
D:\abc
D:\abc\a.txtD:\abc\b.txtD:\abc\hell.txtD:\abc\test
D:\abc\test\hao
D:\abc\test\file.txtD:\abc\test\c.txtD:\abc\test\file.javaD:\abc\test\haha.java


Properties集合+IO的使用
Properties集合:1.Properties是HashTable的子类,具备Map集合的特点。
                2.该集合存储的键值对都是字符串类型。
                3.集合中和IO流技术相结合的容器,可用于键值形式对配置文件,操作键盘数据。


package com.study.io;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;


public class PropertiesDemo {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
//PropertiesDemo();
//PropertyMethod_1();
//PropertyMethod_2();
PropertyMethod_3();
//PropertyMethod_4();






}
//1.Properties 集合的存取元素
public static void PropertiesDemo(){
//创建集合 对象
Properties pt=new Properties();
pt.setProperty("张三", "20");

          //取出元素
  Set<String> names=pt.stringPropertyNames();
  for(String name : names)
    {
         String value=pt.getProperty(name);
          System.out.print(name+":"+value);
    }
}
//2.Properties 集合与IO流相结合  ,
public static void PropertyMethod_1(){
//创建集合 对象
Properties pt=new Properties();
pt.setProperty("张三", "20");
pt.setProperty("李四", "11");
pt.setProperty("王博", "28");
pt.setProperty("孙刘", "32");

        pt=System.getProperties();
        pt.list(System.out);// 控制台输出配置文件
}
//3.Properties 集合中的文件存储到文本中 
public static void PropertyMethod_2() throws IOException{
//创建集合 对象
Properties pt=new Properties();
pt.setProperty("张三", "20");
pt.setProperty("李四", "11");
pt.setProperty("王博", "28");
pt.setProperty("孙刘", "32");
//Properties 集合中的文件存储到文本中 ,需要关联输出流

FileOutputStream fos=new FileOutputStream("info.txt");
//将集合的数据存储到文件中,使用store方法
pt.store(fos, "info");
            
fos.close();
}
//3.将info.txt 文本文件存储到Properties 集合中,再控制台输出来
public static void PropertyMethod_3() throws IOException{
//创建集合 对象
Properties pt=new Properties();
pt.setProperty("张三", "20");
pt.setProperty("李四", "11");
pt.setProperty("王博", "28");
pt.setProperty("孙刘", "32");
//Properties 集合中的文件存储到文本中 ,需要关联输出流

FileInputStream fis=new FileInputStream("info.txt");
//load 方法将数据加载到集合中,在控制台列出
pt.load(fis);
       pt.list(System.out);   
fis.close();
}


}
练习定义 :用于记录应用程序运行次数,如果超过5次给出使用次数,请注册的提示。
 package com.study.io;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;


import javax.management.RuntimeErrorException;


public class PropriesTest {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
getCount();


}
   public static void getCount() throws IOException{
  //将配置文件封装成对象
  File fl=new File("D:\\abc\\info.Properties");
  
  // 判断文件是否存在,如果不在就创建一个
  if(!(fl.exists())){
  fl.createNewFile();
  }
  // 使操作文件的输入流,与文件对象关联
  FileInputStream fis=new FileInputStream(fl);
  
  // 创建集合,存储配置文件键值对字符串类型数据
  Properties pt=new Properties();
  
  // 将流数据加载到集合中
            pt.load(fis);
   //集合中通过键获取次数         
   String value=pt.getProperty("time");
   //定义一个计数器
   int count=0;
   if(value!=null){
    count=Integer.parseInt(value);//字符串 转成int
    if(count>5){
    throw new RuntimeException("免费体验次数已到,请注册给钱!");
    }
  }
   count++;
   
   //改变后的次数重新存储到集合中
   pt.setProperty("time", count+"");
   
   FileOutputStream fos=new FileOutputStream(fl);
   
   pt.store(fos, "");
   fis.close();
   fos.close();
   }
   
}


 合并流:                                                                            
 SeaquenceInputStream 对多个文件流进行合并                                               
 package com.study.io;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;


public class SequenceDemo {


/**
* @param args
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
         Vector<FileInputStream> vt=new Vector<FileInputStream>();
         
          vt.add(new FileInputStream("D:\\abc\\a.txt"));
          vt.add(new FileInputStream("D:\\abc\\b.txt"));
          vt.add(new FileInputStream("D:\\abc\\c.txt"));
          
          Enumeration<FileInputStream> en=vt.elements();
          
          SequenceInputStream sqis=new SequenceInputStream(en);
          
          FileOutputStream fos=new FileOutputStream("D:\\abc\\hao123.txt");
          byte[] bt=new byte[1024];
          int len=0;
          
            while(((len=sqis.read(bt))!=-1)){
            fos.write(bt,0,len);
            }
            
            fos.close();
            sqis.close();
}


}
                                                                                    
                                                                                     
 字节编码:                                                                          
 编码:字符串变成字节数组为编码                                                      
 解码:字节数组变成字符串                                                            
 String --->byte[]  str.getByte(charsetName)                                         
 byte[] ---->String  :new String(byte[],charsetName);   


------------------------------------------------------------------------------------------------ 
 字符流字节流特点总结:
字符流:1.字符流处理的是2个字节的字符,保存文本数据,读取字符使用字符流方便,可以自动编码解码。
        2.字符流只能处理字符或者字符串。
        3.字符流使用Unicode字符集,支持多国文字,按16位传输。
字节流:1.处理单元是1个字节,操作字节和字节数组,存取音频、音乐歌曲、图片使用字节流方便。
        2.字节流可以存储任意类型的对象,字节流提供任意类型操作IO流的功能,但不能直接操作Unicode字符。
        3.字节流是8位传输的。
 字节流与字符流的区别:
         1.字节流在操作的时候本身是不会用的缓存区,是与文件本身直接操作,字符流操作的时候用的缓冲区。
         2.字符流操作时,即使不关闭(close)资源 也能输出,字符流必须关闭资源,说明使用的是缓冲区数据。
         
硬盘文件存储:
 所有文件存储都是以字节形式存储的,硬盘上保存的并不是文件的字符,而是先把字符编码成字节,再存储到硬盘中。
 读取文件的时候也是一个字节字节的读取,形成字节序列。
                             
 -------------------重点理解IO流操作规律---- -----------------------------------   
 
举例1:键盘录入,控制台输出
源:键盘录入 
目的:控制台输出
  BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
  
  // 输出 
   BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
 
举例2:将键盘录入的数据保存到一个文件中
分析体系
源:InputStream  Reader
 是纯文本  是,用Reader
设备:键盘,对应对象是System.in 是字节流
为了方便键盘操作文本数据,将字符流转换成字符串操作方便,用了Reader体系的转换流
转换流:InputStreamReader   字节转换字符的桥梁
InputStreamReader isr=new InputStreamReader(System.in);
需要高效率
BufferReader bufr=new BufferReader(isr);
 
目的:OutputStream  Writer
是否是文本? 是 Writer
设备:硬盘  写入一个文件使用 FileWriter,操作方便使用输出使用字符输出转换流:OutputStreamWriter
要高效率吗? 需要 BufferWriter
  OutputStreamWriter fw=new OutputStreamWriter("hello.txt");
  BufferWriter bufw=new BufferWriter(fw);
-----------------------------------------------------------
  BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
  BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("hell.txt")));  
 
扩展:键盘录入的数据按照指定的编码表UTF-8存储,数据保存到文件中
 
目的:OutputStream  Writer
是否是文本? 是 Writer
设备:硬盘  写入一个文件使用 FileWriter
但是FileWriter 只能使用默认的编码表,GBK,存储时需要加入编码表UTF-8,只有转换才可以
使用的对象是OutputStreamWriter 转换流 存储的是字节输出流 FileOutputStream
// 键盘录入
  BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
//指定编码输出,用转换流
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(abcc.txt),"UTF-8")

举例3. 读取一个文本文件,将数据展现在控制台上
1.明确体系
源:输入流  InputStream   Reader  (先读取)
目的:输出流 OutputStream Writer   (写入目的地)


2.明确数据:
源:是文本文件, Reader
目的 :是文本文件 Writer


3.设备:
源:硬盘文件, FileReader
目的 :控制台输出 System.out
FileReader fr=new FileReader("a.txt");  //源
OutputStream out=new System.out; //输出


4.需要额外功能
源是文本,使用字符流操作,
目的地是字节输出流。
需要转换流:OutputStreamWriter
FileReader fr=new FileReader("a.txt");  //源
OutputStreamWriter osw=new OutputStreamWriter(System.out) //目的地


高效率:Buffer 缓冲区
BufferedReader bufr=new  BufferedReader(new FileReader("a.txt")); //源放入缓冲区
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter("a.txt"));  //控制台输出


举例四:读取键盘录入的数据,展现在控制台
1.明确体系
源:输入流  InputStream   Reader  (先读取)键盘
目的:输出流 OutputStream Writer   (写入目的地)控制台


2.明确数据:
源:是文本文件,文件流 InputStreamReader
目的 :是文本文件 OutputStreamWriter


3.设备:
源:键盘, System.in
目的 :控制台输出 System.out
InputStream in=new InputStream(System.in);  //源键盘输入
OutputStream out=new System.out; //控制台输出


4.额外功能
a.确定处理数据是文本数据,字符流体系,方便操作字符数据,都转成字符流
b.提供效率 使用Buffer


BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); //键盘输入
//输出流
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out) );


举例5:读取一个文本文件,将文件按照指定编码UFT-8进行存储,保存到另外一个文件
分析:
1.明确体系
源:输入流  InputStream   Reader  (先读取)
目的:输出流 OutputStream Writer   (写入目的地)


2.明确数据:
源:是文本文件, Reader
目的 :是文本文件 Writer


3.设备:
源:硬盘文件, FileReader  //读取源
目的 :硬盘文件 FileWriter  //写入目的
FileReader fr=new FileReader("a.txt");  //源
FileWriter fw=new FileWriter("a.txt"); //输出


4.额外功能:
1.输出目的中是个文件,但要指定编码表,需要转换流
OutputStreamWriter 这个转换流接收一个字节输出流
对应源是个文件,要使用到操作文件输出流对象 FileOutputStream
FileReader fr=new FileReader("a.txt");  //读取源


OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("fr"));
2.高效率:Buffer


BufferReader bufr=new BufferReader(new FileReader("a.txt"));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),"UTF-8"));


//键盘录入常见写法
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//键盘输入数据
BufferedWriter bufw=new BufferedWriter(new InputStreamWriter("a.txt"));  //写入a.txt


---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a 
href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值