java字节流与字符流

字节输出流——OutputStream(程序——>文件)

OutputStream是一个抽象类,需要子类来初始化实例。已知直接子类有FileOutputStream。

除了close()和flush()方法(任何涉及流的操作都需要关闭close),Outputstream的写入输出流(byte字节或byte数组->输出流->文件)有三个重载方法:

  • public abstract void write(int b) throws IOException:一次只写入一个字节
  • public void write(byte[] b) throws IOException:一次写入整个字节数组
  • public void write(byte[] b, int off, int len) throws IOException:一次写入从off开始,长度为len的字节数组

FileOutputStream的两个常用的构造方法:

  • public FileOutputStream(File file) throws FileNotFoundException:调用此构造方法每此写入的输出流会覆盖原有文件
  • public FileOutputStream(File file, boolean append) throws FileNotFoundException:调用此构造方法每次会在原有文件末尾追加内容,不覆盖原有文件 

1.一次只向输出流写入一个字节,每次覆盖原有文件

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("d:" + File.separator + "test2.txt");
        //倘若父目录不存在,则创建所有这条路径上必须的父目录
        if (!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        //倘若文件不存在,则会创建一个新的空文件
        //覆盖原有文件
        OutputStream outputStream=new FileOutputStream(file);
        //每次在末尾追加内容,不覆盖原有文件
//        OutputStream outputStream=new FileOutputStream(file,true);
        String str="你好,world\r\n";//\r\n在文件中表示换行,共占两个字节
        //采用默认编码将字符串转化为字节数组,我默认用utf-8
        // 在中文平台下,如果指定的字符集编码是UTF-8,那么按照UTF-8对中文的编码规则:每个中文用
        //3个字节表示
        byte[] bytes=str.getBytes();
        for (int i=0;i<bytes.length;i++){
            outputStream.write(bytes[i]);
        }//一个一个字节输出
//        outputStream.write(bytes);//一整个字节数组输出
//        outputStream.write(bytes,3,5);//部分字节数组输出
        outputStream.close();//流的操作都要在最后关闭
    }
}

运行结果:(打开text.txt文件)

你好,world

2.调用outputstream.write(bytes)与上面的运行结果相同。

3.调用outputstream.write(bytes,1,4)运行结果:(打开text.txt文件)

好,w

4.text.txt文件不去改动,调用new FileOutputStream(file,true)构造方法初始化,outputstream.write(bytes)写入输出流,执行三次后,文件会在末尾追加三次内容,运行结果:(打开text.txt文件)

好,w你好,world
你好,world
你好,world

 

字节输入流——InputStream(文件——>程序)

InputStream也是一个抽象类,它也需要子类来实例化。我们这里主要讲解它的直接子类FileInputStream。InputSteam也有close()方法,但没有flush()。而且相对应的,InputStream也有三个重载的读取方法(文件->输出流->byte数组):

  • public abstract int read() throws IOException:一次只读取一个字节,返回读取的字节值,若流已经到底读取完了,则返回-1
  • public int read(byte[] b) throws IOException:一次最多读取数组b的长度,返回读取的字节数,若流已经到底读完了,则返回-1
  • public int read(byte[] b, int off, int len) throws IOException:一次最多读取从off开始,长度为len的字节数组b,返回读取的字节数,若流已经到底读完了,则返回-1

FileInputStream的一个常用构造方法,它没有像OutputStream那样有追加内容的另一个构造方法:

示例:用第一种方法将文件中的数据读取到一个byte数组

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

        File file=new File("J:"+File.separator+"coding"+File.separator+"test"+File.separator+"test.txt");
        if(file.exists()){
            InputStream inputStream=new FileInputStream(file);
            byte[] bytes=new byte[1024];//用来存放从文件中读取的数据
            int count=0;
            int temp=0;
//          inputStream.read(bytes); 第二种方法
            while ((temp=inputStream.read())!=-1){//第一种方法:每次读取一个字节,并赋值给temp
                bytes[count++]=(byte) temp;
            }
            inputStream.close();//关闭输入流
            //输出结果可以看出count的作用
            System.out.println("["+new String(bytes,0,count)+"]");
            System.out.println("**********************************************");
            System.out.println("["+new String(bytes)+"]");
            System.out.println("***********************************************");
        }

    }
}

运行结果: 

[你好,world!
I miss you

我想你

但

我错过你了]
**********************************************
[你好,world!
I miss you

我想你

但

我错过你了                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ]
***********************************************

 

字符输出流——Writer(程序——>文件)

Writer也是一个抽象类,需要子类来初始化实例。这里我们使用它的子类FileWriter。

Writer类 也有close()和flush()方法,除此之外,Writer类还有重载的五个写的方法等其他方法,举例两个:

  • public void write(char[] cbuf) throws IOException:一次写入整个字符数组
  • public void write(String str) throws IOException:一次写入整个字符串

和FileOutputStream一样,FileWriter也有两个常用的构造方法:

  • public FileWriter(File file) throws FileNotFoundException:调用此构造方法每此写入的输出流会覆盖原有文件
  • public FileWriter(File file, boolean append) throws FileNotFoundException:调用此构造方法每次会在原有文件末尾追加内容,不覆盖原有文件 

示例:将字符串写入文件

public class Test {
    public static void main(String[] args) throws IOException {
        File file=new File("J:"+File.separator+"coding"+File.separator+"test"+File.separator+"test.txt");
        if (!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        Writer writer=new FileWriter(file);
        String str="好好学习,天天向上";
        writer.write(str);
        writer.close();//流必须要关闭,尤其是字符流,不进行close()可能会没有写到文件中

    }
}

运行结果(打开text.txt文件):

好好学习,天天向上

 

字符输入流——Reader(文件——>程序)

Reader类也是一个抽象类,这里我们使用FileReader来初始化。

Reader类和InputStream类一样,只有close()方法,没有flush()方法。Reader类有4个重载的读取数据的方法:

  • public int read() throws IOException:读取一个字符,并返回字符编码,已经读到底返回-1
  • public int read(char[] cbuf) throws IOException:读取数据到字符数组,并返回读取的字符个数,已经读到底返回-1
  • public abstract int read(char[] cbuf, int off, int len) throws IOException:读取数据到off开始长度为len的字符数组,并返回读取的字符个数,已经读到底返回-1
  • public int read(CharBuffer target) throws IOException

示例:读取文件内容到字符数组

public class Test {
    public static void main(String[] args) throws IOException {
        File file=new File("J:"+File.separator+"coding"+File.separator+"test"+File.separator+"test.txt");
        if (file.exists()){
            char[] data=new char[1024];
            int count=0;
            Reader reader=new FileReader(file);
            count=reader.read(data);
            reader.close();
            System.out.println("["+new String(data,0,count)+"]");

        }
    }
}

运行结果:

[好好学习,天天向上]

字节流与字符流的区别

字节流与字符流最大的区别是:字节流直接与终端进行数据交互,而字符流需要将数据经过缓冲区处理后才能输出。在使用OutputStream进行数据输出的时候,即使最后没有close()也能将数据正常输出到文件,但是使用Writer的话,如果最后没有关闭流,那么表示存在缓冲区的数据不会被强制清空就,所以有可能不能正常输出数据到文件。也可以用flush()强制清空缓冲区。

在开发之中对于字节数据处理是比较多的,如图片、电影、音乐、文字。所以,如果处理中文优先考虑字符流,没有中文建议使用字节流。

 

转换流——OutputStreamWriter和InputStreamReader

OutputStreamWriter和InputStreamReader分别是Writer和Reader的子类,也是FileWriter和FileReader的父类,这两个不是抽象类,主要作用是将字节流转换为字符流。它们的构造方法就能实现这样的功能:

OutputStreamWriter: 

  •  public OutputStreamWriter(OutputStream out):接收字节输出流流,返回字符输出流

InputStreamReader:

  •  public InputStreamReader(InputStream in):接收字节输入流,返回字符输出流

示例:通过OutputStreamWriter将字节输出流转换为字符输出流输出字符串内容到文件

public class Test {
    public static void main(String[] args) throws IOException {
        File file=new File("J:"+File.separator+"coding"+File.separator+"test"+File.separator+"test.txt");
        if (!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        OutputStream out=new FileOutputStream(file);
        Writer writer=new OutputStreamWriter(out);
        String str="好好学习,天天向上";
        writer.write(str);
        writer.close();//这里已经转换为字符流,所以同样的,如果不关闭,有可能不会正常输出

    }
}

运行结果(打开text.txt文件):

好好学习,天天向上

 

利用字节流进行文件拷贝

public class Test {
    public static void main(String[] args) throws IOException {
        File file=new File("J:"+File.separator+"壁纸图片"+File.separator+"1.jpg");//源文件路径
        if(!file.exists()){
            return;
        }
        File file1=new File("J:"+File.separator+"壁纸图片"+File.separator+"2.jpg");//目标文件路径
        if (!file1.getParentFile().exists()){
            file1.getParentFile().mkdirs();
        }
        InputStream in=new FileInputStream(file);
        OutputStream out=new FileOutputStream(file1);
        int count=0;
        byte[] bytes=new byte[1024];
        while ((count=in.read(bytes))!=-1){
            out.write(bytes,0,count);
        }
        in.close();
        out.close();


    }
}

运行结果:

上面的例子是开辟了一个长度为1024的byte数组进行读取和输出的,也可以一个一个字节读和输,但是那样速度会很慢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值