【JAVA IO】_字节流与字符流笔记

【JAVA IO】_字节流与字符流笔记

本章目标:

掌握流的概念
掌握字节流与字符流的作用
掌握文件的标准操作步骤
掌握字节与字符操作的区别


程序中的输入输出都是以流的形式保存的,流中保存的实际上全部是字节文件。

3.2、字节流与字符流

在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Write类完成,输入主要是使用Reader类完成。

内容操作就四个类:OutputStream、InputStream、Writer、Reader

操作流程:
A、使用File类打开一个文件
B、通过字节流或字符流的子类,指定输出的位置
C、进行读/写操作
D、关闭输入/输出

3.3、字节流

字节流主要是操作byte类型数据,以byte数组为准,主要操作类就是OutputStream、InputStream。

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

Byte是字节,肯定使用字节流操作。所有的数据基本上都可以直接使用byte数组表示出来。

3.3.1、字节输出流:OutputStream

OutputStream类

outputStream是整个io包中字节输出流的最大父类,此类的定义如下:

public abstract class OutputStream extends Object implements Closeable,Flushable

Closeable表示可以关闭的操作,因为程序运行到最后肯定要关闭。
Flushable表示刷新,清空内存中的数据。

OutputStream类的常用方法:

No.    方法或变量                            描述
1    public void close() throws IOException                关闭输出流
2    public void flash() throws IOException                刷新缓冲区
3    public void write(byte[] b) throws IOException            将一个byte数组写入数据流
4    public void write(byte[] b,int off,int len) throws IOException    将一个指定范围的byte数组写入数据流
5    public abstract void write(int b) throws IOException        将一个字节数据写入数据流


要想使用以上方法,必须使用子类实例化,此时使用FileOutputStream子类,此类的构造方法如下:

public FileOutputStream(File file) throws FileNotFoundException

import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
    public static void main(String args[])throws Exception{
        //第一步、使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //第二步、通过子类实例化父类对象
        OutputStream out = null;
        out = new FileOutputStream(f);
        //第三步、进行写操作
        String str = "Hello World!!!";
        byte b[] = str.getBytes();
        out.write(b);
        //第四步、关闭输出流
        out.close();
    }
}



在操作的时候,如果文件本身不存在,则会为用户自动创建新文件。
在操作输出流的时候,也可以使用write(int i)的方法写出数据。


import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
    public static void main(String args[])throws Exception{
        //第一步、使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //第二步、通过子类实例化父类对象
        OutputStream out = null;
        out = new FileOutputStream(f);
        //第三步、进行写操作
        String str = "Hello World!!!";
        byte b[] = str.getBytes();
        for(int i=0;i<b.length;i++){
            out.write(b[i]);    //每次只写一个字节内容
        }
        //第四步、关闭输出流
        out.close();
    }
}


以上操作中在写入数据后,文件之前的内容已经不存在了,因为在IO操作中默认的情况是将其内容覆盖的,那么如果现在想要执行追加的功能,则必须设置追加操作,找到FileOutputStream类。

构造方法:
public FileOutputStream(File file,boolean append) throws FileNotFoundException


import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
    public static void main(String args[]) throws Exception{
        //第一步、使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //第二步、通过子类实例化父类对象
        OutputStream out = null;
        out = new FileOutputStream(f,true);
        //第三步、进行写操作
        String str = "Hello World!!!";
        byte b[] = str.getBytes();
        for(int i=0;i<b.length;i++){
            out.write(b[i]);    //每次只写一个字节内容
        }
        //第四步、关闭输出流
        out.close();
    }
}



如果在文件操作中想换行的话,使用"\r\n"完成。

import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
    public static void main(String args[])throws Exception{
        //第一步、使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //第二步、通过子类实例化父类对象
        OutputStream out = null;
        out = new FileOutputStream(f,true);
        //第三步、进行写操作
        String str = "\r\nHello World!!!";
        byte b[] = str.getBytes();
        for(int i=0;i<b.length;i++){
            out.write(b[i]);    //每次只写一个字节内容
        }
        //第四步、关闭输出流
        out.close();
    }
}



3.3.2、字节输入流:InputStream

定义格式:
public abstract class InputStream extends Object implements Closeable

构造方法:
public FileInputStream(File file) throws FileNotFoundException

InputStream类的常用方法
No.    方法或常量                    描述
1    public int available() throws IOException    可以取得输入文件的大小
2    public void close() throws IOException        关闭输入流
3    public abstract int read() throws IOException    读取内容,以数字的方式读取
4    public int read(byte[] b) throws IOException    将内容读到byte数组之中,同时返回读入的个数。

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
    public static void main(String[] args)throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        InputStream input = null;
        input = new FileInputStream(f);
        //3.进行读操作
        byte b[] = new byte[1024];
        input.read(b);
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(b));    //将byte数组变为字符串输出
    }
}


输出:
内容为:Hello World!!!Hello World!!!
Hello World!!!





此时内容虽然读取出来了,但是可以发现存在的问题。

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
    public static void main(String[] args)throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        InputStream input = null;
        input = new FileInputStream(f);
        //3.进行读操作
        byte b[] = new byte[1024];
        int len = input.read(b);
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(b,0,len));    //将byte数组变为字符串输出
    }
}


能不能根据文件的大小来开辟数组空间呢?
直接使用File类即可:public long length()

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
    public static void main(String[] args)throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        InputStream input = null;
        input = new FileInputStream(f);
        //3.进行读操作
        byte b[] = new byte[(int)f.length()];
        int len = input.read(b);
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(b));    //将byte数组变为字符串输出
    }
}




以上是直接使用byte数组的方式完成的。
现在使用public abstract int read() throws IOException读取内容

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
    public static void main(String[] args)throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        InputStream input = null;
        input = new FileInputStream(f);
        //3.进行读操作
        byte b[] = new byte[(int)f.length()];
        for(int i=0;i<b.length;i++){
            b[i] = (byte)input.read();
        }
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(b));    //将byte数组变为字符串输出
    }
}



以上的操作,只适合于知道输入流大小的时候,如果现在不知道大小呢?

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
    public static void main(String[] args)throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        InputStream input = null;
        input = new FileInputStream(f);
        //3.进行读操作
        byte b[] = new byte[1024];
        int len = 0;
        int temp = 0;
        //以下代码颜色加深标记
        while((temp = input.read())!=-1){
            b[len] = (byte)temp;
            len++;
        }
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(b,0,len));    //将byte数组变为字符串输出
    }
}


当不知道读取内容有多大的时候,就只能以读取的数据是否为-1做为读完的标志。

3.4、字符流

在程序中一个字节等于2个字节,那么java提供了Reader、Writer两个专门操作字符流的类。
字符输出流Writer
字符输入流Reader


3.4.1、字符输出流:Writer
Write本身是一个字符流的输出类,此类的定义如下:

public abstract class Writer extends Object implements Appendable,Closeable,Flushable

构造方法:

public FileWriter(File file) throws IOException

Writer类的常用方法

No.    方法或常量                        描述
1    public abstract void close() throws IOException        关闭输出流
2    public void write(String str) throws IOException    将字符串输出
3    public void write(Char[] char) throws IOException    将字符数组输出
4    public abstract void flush() throws IOException        强制性清空缓存

字符流的操作比字节流操作好在一点,就是可以直接输出字符串了。不用再像之前那样进行转换操作了。

import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
    public static void main(String args[])throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Writer out = null;
        out = new FileWriter(f);
        //3.进行写操作
        String str = "Hello World!!!";
        out.write(str);
        //4.关闭输出流
        out.close();
    }
}


FileWriter增加追加标识

import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
    public static void main(String args[])throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Writer out = null;
        out = new FileWriter(f,true);
        //3.进行写操作
        String str = "\r\nLixinghuaHello World!!!";
        out.write(str);
        //4.关闭输出流
        out.close();
    }
}



3.4.2、字符输入流Reader
字符输入流:Reader

定义格式:
public abstract class Reader extends Object implements Readable,Closeable

Reader本身也是抽象类地,如果现在要从文件中读取内容,则可以直接使用FileReader子类。

FileReader的构造方法:
public FileReader(File file) throws FileNotFoundException

Reader类的常用方法:
No.    方法或常量                    描述
1    public abstract void close() throws IOException    关闭输出流
2    public int read() throws IOException        读取单个字符
3    public int read(char[] cbuf) throws IOException 将内容读到字符数组之中,返回读入的长度

以字符数组的形式读取出数组

import java.io.File;
import java.io.Reader;
import java.io.FileReader;
public class ReaderDemo01{
    public static void main(String args[])throws Exception{
        //1.使用File类找到一个文件    
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Reader input = null;
        input = new FileReader(f);
        //3.进行读操作    
        char c[] = new char[1024];    //记住这里的char是小写
        int len = input.read(c);//形同FileinputStream的read()方法
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(c,0,len));
    }
}


可以使用循环的方式,通过文件是否读到低的形式读取。

import java.io.File;
import java.io.Reader;
import java.io.FileReader;
public class ReaderDemo01{
    public static void main(String args[]) throws Exception{
        //1.使用File类找到一个文件    
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Reader input = null;
        input = new FileReader(f);
        //3.进行读操作
        char c[] = new char[1024];
        int len=0;
        int temp=0;
        while((temp=input.read())!=-1){
            c[len] = (char)temp;
            len++;
        }
        //4.关闭输出流
        input.close();
        System.out.println("内容为:"+new String(c,0,len));
    }
}



3.5、字节流与字符流的区别

字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有那些不同呢?

通过一段代码来验证字符流使用到了缓存。


import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
    public static void main(String args[]) throws Exception{
        //第一步、使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //第二步、通过子类实例化父类对象
        OutputStream out = null;
        out = new FileOutputStream(f);
        //第三步、进行写操作
        String str = "Hello World!!!";
        byte b[] = str.getBytes();
        out.write(b);
        //第四步、关闭输出流
        //out.close();
    }
}


在使用字节流操作中,即使没有关闭,最终也是可以输出的。

import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
    public void main(String args[])throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Writer out = null;
        out = new FileWriter(f,true);
        //3.进行写操作
        String str = "\r\nLixinghuaHello World!!!";
        out.write(str);
        //4.关闭输出流
        //out.close();
    }
}


以上的操作,没有输出任何的内容出来,也就是说,所有的内容现在都是保存在了缓冲区之中,而如果执行关闭的时候会强制性的刷新缓冲区,所以可以把内容输出。

如果现在假设,没有关闭的话,也可以手工强制性调用刷新方法。

public abstract void flush() throws IOException


import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
    public void main(String args[])throws Exception{
        //1.使用File类找到一个文件
        File f = new File("d:"+File.separator+"test.txt");
        //2.通过子类实例化父类对象
        Writer out = null;
        out = new FileWriter(f,true);
        //3.进行写操作
        String str = "\r\nLixinghuaHello World!!!";
        out.write(str);
        //4.关闭输出流
        out.flush();
        //out.close();
    }
}


问题:  开发中是使用字节流好还是字符流好?
    所有的硬盘上保存文件或是进行传输的时候都是以字节的方式进行的。包括图片也是按字节完成,而字符是只有在内存中才会形成,所以使用字节的操作是最多的。

3.6、操作范例

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

e421083458

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值