黑马程序员——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>、期待与您交流! -------------------------------

黑马程序员——Java字符流、字节流IO流相关推荐

  1. 黑马程序员 关于学习毕老师IO流后的一些笔记

    ---------------------- ASP.Net+Android+IO开发S..Net培训.期待与您交流! ---------------------- 流的本质是数据传输,根据数据传输特 ...

  2. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  3. 黑马程序员Java零基础视频教程_下部(P52-P134)

    黑马程序员Java零基础视频教程_下部(P52-P134) 1. 异常 1.1 异常体系介绍 1.2 编译时异常和运行时异常 1.3 异常在代码中的两个作用 1.4 JVM虚拟机默认处理异常的方式 1 ...

  4. 黑马程序员Java教程学习笔记(五)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...

  5. 黑马程序员Java教程学习笔记(三)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(三) 面向对象:设计对象.注意事 ...

  6. 黑马程序员Java零基础视频教程_下部(P135-P200)

    黑马程序员Java零基础视频教程_下部(P135-P200) 1 多线程 1.1 什么是多线程? 1.2 多线程的并发与并行 1.3 多线程的实现方式 1.3.1 继承Thread类的方式进行实现 1 ...

  7. 黑马程序员Java零基础视频教程_上部(P1-P80)

    黑马程序员Java零基础视频教程_上部(P1-P80) 1. Java入门 1.1 Java学习介绍 1.2 Java人机交互 1.2.1 常用CMD命令 2. Java基础学习 2.1 Java入门 ...

  8. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  9. 2023年黑马程序员Java学习路线图

    2023年Java学科免费学习资源放送40+套课程,超过600小时的内容! 在过去的一年里,为了帮助更多人线上充电,学会更多技能,黑马程序员举办了 150+ 场免费直播公开课,新增精品视频教程 80+ ...

最新文章

  1. The difference between synchronous and asynchronous code in JavaScript
  2. java 取字符的ascii_如何用java获得字符串的ASCII值
  3. Unable to locate Attribute with the the given name [] on this ManagedType[com.XXX]
  4. angular 字符串转换成数字_Python | 一文看懂Python列表、元组和字符串操作
  5. javascript高级程序设计-Array迭代及归并
  6. 怎样将Redis以本地服务方式进行启动?
  7. SwiftUI 高级用法之ForEach如何使用 enumerated() UserDefaults.standard(教程含源码)
  8. python绘制网格线在原图上面_在pyqtgraph中在图像上显示网格线
  9. 五阶魔方公式java_五阶魔方花样有多漂亮,关键是有点难
  10. hdu2203java_HDU2203(KMP入门题)
  11. java大数据培训专业课程与教学模式的介绍
  12. 公务员考试要求及流程梳理
  13. iPhone开发网站、论坛、博客 .
  14. 1024: 计算字母序号 C语言
  15. 【linux】使用systemctl start xxx启动自己的程序|开机启动|守护进程
  16. Linux 中ln 命令-n 参数的含义
  17. 阿里巴巴启动全面组织升级
  18. antd中默认的样式修改不了咋办呢,捉急呀
  19. 下载资源前请务必先阅读!
  20. 网络语言为你打c,“想打定话给你”是什么梗

热门文章

  1. 计算机专业学生必备技能
  2. 【模拟赛】卷王(构造)
  3. 乌镇•白硕:抗衡Libra,我们需要建立一个法定数字货币体系
  4. linux显示器镜像翻转,Ubuntu Linux显示器屏幕偏移的解决办法
  5. 酷云互动首推以隐私计算为底层的品效协同平台 助力行业发展
  6. 大数据发展和就业前景好吗?大数据人才缺口有多大?
  7. android 字体样式设置为LCB(实现第三方库字体)
  8. 【JS高级】正则入门基础—关于你想知道的正则表达式_01
  9. PHP代码覆盖率测试
  10. Elasticsearch(ES)常用命令整理