黑马程序员Java基础__IO(上)

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------


一、IO类

一、基本框架

一)IO流

(1)IO的分类


A:数据流向

输入流

输出流


B:数据类型

字节流

字节输入流

字节输出流

字符流
字符输入流
字符输出流

字符流只用于处理文字数据,而字节流可以处理媒体数据。


(2)IO流分类的基类


A:字节流

输入流:
InputStream
FileInputStream

BufferedInptuStream

输出流:
OutputStream
FileOutputStream
BufferedOutputStream

B:字符流

输入流:
Reader
FileReader

BufferedReader

输出流:
Writer
FileWriter
BufferedWriter


注意:每种类型的流对象都是以该类型的基类名做后缀名。


二、字符输出流FileWriter的使用


一)使用步骤:

1)创建一个FileWriter对象,该对象一被初始化,就必须要明确被操作的文件。且该目录下如果已有同名文件,则同名文件将被覆盖。其实该步就是在明确数据要存放的目的地。

2)调用write(String s)方法,将字符串写入到流中。

3)调用flush()方法,刷新该流的缓冲,将数据刷新到目的地中。

4)调用close()方法,是关闭流资源。但是关闭前会刷新一次内部的缓冲数据,并将数据刷新到目的地中。


二)代码体现:


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

fw.write("hello,io");

fw.flush();

fw.close();


三、字符输入流FileReader的使用


一)使用步骤:

1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。

2)调用读取流对象的read()方法。read():一次读一个字符,且会继续往下读。

      第一种方式:读取单个字符。第二种方式:通过字符数组进行读取。

3)读取后要将流资源关闭。

注意:close()和flush()区别:flush()刷新后,流可以继续使用;而close()刷新后,将会关闭流,不可再写入字符流。


二)代码体现:


方式1

FileReader fr=new FileReader("demo.txt");  
  int ch=0;  
  /* 
  调用读取流对象的read方法 
  read():一次读一个字符,而且会自动往下读. 
  */  
  while((ch=fr.read())!=-1)  
  {  
  System.out.println("ch="+(char)ch);  
  }  
  /* 
  while(true) 
  { 
   int ch=fr.read(); 
   if(ch==-1) 
    break; 
  System.out.println("ch="+(char)ch); 
  }

方式2

fr=new FileReader("FileWriterDemo.java");  
  //定义一个字符数组.用于存储到字符.  
  //该read(char[])返回的是读到的个数  
  char[] buf=new char[1024];  
  //定义一个变量来记住个数  
  int num=0;  
  //用while循环来判断结尾是否读到的个数为-1  
  while((num=fr.read(buf))!=-1)  
  {  
   //打印个数和字符数组.new String(buf,0,num)是Sting类中打印数组从0开始.到nun结束  
   System.out.print(num+"....."+new String(buf,0,num));  
   //注意输出语句没加ln.是因为数组的长度是1024,如果到了1024就会换行.所以不加.  
  } 

三)复制文本文件


示例1:

import java.io.*;  
class  CopyText  
{  
 public static void main(String[] args)   
 {  
  copy_2();  
 }  
 public static void copy_2()//建立字符数组集体拷贝  
 {  
  FileReader fr=null;//在代码块外边给fr初始化.要不然在代码块里面建立对象别的地方会访问不到  
  FileWriter fw=null;  
  try  
  {  
   fr=new FileReader("MathDemo.java");//建立对象并指定好目录  
   fw=new FileWriter("MathDemo_copy.txt");  
   char[] buf=new char[1024];//建立字符数组,用来储存数据  
  
   int len=0;//定义一个变量来记住字符数  
   while((len=fr.read(buf))!=-1)//因为字符数到末尾会是-1.进行判断  
   {  
    fw.write(buf,0,len);//写出数据.并从零开始.到字符数那里结束  
   }  
  }  
  catch (IOException e)//路径不存在抛异常  
  {  
   throw new RuntimeException("路径不存在");  
  }  
  finally  
  {  
   try  
   {  
    if(fr!=null)//对close判断.是否为空如果建立对象不成功的话close根本不识别.  
     fr.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("写入失败");  
   }  
   try  
   {  
    if(fw!=null)  
     fw.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("读取失败");  
   }  
  }  
 }  
 public static void copy_1()//一个字符一个字符的拷贝  
 {  
  FileReader fr=null;  
  FileWriter fw=null;  
  try  
  {  
   fr=new FileReader("SystemDemo.java");  
   fw=new FileWriter("System_copy.txt");  
  
   int ch=0;  
   while((ch=fr.read())!=-1)  
   {  
    fw.write(ch);  
   }  
  }  
  catch (IOException e)  
  {  
   throw new RuntimeException("路径不存在");  
  }  
  finally  
  {  
   try  
   {  
    if(fr!=null)  
     fr.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("写入失败");  
   }  
   try  
   {  
    if(fw!=null)  
     fw.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("读取失败");  
   }  
  }  
 }  
} 

四、高效流的使用

一)高效输出流(BufferedWriter)的步骤:


1)创建一个字符写入流对象。

2)为提高字符写入流效率,加入缓冲技术,只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。

3)其实关闭缓冲区就是在关闭缓冲区中的流对象。


newLine():根据系统不同写入一个换行符。

二)高效输入流(BufferedReader)的步骤:


1)创建一个读取流对象和文件关联。

2)为提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数。

3)该缓冲区提供了一个一次读一行的方法readLine(),方便与对文本数据的获取,当返回null时,表示读到文件末尾。


readLine():一次读取一行数据。只返回数据,不返回换行符。


(三)高效流复制文件


示例2:

import java.io.*;  
class  CopyTextBuf  
{  
 public static void main(String[] args)   
 {  
  BufferedReader bufr=null;  
  BufferedWriter bufw=null;  
  try  
  {  
   //为了提高效率.加入缓冲技术,将字符读取流对象作为参数传递给缓冲区的构造函数.  
   //建立缓冲区,创建流对象和文件相关联的  
   bufr=new BufferedReader(new FileReader("BufferedReaderDemo.java"));//字符读取流  
  
   bufw=new BufferedWriter(new FileWriter("BufferedReaderDemoCopy_1.txt"));//字符输出流  
   String s=null;//因为读取一行到末尾的时候会返回null.就可以以null作为循环条件来循环  
   while((s=bufr.readLine())!=null)  
   {  
    bufw.write(s);//读取一行.输出一行  
    bufw.newLine();//换行  
   }  
  }  
  catch (IOException e)  
  {  
   throw new RuntimeException("文件路径错误");  
  }  
  finally  
  {  
   try  
   {  
    if(bufr!=null)  
     bufr.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("读取关闭文件失败");  
   }  
   try  
   {  
    if(bufw!=null)  
     bufw.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("输出关闭文件失败");  
   }  
  }  
 }  
}  

------------------------------------------------------------------

五、装饰设计模式:

一)特点:

被装饰的对象功能不够强大,可将其作为参数传入到装饰类中,基于被装饰类已有的功能,提供更强大的功能。

装饰类和被装饰类同属于一个体系,避免了继承体系的臃肿,降低了类与类之间的关系,使用比较灵活。


六、LineNumberReader

一)概述:BufferedReader的子类,也属于装饰类跟踪行号的缓冲字符输入流。

此类定义了方法 setLineNumber(int)、getLineNumber(),它们可分别用于设置和获取当前行号。

示例:
   FileReader fr=new FileReader("demo.txt");//建立输入流对象于文件相关联
   LineNumberReader lnr=new LineNumberReader(fr);//建立缓冲区
   String line =null;
   lnr.setLinNumber(100);//设置行号
   while((line=lnr.readLine())!=null)
   {
    System.out.println(lnr.getLineNumber()+":"+line);//获取行号,和打印一行
   }
   lnr.close

---------------------------------------------------------------------------

七、字节流

一)读写字节流:InputStream     --->  输入流(读)

                               OutputStream   --->  输出流 (写)


二)InputStream常用方法:

  int  |available() 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。


  void |close() 关闭此输入流并释放与该流关联的所有系统资源。


  void |mark(int readlimit) 在此输入流中标记当前的位置。


  boolean | markSupported() 测试此输入流是否支持 mark 和 reset 方法。


  abstract  int| read() 从输入流中读取数据的下一个字节。


  int |read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

 
  int |read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组。


  void|reset() 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。


  long| skip(long n) 跳过和丢弃此输入流中数据的 n 个字节。 
 
 OutputStream类是字节输入流的抽象类,次抽象表示输出字节流的所有类的超类.OutputStream。

 

三)OutputStream常用方法:


   void |close() 关闭此输出流并释放与此流有关的所有系统资源。


   void |flush() 刷新此输出流并强制写出所有缓冲的输出字节。


   void |write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。

 
   void |write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。


   abstract  void |write(int b) 将指定的字节写入此输出流。


八、文件的字节输出(入)流

示例3:

import java.io.*;  
class  CopyPic  
{  
 public static void main(String[] args)   
 {  
  FileInputStream fis=null;  
  FileOutputStream fos=null;  
  try  
  {  
   fis=new FileInputStream("D:\\2.jpg");//建立字符输入流对象和文件相关联  
   fos=new FileOutputStream("copy.jpg");//建立字符输出流对象指定路径和文件名字  
   byte[] buf=new byte[1024];//创建一个字符数组.用来缓存  
  
   int num=0;//定义一个变量用于判断结尾处是否是-1  
  
   while((num=fis.read(buf))!=-1)  
   {  
    fos.write(buf,0,num); //循环一次.字符数组输出一次.  
   }  
  }  
  catch (IOException e)//处理异常  
  {  
   throw new RuntimeException("路径错误");  
  }  
  finally  
  {  
   try  
   {  
    if(fos!=null)//判断创建文件失败是否为null;  
     fos.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("输出关闭失败");  
   }  
   try  
   {  
    if(fis!=null)  
     fis.close();  
   }  
   catch (IOException e)  
   {  
    System.out.println("输入关闭失败");  
   }  
  }  
 }  
} 

九、用缓冲区技术拷贝媒体文件

示例4:

import java.io.*;  
class CopyPic  
{  
    public static void main(String[] args)   
    {  
        //创建流对象引用   
        FileOutputStream fos = null;  
        FileInputStream fis = null;  
        try{  
            //创建读写流对象   
            fos = new FileOutputStream("2.gif");  
            fis = new FileInputStream("1.gif");  
            int len = 0;  
            //定义字节数组,存储读取的字节流   
            byte[] arr = new byte[1024];  
            //循环读写流,完成数据存储   
            while((len=fis.read(arr))!=-1){  
                fos.write(arr,0,len);  
            }  
        }catch (IOException e){  
            throw new RuntimeException("复制图片失败");  
        }  
        //最终关闭资源   
        finally{  
            if(fos!=null){  
                try{  
                    fos.close();  
                }catch (IOException e){  
                    throw new RuntimeException("写入流关闭失败");  
                }  
            }  
            if(fos!=null){  
                try{  
                    fis.close();  
                }catch (IOException e){  
                    throw new RuntimeException("读取流关闭失败");  
                }         
            }  
        }  
    }  
}

十、转换流


一)InputStreamReader :

是字节流通向字符流的桥梁。每次调用 InputStreamReader 中的一个 read()方法都会导致从底层输入流读取一个或多个字节。

要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。 
为了达到最高效率,可以考虑在 BufferedReader 内包装 InputStreamReader。


1)构造方法:
  InputStreamReader(InputStream in)
  InputStreamReader(InputStream in, String charsetName)
 示例:
  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

 

二)OutputStreamWriter :
是字符流通向字节流的桥梁。
将要写入流中的字符编码成字节,每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。

在写入底层输出流之前,得到的这些字节将在缓冲区中累积。

为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。


1)构造方法:

  OutputStreamWriter(OutputStream out)
  OutputStreamWriter(OutputStream out, String charsetName)

 示例:
  BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));


 PrintStream 的构造方法:

 PrintStream(String fileName):创建具有指定文件名称且不带自动行刷新的新打印流。


---------------------------------------------------------------------


十一、异常信息

示例:

import java.io.*;  
import java.util.*;  
import java.text.*;  
class  ExceptionInfo  
{  
 public static void main(String[] args)throws IOException   
 {  
  try  
  {  
   int[] arr = new int[2];  
   System.out.println(arr[3]);  
  }  
  catch (Exception e)  
  {  
     
   try  
   {  
    Date d = new Date();//建立日期类  
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化日期  
    String s = sdf.format(d);  
  
    PrintStream ps = new PrintStream("exeception.log");//设置异常文件  
    ps.println(s);  
    System.setOut(ps);  
  
      
   }  
   catch (IOException ex)  
   {  
    throw new RuntimeException("日志文件创建失败");  
   }  
   e.printStackTrace(System.out);//异常信息  
  }  
 }  
}


一)获取系统信息方法:

Properties getProperties()

示例5:

import java.io.*;  
import java.util.*;  
class  SystemInfo  
{  
 public static void main(String[] args) throws IOException  
 {  
  Properties prop=System.getProperties();  
    
  //System.out.println(prop);  
  prop.list(new PrintStream("sysinfo.txt"));  
  //Properties中的list方法PrintStream创建具有指定文件名称且不带自动行刷新的新打印流。  
 }  
} 

-----------android培训 java培训 、java学习型技术博客、期待与您交流! ------------

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值