黑马程序员-IO流

------- android培训java培训、期待与您交流! ----------


IO流用来处理设备间的数据传输   流对象都封装在java.io包中

按流向分  输入流 输出流  

按操作数据分字节流 字符流   一般多用字节流 为什么出现字符流  因为不同地方有不同的编码表,在不同国家,不同操作系统的电脑上面会出现乱码,所以字符流可以在内部去融合编码表。

流有4个基类都是抽象类

字符流的抽象基类 InputStream 输入  OutputStream输出

字节流的抽象基类 Reader 读         Writer写

Writer类运用 

write(String str)  写入字符串

write(char[] cbuf)   写入字符数组

write(char[] cbuf, int off,int len)  写入字符数组的某一部分。

flush()  刷新该流的缓冲

close()  关闭流但会刷新它

 

在硬盘上创建数据并写入一些文字数据

FileWriterfw = new FileWriter(“文件路径”);//创建FileWriter对象

fw.write(); //调用writer方法将数据写入到内存中

fw.close(); //将内存中的数据刷新到目的地,并关闭流对象

这种方法会把以前的内容覆盖掉若进行续写的话则FileWriter提供了方法

FileWriter(String fileName, boolean append)

根据给定的 File 对象构造一个 FileWriter 对象。如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处

FileWriterfw = new FileWriter(“文件路径”,true);

处理异常

方法一 直接抛出异常 throws IOException

方法二try{ }catch(){ }

需要注意的是流最后都是要关闭的所以把close()方法放在finally中。但是有时候创建文件时路径不存在,则文件无法创建但无法调用close()方法,导致出现NullPointerException异常。所以需要对关闭的流对象进行空的判断。

代码:

FileWriter fw =null;

       try

       {

          fw = new FileWriter("abc.txt");

          fw.write("abcd");

       }

       catch(IOException e)

       {

          System.out.println(e.toString());

       }

       finally

       {

          try

          {

              if(fw!=null)

                  fw.close();

          }

          catch(IOException e)

          {

              System.out.println(e.toString());

          }

       }

 

读取分两种

第一种一次读一个字节

    FileReaderfr = new FileReader("abc.txt");//创建文件读取对象和指定名称的文件相关联

         intch = 0; 

         while((ch= fr.read())!=-1);//进行循环读取,read()方法如果已到达流的末尾,则返回-1

         System.out.println("ch="+(char)ch);//ch强制转换成char型

         fr.close();

第二种一次读数组

    FileReaderfr = new FileReader("abc.txt");

         char[]buf = new char[2];//创建字符数组buf 数组长度为2。一般以1024的倍数定义

         intnum = 0;

         while((num= fr.read(buf))!= -1)

         System.out.println(newString(buf,0,num));//String(char[] value,int offset, int count)从0开始取,取num个字符

         fr.close();

 

进行文件的拷贝

方法一 一次写一个字符

    FileWriter fw = new FileWriter(”目的地”)

    FilerReader fr = new FileReader(“读取文件路径”);

    Int ch = 0;

       while((ch = fr.read())!=-1);

             fw.write(ch);

       fw.close();

             fr.close();

方法二 一次写数组

    FileWriter fw = new FileWriter(“目的地”);

    FileReader fr = new FileReader(“读取路径”);

    Char[] buf = new char[1024];

    Int num = 0;

    While((num = fr.raed(buf))!= -1);

    Fw.writer(buf);

       fw.close();

             fr.close();

字符流缓存区为了提高读写效率

BufferedReader 和BufferedWriter类  只要将被提高效率的流对象作为参数传递给缓存区的构造函数即可。因此在创建缓存区前必须有流对象。

例: BufferReader br =new BufferReader(new(FileReader(“读取文件路径”)));

 br.close()  关闭缓存区就是关闭缓存区的流对象

在 BufferedWriter中  newline()方法写入一个行分隔符

在 BufferedReader中 readLIne()方法读取一文本行包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null.

readLine()方法的原理是 一个个字节的读取,然后将读取的字节放入缓存区中,遇到/r/n返回.

BufferedWriter

       FileWriter fw = new FileWriter("2.txt");

       BufferedWriter bw = new BufferedWriter(fw);

       for(int x=0; x<5; x++){

           bw.write("abcdefg"+"::"x);

           bw.newLine();

       }

       bw.flush();

       bw.close();

BufferedReader

循环读一行

  FileReader fr = new FilerReader(“读取文件地址”);

  BufferedReader br = new BufferedReader(fr);

  String line = null;

  While((line=br.readLine())!= null)

  System.out.println(line);

  Br.close;

         一次读取单个字符

FileReader fr = new FileReader("2.txt");

       BufferedReader br = new BufferedReader(fr);

       int num = 0;

       while((num=br.read())!=-1){

           System.out.print((char)num);

     }

 

自己定义BufferedReader

 

class MyBufferedReader{

   

    private FileReader r;

    //定义构造函数

    MyBufferedReader(FileReader r){

       this.r = r;

    }

    //定义myReader方法,用于一次读取一行

    public String myReader() throws IOException{

       //定义一个临时容器

       StringBuilder sb = new StringBuilder();

       int ch = 0;

       //当文本没有读到末尾时

       while((ch=r.read())!=-1){

           //如果包含任何行终止符'\r',则继续

           if(ch=='\r'){

              continue;

           }//如果包含任何行终止符'\n',则返回容器中的数据

           if(ch=='\n'){

              return sb.toString();

           }//如果都不满足,则将字符加入临时容器中

           else{

              sb.append((char)ch);

           }  

       }

       return null;

    }

   

    //定义一个关闭缓存区方法

    public void myClose() throws IOException{

       r.close();   

    }  

   

}

 

装饰设计模式

     当想要对已有对象进行功能增强时,可以定义类将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类成为装饰类

 

装饰类通常会通过构造方法接收被装饰的对象

 

装饰和继承的区别

     装饰比继承要灵活避免了继承的臃肿,而且降低了类与类之间的关系。装饰类因增强已有对象具备的功能和已有的是相同的,但提供了更强的功能。所以装饰类和被装饰类通常位于一个体系之下。

     比如MyWriter类中有MyFileWriter  也可以增加MyWordWriterMyPageWriter。但为了提高他们的写入效率加入缓存区MyBufferedFileWriter  MyBufferedWordWriter  MyBufferedPageWriter  但这样不利于程序的扩展性   他们都加入了缓存技术所以直接继承MyWriter就可以  定义MyBufferedWriter即可。提高了可扩展性。即使再加入了其他的类也可以调用MyBuffered

LineNumberReader运用

                   WriterFileReaderfr = new FileReader("2.txt");

LineNumberReader ln = new LineNumberReader(fr);

       String line = null;

       ln.setLineNumber(100);//设置行号

while((line=ln.readLine())!=null){

              System.out.println(ln.getLineNumber()+"::"+line);//获取行号

           }

 

字节流

InputStream 和 OutputStream 

FileOutputStream fos = new FileOutputStream (“文件路径”);//创建FileOutputStream对象

fos.write(“abcd”.getBytes()); //把字符串转变成字符数组

fw.close(); //关闭流对象

 

单个读取

FileInputStream fis = new FileInputStream(“文件名”);

int ch = 0;

while((ch =fis.read())!= -1);

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

Fis.close();

读取数组

FileInputStream fis = new FileInputStream(“文件名”);

byte[] buf =new byte[1024];

int len = 0;

while((len=fis.read(buf))!=-1);

    System.out.println(new String(buf,0,len));

Fis.close();

方法三  因为FileInputStream中定义了available()方法可以获取字符数

FileInputStream fis = new FileInputStream(“文件名”);

byte[] b =new byte[fis.available()];

fis.read(buf);

System.out.println(newString(buf));

fis.close();    

   方法二和方法三区别在于定义的缓存区空间大小不一样。一般文件大采用方法三会造成缓存区溢出。所以方法三适用于小文件。一般采用方法二。

 

拷贝图片

FileInputStream fis = new FileInputStream("s1.jpg");

       FileOutputStream fos = new FileOutputStream("s1-copy.jpg");

       byte[] bt = new byte[1024];

       int leg = 0;

       while((leg=fis.read(bt))!=-1){

           fos.write(bt);

       }

       fos.close();

       fis.close();

 

 

字节流的缓存区

 

BufferedOutputStream bos =

new BufferedOutputStream(new FileOutputStream("s2.mp3"));

BufferedInputStream bis =

new BufferedInputStream(new FileInputStream("s1.mp3"));

       int num = 0;

       while((num=bis.read())!=-1){

           bos.write(num);

       }

       bos.close();

       bis.close();

 

 

 

 

 

键盘录入

System.out:对应的是标准的输出设备 控制台

System.in:对应的是标准的输入设备 键盘

 

 

方法一

InputStream is = System.in;

       StringBuffer sb = new StringBuffer();

       //方法二

/*     while(true){

           int num = is.read();

           if(num == '\r')

              continue;

           if(num == '\n'){

              String s = sb.toString();

              if("over".equals(s));

              System.out.println(s);

              sb.delete(0, sb.length());

           }

           else

              sb.append((char)num);

             

       }*/

       //方法一:

       int num = 0;

       while((num=is.read())!=-1){

           if(num == '\r')

              continue;

           if(num == '\n'){

              String s = sb.toString();

              if("over".equals(s));

              System.out.println(s);

              sb.delete(0, num);

           }

           else

              sb.append((char)num);

       }             }

方法二    转换流

 

方法一录入一行数据就是读取一行,也就是readLine()方法。但readLine()方法是BufferedReader()里的。将字节流转换成字符流需要调用转换流,被封装在字符流中。

InputStreamis = System.in;//创建输入流对象

       InputStreamReaderisr = new InputStreamReader(is);//转换流

       BufferedReaderbr = new BufferedReader(isr);

       Stringline = null;

       while((line=br.readLine())!=null)

       {

           if("over".equals(line))

              break;

           System.out.println(line.toUpperCase());

       }

       br.close();

对方法二读取转换流的优化

    BufferedReaderbr =

newBufferedReader(new(InputStreamReader(System.in)))

读取转换流

BufferedWriterbw =

newBufferedWriter(new(OutputStreamWriter(System.out)))

录入转换流

 

InputStreamReader:字节流通向字符流的桥梁

OutputStreamWriter:字符流通向字节流的桥梁。

                     录入的是字符存在硬盘上的是字节

 

流的操作规律

    流对象有很多,具体调用哪个流对象

第一:明确源和目的。 即输入流还是输出流。

第二:明确是否是纯文本文件。  是字符流。 不是 字节流。

第三:明确调用什么设备。 硬盘file 键盘System.in 控制台System.out。

 

要将数据按照指定编码表存入文件中。

在OutputStreamWriter中定义了

OutputStreamWriter(OutputStream out, String charsetName)
          创建使用指定字符集的OutputStreamWriter。

而在FileWriter中定义死了采用默认的编码形式,所以要指定编码则需要把字符流转变成字节流。

 

改变标准的输入输出设备。

在System中分配了从新分配标准的输入输出流。SetIn   SetOut。

System.SetIn(newFileInputStream(“abc.txt”));

System.SetOut(newPrintStream(“a.txt”));

 

 

 

 

 

 

 

 

File类  用于将文件或者文件夹封装成对象,并且作为参数直接传递给流对象。

创建File对象

File f1 = newFile(“c:\\abc”,”abc.txt”);

在上例中出现目录分隔符\\,若在LINUX中无法识别。所以在File中定义了separator字符,用于替换目录分隔符。

File f1 = newFile(“c:”+”File.separator”+”abc”,”abc.txt”)

   

功能

1.      创建      createNewFile()

      Filef1 = new File(”abc.txt”);

System.out.println(“create”+”f1.createNewFile()”);

若文件已存在则不创建返回false

创建文件夹

File f1 = newFile(”abc”);

System.out.println(“create”+”f1.mkdirs()”);

2.      删除  delete() 和deletetExit()

       System.out.println(“create”+”f1.deleted()”);

       上例中若出现异常则语句无法执行。如果放在finally中则有时删除不掉如文件正在运行时。所以采用delectExit()方法。在程序退出时删除指定文件

       System.out.println(“create”+” deletetExit()”);

3.      判断

       Exists()文件是否存在

           isDirectory()是否是目录

           isFile()是否是文件

           isHidden()是否隐藏

           isAbsolute()是否绝对路径

4.      获取信息

   getName()名称 getPath()路径  getParent()父目录  length()大小

   list()返回一个字符串数组    listFiles()返回一个抽象路径名数组

 

递归

列出指定目录下所有文件和文件夹包括子目录

         publicstatic void main(String[] args){

                   Filedir = new File("d:\\java");  //创建File对象

                   showDir(dir);

         }

        

         publicstatic void showDir(File dir){

                   System.out.println(dir);     //输出文件夹

                   File[]files = dir.listFiles();    //创建数组

                   for(intx=0; x<files.length; x++){

                            if(files[x].isDirectory())   //如果文件是目录

                                     showDir(files[x]);   //循环调用

                            else

                                     System.out.println(files[x]);

                   }

         }

  在上面函数自己点用自身 这种表现形式叫做递归。

 

有序的迭代

public class day2005 {

 

    public static void main(String[] args) {

       File dir = new File("d:\\java");

       getDir(dir,0);

    }

    public static String getLevel(int level){

       StringBuffer sb = new StringBuffer();

       for(int x=0; x<level; x++)

           sb.append("|--");

       return sb.toString();

      

    }

      

    public static void getDir(File dir,int level){

       System.out.println(getLevel(level)+dir.getName());

       level++;

       File[] c = dir.listFiles();

       for(int x=0; x<c.length; x++){

           if(c[x].isDirectory())

              getDir(c[x],level);

           else

              System.out.println(getLevel(level)+c[x]);    

       }         

    }  

 

 

 

删除带内容目录

 

public static void main(String[] args){

                   Filedir = new File("d:\\java");  //创建File对象

                   deleteDir(dir);

         }

        

         publicstatic void deleteDir(File dir){

                   System.out.println(dir);     //输出文件夹

                   File[]files = dir.listFiles();    //创建数组

                   for(intx=0; x<files.length; x++){

                            if(files[x].isDirectory())   //如果文件是目录

                                     deleteDir(files[x]);   //循环调用

                            else

                                     System.out.println(files[x].toString()+::+files[x].delete());

                   }

         }\

 

 

 

 

/*1.将指定的目录进行递归

2.获取递归过程所有的java文件的路径

3.将这些路径存储到集合中

4.将集合中的数据写入到一个文件中*/

public class day2010 {

 

    public static void main(String[] args) throws IOException {

       File dir = new File("d:\\java");

       List list = new ArrayList();

       fileToList(dir,list);

      

       File file = new File(dir,"javaList.txt");

       writeToFile(list,file.toString());

    }

   

    public static void fileToList(File dir,List list){

       File[] files = dir.listFiles();

       for(int x=0; x<files.length; x++){

           if(files[x].isDirectory())

              fileToList(files[x],list);

           else

              list.add(files[x]);

       }

    }

   

    public static void writeToFile(List<File> list,String javaList) throws IOException{

       BufferedWriter bw =

           new BufferedWriter(new FileWriter(javaList));

       for(File f : list){

           String path = f.getAbsolutePath();

           bw.write(path);

           bw.newLine();

           bw.flush();

       }         

    }

   

 

 

 

 

 

 

 

Properties

 Properties 继承于 Hashtable 所以继承map集合的特点,而且它里面存储的键值对都是字符串;是集合和IO相结合的集合容器。

特点:用于键值对形式的配置文件

 

存取:

       Propertiespro = new Properties();

       pro.setProperty("zhangsan","30");

       pro.setProperty("lisi","40");

       System.out.println(pro);//存入

       String value =pro.getProperty("lisi");

       System.out.println(value);//获取值

       Set<String> names =pro.stringPropertyNames();

       for(String s : names)

           System.out.println(s+":"+pro.getProperty(s));//全部获取

 

存取配置文件:

    //1. 创建流对象和a.txt想关联

//2. 读取一行数据,并用=切割

//3. 左边为键  右边为值,存入到Properties集合中

public staticvoid loadDemo() throws IOException{

                   FileReader fr = newFileReader("a.txt");//读取a.txt文件内容

                   BufferedReader br = newBufferedReader(fr);

                   Properties pro = newProperties();

                   String line = null;// 读取一行数据,

                   while((line=br.readLine())!=null){

                            String[] arr =line.split("=");// 用=切割

                            //System.out.println(line);

                   pro.setProperty(arr[0],arr[1]);//左边为键  右边为值,存入到Properties集合中

                   }

                   br.close();

                   System.out.println(pro);//输出pro集合中的数据

IO包中其他类

 

打印流

字节打印流 PrintStream  字符打印流PrintWriter

构造函数可接收的类型

1.file对象 File   2. 字符串路径 String    3. 字节输出流 OutputStream

字符打印流多出个  字符输出流 Writer

BufferedReader br =

             new BufferedReader(newInputStreamReader(System.in));

PrintWriter pw= new PrintWriter(System.out,true);//输出字节输出流,

//如果为 true,则 printlnprintfformat 方法将刷新输出缓

   String line = null;

   while((line = br.readLine())!=null) {

             if("over".equals(line))

                       break;

             pw.println(line);

             pw.flush();//获取一次就刷新一次

   } 

     br.close();


知识总结


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




public class 总结 {


}
/*
字符流:
Reader    为了提高效率产生了缓冲区
---InputStreamReader    
---FileReader 
  
---BufferedReader
---LineNumberReader   
 getLineNumber() 获得当前行号。
 setLineNumber(int lineNumber) 设置当前行号。

Writer    为了提高效率产生了缓冲区
---OutputStreamWriter
---FileWriter

---BufferedWriter






InputStream 方法: close();   read()  读取单个字符;  
 read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。
  
OutputStream 方法:close();  flush();    write(int c) 写入单个字符;
 write(char[] cbuf, int off, int len)  写入字符数组的某一部分。
 
BufferedReader方法:close() 关闭该流并释放与之关联的所有资源。
read() 读取单个字符。
read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
readLine()  读取一个文本行。


 
BufferedWriter方法:close()  关闭此流,但要先刷新它。
newLine() 写入一个行分隔符。
write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
write(int c) 写入单个字符。
应用:复制一个文件
方法一:一次读一个字符
FileReader fr = new FileReader("1.txt");
FileWriter fw = new FileWriter("2.txt");
int num =0;//定义一个变量,用于存储字符
while((num=fr.read())!=-1){
fw.writer((char)num);
}
fw.close;
fr.close;
方法二: 一次读取数组
FileReader fr = new FileReader("1.txt");
FileWriter fw = new FileWriter("2.txt");
char[] c = new char[1024];定义一个数组 
int num = 0;
while((num=fr.read(c)!=-1){
fw.writer(c,0,num); //num的作用  定义数组c为1024个字节,如果不定义num则把1024个字节全部占用了。如果定义了则到文件末尾处就结束了
}
fw.close;
fr.close;

缓冲区:
BufferedReader br = new BufferedReader(new FileReader("2.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("3.txt"));
String leng = null;//一次读取一行
while((leng=br.readLine()!=null){
bw.writer(leng);
}
int num =0; //如果一次读取一个字符
while((num=fr.read())!=-1){
bw.writer(num);
}
bw.close;
br.close;


设置行号和获取行号:
FileReader fr = new FileReader("1.txt");
LineNumberReader lnr = new LineNumberReader(fr);
lnr.setLineNumber("100");设置行号
String leg = null;
while((leg=lbr.readLine())!=-1){
System.out.println(lnr.getLineNumber());获取行号
}

装饰设计模式:
class MyBufferedReader{

private FileReader r;
//定义构造函数
MyBufferedReader(FileReader r){
this.r = r;
}
//定义myReader方法,用于一次读取一行
public String myReader() throws IOException{
//定义一个临时容器
StringBuilder sb = new StringBuilder();
int ch = 0;
//当文本没有读到末尾时
while((ch=r.read())!=-1){
//如果包含任何行终止符'\r',则继续
if(ch=='\r'){
continue;
}//如果包含任何行终止符'\n',则返回容器中的数据
if(ch=='\n'){
return sb.toString();
}//如果都不满足,则将字符加入临时容器中
else{
sb.append((char)ch);
}
}
return null;
}

//定义一个关闭缓存区方法
public void myClose() throws IOException{
r.close();
}

}
*/






/*
 字节流
  InputStream
  ---FileInputStream
 
  ---FilerInputStream
  ---BufferedInputStream
 
  OutputStream
  ---FileOutputStream
 
  ---FilerOutputStream
  ---BufferedOutputStream
 
FileInputStream方法:    available()方法可以获取字符数;  close();
 read() 从此输入流中读取一个数据字节。 
 read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
 
FileOutputStream方法: close();   write(int b) 将指定字节写入此文件输出流。 
write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
 
拷贝图片:
FileInputStream fis = new FileInputStream("s1.jpg");
FileOutputStream fos = new FileOutputStream("s1-copy.jpg");
byte[] bt = new byte[1024];
int leg = 0;
while((leg=fis.read(bt))!=-1){
fos.write(bt);
}
fos.close();
fis.close();

缓冲区:
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("s2.mp3"));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("s1.mp3"));
int num = 0;
while((num=bis.read())!=-1){
bos.write(num);
}
bos.close();
bis.close();

键盘录入
System.out:对应的是标准的输出设备 控制台
System.in:对应的是标准的输入设备 键盘


键盘录入:
InputStream is = System.in;
StringBuilder sb = new StringBuilder();
while(true){
int ch = is.read();
if(ch=='\r')
continue;
if(ch=='\n')
String s = sb.toString();//将缓冲区变成字符串
if("over".equals(s))//如果遇到over则结束while循环
break;
else
System.out.print(sb);
sb.delete(0, sb.length());//清空容器里的数据
}
else
sb.append(ch);//数据继续添加到容器里

}


通过键盘录入方法可以看到和字符流BufferedReader中的readLine()方法相同 。所以是否可以把字节流转换成字符流


转换流:
读取转换流
BufferedReader br = new BufferedReader(new(InputStreamReader(System.in)))
录入转换流
BufferedWriter bw =new BufferedWriter(new(OutputStreamWriter(System.out)))


将键盘输入的数据输出在显示器中
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter (System.out));
String leg = null;
while((leg=br.readLine())!=null){
if("over".equals(leg))
break;
bw.write(leg);
bw.newLine();//newLine()方法在BufferedWriter 中。
bw.flush();


改变标准的输入输出设备
System  中的 SetIn();  SetOut();方法




将异常信息转换到文件中   log4j日志工具
*/
















































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值