字节流与字符流

 

字节流

基本输入流(InputStream)和基本输出流(OutputStream)是字节流类,读写以字节为单位进行

其中基本输入流InputStream层次:

其中基本输出流OutputStream层次:

 

1、引入:

通过对File类的学习,我们已经了解并掌握了Java对目录和文件的管理,但File类不是流类,没有对文件内容的读写方法,要完成对文件内容的读取和写入,

java.io包中的FileInputStream类和FileOutputStream类可以对文件内容的读取和写入所有的读写操作只能以字节为单位对二进制数据进行处理

2、介绍:

FileInputStream类和FileOutputStream类的构造函数是创建一个输入输出的对象,通过引用该对象的读写方法,来完成对文件的输入输出操作。

当然,要构造一个FileInputStream对象,所连接的文件必须存在而且是可读的;构造一个FileOutputStream对象如果输出文件已经存在且可写,该文件内容会被新的输出所覆盖。否则会出现IOException异常。

 

 

 

 

 

 

 

 

 

 

 

1、FileInputStream输入流与 FileOutputStream输出流
FileInputStream
2种构造方法:
① public FileInputStream(String name):
例如:
FileInputStream f=new FileInputStream(" D:/java/ex.java");
② public FileInputStream(File file):
例如:
Filef=new File(" D:\\javapj\\ex.java");
FileInputStream fin=new FileInputStream(f);
文件的输入流的基本操作
int  available()
返回可以不受阻塞地从此输入流读取的字节数。
void close()
关闭此文件输入流并释放与此流有关的所有系统资源
int  read()
从此输入流中读取一个数据字节。
int  read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
 
 
 
 
 
 
 
 
 
 
FileOutputStream
2种构造方法:
① public FileOutputStream(String name):
例如:
FileOutputStream f=new FileOutputStream("D:/java/ex.java");
② public FileOutputStream(File file):
例如:
Filef=new File(" D:\\javapj\\ex.java");
FileOutputStream fin=new FileOutputStream(f);
文件输出流的操作方法
void  close()
关闭此文件输出流并释放与此流有关的所有系统资源。
void  write(byte[] b)
将 b.length 个字节从指定 byte 数组写入此文件输出流中。
void  write(int b)
将指定字节写入此文件输出流。

 

 

 

 

 

 

 

 

 

 

例1.建立一个FileInputStream对象。 读取某一文件的内容

注意:方法1可读取中文内容,方法2不可以

方法1:

import java.io.*;

public class FileInputStreamDemo

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

      {

      FileInputStream f=new FileInputStream("E:\\Code\\t2.txt");

      int i=f.available();  //获取f的字节数

      byte[] b=new byte[i];  //建立一个字节数组,数组大小由文件大小决定

      f.read(b);   //读取文件f中的内容到b数组中

      f.close();

      String s=new String(b);  //将字节数组b转为字符串

      System.out.println(s);

      }

}

 

方法2:

import java.io.*;

public class FileInputStreamDemo{

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

      {

      FileInputStream f=new FileInputStream("E:\\Code\\t2.txt");

      int c;

      while((c=f.read())!=-1)

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

      f.close();

      }

}

 

 

 

 

例2.建立一个FileOutputStream对象,将字符串写入到记事本中
import java.io.*;
public class FileOutputStreamDemo{
public static void main(String args[])throws IOException,Exception
  {
FileOutputStream f=new FileOutputStream("E:\\Code\\t2.txt",true);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  System.out.println("请输入内容:");
  String s=br.readLine();
  byte[] b=s.getBytes();
  f.write(b);
 f.close();
  }
}

 

 

 

 

 

 

 

 

 

 

2.DataInputStream 和DataOutputStream类
字节文件流FileInputStream 和FileOutputStream只能提供纯字节或字节数组的输入/输出,如果要进行基本数据类型如整数和浮点数的输入/输出。则要用到过滤流类的子类二进制数据文件流DataInputStream 和DataOutputStream类。这两个类的对象必须和一个输入类或输出类联系起来,而不能直接用文件名或文件对象建立。
使用数据文件流的一般步骤:
(1)建立字节文件流对象;
(2)基于字节文件流对象建立数据文件流对象;
(3)用流对象的方法对基本类型的数据进行输入/输出。     
DataInputStream类的构造方法如下:
DataInputStream(InputStream in)创建过滤流FilterInputStream对象并为以后的使用保存InputStream参数in。
DataOutputStream类的构造方法如下:
DataOutputStream(OutputStream out)创建输出数据流对象写数据到指定的OutputStream 。

 

 

 

 

 

 

 

 

 

例3.import java.io.*;
public class DataOutputStreamDemo1{
public static void main(String args[])throws IOException,Exception
    {  //写入
     FileOutputStream f=new FileOutputStream("t1.txt",true);   
     DataOutputStream out=new DataOutputStream(f);
     String s="java 教程 ";
     out.write(s.getBytes());//取得字符串对应的二进制码,然后再写入文件中  
   
     //读取
     FileInputStream f1=new FileInputStream("t1.txt");
     DataInputStream in=new DataInputStream(f1);
     int i=f1.available();
     byte[] b=new byte[i];
     in.read(b);
     String str=new String(b);
     System.out.println(str);
     out.close();
    }
}

 

 

 
例4.在E盘根目录下建立文件FIB.DAT,存储Fibonacci数列的前20个数。Fibonacci数列的前两个数是1,从第三个数开始,是其前两个数之和。即1,1,2,3,5,8,13,21,.…。
import java.io.*;
class OutputStreamDemo2 { 
    public static void main(String args[]) {
        try { // 创建字节文件输出流
        OutputStream fos =
          new FileOutputStream("E:/fib.dat");
        DataOutputStream dos =
          new DataOutputStream(fos);
        int count = 0,i = 1,j = 1;
        for(;count < 20; count++){
           dos.writeInt(i);
           int k = i + j;
           i = j;
           j = k;
        }
        fos.close();  // 关闭文件输出流
      } catch(Exception e) {
       System.out.println("Exception: " + e);
     }
     System.out.println("文件创建成功!");
   }
}
程序运行正常结束后,可以在E盘的根目录见到创建的文件FIB.DAT。这是二进制数据文件,用系统的TYPE命令查看其内容是无意义的。可用下例程序来查看其内容。
 
 
例5.从上例建立的文件中读取Fibonacci数据并显示到屏幕上。
import java.io.*;
class DataInputStreamDemo{
public static void main(String args[]) {
  try {                          
   FileInputStream fis =
    new FileInputStream("E:/fib.dat"); //创建输入流
   DataInputStream dis =
    new DataInputStream(fis);      //创建数据输入流
   for(int i = 0; i < 20; i++){    // 读数据
    if(i % 10 == 0)System.out.println();
      System.out.printf(“%5d”,dis.readInt());
    }
    fis.close(); // 关闭文件输入流
   } catch(Exception e) {
      System.out.println("Exception: " + e);
    }
    System.out.println();
  }
 }
 
 
 
 
3.BufferedInputStream和BufferedOutputStream类
若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流。缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率。
缓冲输出流BufferedOutputStream类提供和FileOutputStream类同样的写操作方法,但所有输出全部写入缓冲区中。当写满缓冲区或关闭输出流时,它再一次性输出到流,或者用flush()方法主动将缓冲区输出到流。
当创建缓冲输入流BufferedInputStream时,一个输入缓冲区数组被创建,来自流的数据填入缓冲区,一次可填入许多字节。
(1)创建BufferedOutputStream流对象
若要创建一个BufferedOutputStream流对象,首先需要一个FileOutputStream流对象,然后基于这个流对象创建缓冲流对象。
BufferedOutputStream 类的构造方法如下:
BufferedOutputStream(OutputStream out)创建缓冲输出流,写数据到参数指定的输出流,缓冲区设为缺省的512字节大小。
BufferedOutputStream(OutputStream out, int size)创建缓冲输出流,写数据到参数指定的输出流,缓冲区设为指定的size字节大小。
例如,下面的代码可创建一个缓冲输出流bos:
FileOutputStream fos =new FileOutputStream("/user/dbf/stock.dbf");
BufferedOutputStream bos =new BufferedOutputStream(fos);
(2)用flush()方法更新流
要想在程序结束之前将缓冲区里的数据写入磁盘,除了填满缓冲区或关闭输出流外,还可以显式调用flush()方法。flush()方法的声明为:
 public void flush() throws IOException
        例如:bos.flush();
(3)创建BufferedInputStream流对象
BufferedInputStream类的构造方法如下:
BufferedInputStream(InputStream in)
创建BufferedInputStream流对象并为以后的使用保存InputStream参数in,并创建一个内部缓冲区数组来保存输入数据。
BufferedInputStream(InputStream in, int size) 用指定的缓冲区大小size创建BufferedInputStream流对象,并为以后的使用保存InputStream参数in。
(4)缓冲流类的应用
缓冲流类一般与另外的输入输出流类一起配合使用。对例5,可以将流对象定义修改为:
FileInputStream fis =new FileInputStream("E:/fib.dat");
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
 
 
 
 
 
 
 
 
 
 
 
 
 

字符流

Java提供了处理以16位的Unicode码表示的字符流的处理能力。包Java.io中的类Reader和Writer是所有字符流的父类。

这两个类是抽象类,只提供了一系列用于字符流处理的接口,不能生成这两个类的实例。只能使用它们的子类的对象处理字符流。

1.InputSteamReader和OutputStreamWriter类
这是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范。
InputSteamReader和OutputStreamWriter类的构造方法如下:
public InputSteamReader(InputSteam in)
public InputSteamReader(InputSteam in,String enc)
public OutputStreamWriter(OutputStream out)
public OutputStreamWriter(OutputStream out,String enc)
其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式)。
读写字符的方法read()、write(),关闭流的方法close()等与Reader和Writer类的同名方法用法都是类似的。

为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。

 

 

 

例6.用字符流从文本文件中读取字符:

import java.io.*;
public class InputStreamReaderDemo 
{public static void main(String args[ ])throws IOException
  {FileInputStream f=new FileInputStream("t1.txt");
   InputStreamReader r=new InputStreamReader(f);
   int i=f.available();
   char[] c=new char[i];
   r.read(c);
   r.close();
   String s=new String(c);
   System.out.print(s);
   }
}
例7.用字符流向文本文件中写入字符:
import java.io.*;
public class OutputStreamWriterDemo 
{public static void main(String args[ ])throws IOException
  {FileOutputStream f=new FileOutputStream("t1.txt");
   OutputStreamWriter w=new OutputStreamWriter(f);
   String s="Java 教程";
   char[] c=s.toCharArray();
   w.write(c);
   w.close();
   }
}

 


 

2.FileReader和FileWriter类
FileReader和FileWriter类是InputSteamReader和OutputStreamWriter类的子类,利用它们可方便地进行字符输入/输出操作。
FileReader类的构造方法有:
FileReader(File file)对指定要读的file创建FileReader对象。
FileReader(String fileName) 对指定要读的  fileName创建FileReader对象。
FileWriter类的构造方法有:
FileWriter(File file) 对指定的file创建FileWriter对象。
FileWriter(String fileName) 对指定的fileName创建FileWriter对象。
这两个构造方法都可带第二个布尔值的参数append,当append为true时,为添加到输出流。
FileReader类中可用的方法有:read()返回输入字符,read(char[] buffer)输入字符到字符数组中等。
FileWriter类中常用的方法有:write(String str)和Write(char[] buffer)输出字符串,write(int char)输出字符,flush()输出缓冲字符,close()在执行flush后关闭输出流,getEncoding()获得文件流字符的编码等。

 

 

 

 

 

 

 

 

 

 

//例8.读取文件中的内容:
//方法1:
import java.io.*;
public class FileReaderDemo{
public static void main(String args[])throws IOException,Exception
{char data[]=new char[1024]; // 建立可容纳1024个字符的数组
FileReader fr=new FileReader("t1.txt"); // 建立对象fr
 int num=fr.read(data); // 将数据读入字符列表data内
 String str=new String(data,0,num); // 将字符列表转换成字符串
 System.out.println("Characters read= "+num); // 输出在控制台
 System.out.println(str);
 fr.close();
}
}
//方法2:
import java.io.*;
public class FileReaderemo{
public static void main(String args[])throws IOException,Exception
    {
  FileReader fr=new FileReader("t1.txt");
    int c;
    while((c=fr.read())!=-1)
         System.out.print((char)c);
  fr.close();
    }
}
//例9.向文件中写入内容:

import java.io.*;

import java.util.Scanner;

public class FileWriterDemo{

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

  {

  FileWriter fr=new FileWriter("t2.txt",true);

  Scanner sc=new Scanner(System.in);

  System.out.println("请输入内容:");

  String s=sc.next();

  fr.write(s);

  fr.close();

  }

}

 


3.BufferedReader和BufferedWriter类
缓冲字符流类BufferedReader和BufferedWriter的使用,可提高字符流处理的效率。它们的构造方法如下:
public BufferedReader(Reader in)
public BufferedReader(Reader in,int sz)
public BufferedWriter(Writer out)
public BufferedWriter(Writer out,int sz)
其中in和out分别为字符流对象,sz为缓冲区大小。从上述构造方法的声明可以看出,缓冲流的构造方法是基于字符流创建相应的缓冲流。
在BufferedReader和BufferedWriter类中,除了Reader和Writer中提供的基本读写方法外,增加了对整行字符的处理方法readLine()和newLine()。前者从输入流中读取一行字符,行结束标志为回车符和换行符;后者向字符输出流中写入一个行结束标记,该标记是由系统定义的属性line.separator。

 

 

例10.创建顺序文本文件。使用FileWriter类和BufferedWriter类和用write()方法写文件。

import java.io.*;

public class BufferedWriterDemo {

public static void main(String args[]) {

  try {

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

     BufferedWriter bw = new BufferedWriter(fw);

     bw.write("java 教程");

     bw.close();       // 关闭缓冲字符输出流

     }catch(Exception e) {

        System.out.println("Exception: " + e); }

}

}

例11.读顺序文本文件。使用FileReader类和BufferedReader类和用readLine()方法读文件。

import java.io.*;

public class BufferedReaderDemo 

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

  try {

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

      BufferedReader br = new BufferedReader(fr);

      String s;

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

          System.out.println(s);

      fr.close();

      }catch(Exception e) {

         System.out.println("Exception: " + e);}

   }

}

例12.乘坐飞机时,每位顾客可以免费托运20kg以内的行李,超过部分假定按每公斤收费1.2元的话,试编写相应计算收费的程序。

(1)数据变量:

    w -----行李重量(以公斤为单位)

    fee-----收费(单位元)

    根据数据的特点,变量的数据类型必须为浮点型,不妨定为float类型。

(2)算法:

(3)由System.out.println();语句提示用户输入数据(行李重量),然后通过交互式输入方法给w变量赋值。
(4)由单分支结构,构成程序段即对用户敲入的数据进行判断,并按收费标准计算收费额。
import java.io.*;
public class Test
{public static void main(String[] args)throws IOException{  
 float  w,fee;
 char c;
 c = (char)System.in.read();  //等待用户输入
 while(c!='x')
    {   //以下代码为通过控制台交互输入行李重量
InputStreamReader reader=new InputStreamReader(System.in);
BufferedReader input=new BufferedReader(reader);
 System.out.println("请输入旅客的行李重量:");
 input.readLine();    //滤掉无用输入
 String temp=input.readLine();//等待用户输入
 w = Float.parseFloat(temp);  //字符串转换为单精度浮点型
 fee = 0;
 if ( w > 20)
   fee = (float)1.2 * (w-20);
 System.out.println("该旅客需交纳的托运费用:"+fee+"元");
 System.out.println("****************************");
 System.out.println("   *按x键退出,其他键继续*");
 System.out.println("****************************");
 c = (char)System.in.read();  //等待用户输入
     }
    }
}

 

 

 

设计一程序copy.java ,实现文件的拷贝操作

要求:1、模仿dos的copy命令进行编程

2、用File FileInputStream FileOutputStream实现

3、执行格式:java Copy 源文件 目标文件

import java.io.* ;

public class Copy{

       public static void main(String args[]){

              if(args.length!=2){              // 判断是否是两个参数

                     System.out.println("输入的参数不正确。") ;

                     System.out.println("例:java Copy 源文件路径 目标文件路径") ;

                     System.exit(1) ;    // 系统退出

              }

              File f1 = new File(args[0]) ; // 源文件的File对象

              File f2 = new File(args[1]) ; // 目标文件的File对象

              if(!f1.exists()){

                     System.out.println("源文件不存在!") ;

                     System.exit(1) ;

              }

              InputStream input = null ;        // 准备好输入流对象,读取源文件

              OutputStream out = null ;         // 准备好输出流对象,写入目标文件

              try{

                     input = new FileInputStream(f1) ;

              }catch(FileNotFoundException e){

                     e.printStackTrace() ;

              }

              try{

                     out = new FileOutputStream(f2) ;

              }catch(FileNotFoundException e){

                     e.printStackTrace() ;

              }

              if(input!=null && out!=null){   // 判断输入或输出是否准备好

                     int temp = 0 ;      

                     try{

                            while((temp=input.read())!=-1)  // 开始拷贝

                                   out.write(temp) ;  // 边读边写

                            System.out.println("拷贝完成!") ;

                     }catch(IOException e){

                            e.printStackTrace() ;

                            System.out.println("拷贝失败!") ; }

                     try{

                            input.close() ;              // 关闭

                            out.close() ;          // 关闭

                     }catch(IOException e){

                            e.printStackTrace() ;}

              }

       }

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值