Java笔记 —— IO(概念,方法,实例)(1)

在这里插入图片描述

在原来内容的后面追加,而不是覆盖原有的内容

字节缓冲输入流 BufferedInputStream

在我们之前用InputStream读取文件中的数据的时候就发现,用一个字节数组取读取,比每次单个读取一个个的字节要高效快速很多。这种思想被java用到了字节缓冲流里面,缓冲流的存在就是先将数据读取到缓冲流(内存中),然后一次性从内存中读取多个字符,从而提高读取的效率。

这里实际上用到了装饰者模式,详细内容可以看这篇博客

Java IO流之FilterInputStream和FilterOutputStream分析

BufferedInputStream本质上是通过一个内部缓冲区数组实现的。当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

构造方法:

  1. BufferedInputStream(InputStream in)

  2. BufferedInputStream(InputStream in, int size) 指定缓冲区大小size

这里的InputStream in参数,在创建对象时实际传入的是InputStream的具体实现类

package review.IO;

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.IOException;

public class Demo4 {

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

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(“a.txt”));

int len = 0;

byte[] bytes = new byte[1024];

while((len=bis.read(bytes))!=-1){

String s = new String(bytes,0,len);

System.out.println(s); //读取结果为abcdefg

}

bis.close();

}

}

字节缓冲输出流 BufferedOutputStream

flush()的作用:刷新缓冲区,将缓冲区的内容写入到文件中

flush()与close()的区别:

1、close()方法调用是关闭流对象,但是呢,会先刷新一次缓冲区,关闭之后,就不能继续使用该流对象了

2、flush()方法调用后,刷新一次缓冲区,但是流对象可以继续使用

使用缓冲输出流往文件里面写入数据的时候,flush和close至少有一个才能将数据写入文件,否则数据将一直存在缓冲区,直到缓冲区满,然后自动写入

package review.IO;

import java.io.BufferedOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class Demo5 {

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

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(“b.txt”));

bos.write(“你好,hello”.getBytes());

//flush将缓冲区里面的内容直接输出,而不用等待缓冲区满

bos.flush();

bos.close();

}

}

转换流

当文件内容中有中文的时候,如果我们只读取一个字节,然后输出这个字节,就会发现输出的结果是乱码

在这里插入图片描述

package review.IO;

import java.io.FileInputStream;

import java.io.IOException;

public class Demo6 {

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

FileInputStream fis = new FileInputStream(“a.txt”);

int b = 0;

while((b=fis.read())!=-1){

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

}

}

}

读取的结果为

在这里插入图片描述

是一串乱码,这是因为中文占用的字节数不止一个,多个字节才能组成一个中文汉字。如果单独拆出一个字节,就会发现输出的就是乱码

正因为这样,字节流操作中文很不方便,所以需要用到字符流

字符流是建立在字节流之上的,它能够提供字符层次的编码和解码

转换流为我们建立了字节流到字符流的桥梁,其本身是一种处理流,提供了字节流和字符流之间的转换。

Java中提供了两个转换流:InputStreamReader 和 OutputStreamWriter,这两个类都属于字符流。

InputStreamReader将字节输入流转为字符输入流,继承自Reader。

OutputStreamWriter是将字符输出流转为字节输出流,继承自Writer。

在计算机中是以二进制的形式存储的数据,我们实际看到的文字信息都是讲二进制数据转换之后显示而来的。这两者之间存在着一种编码与解码的关系。

编码:类似与加密的过程,把能看懂的字符或字符串转成看不懂的字节。 String – byte[]

解码:类似于解密的过程,把看不懂的字节转成看得懂的字符或字符串。 byte[] – String

字符流其实可以理解为转换流。字符流=字节流+编码表。

package review.IO;

import java.io.IOException;

import java.util.Arrays;

public class Demo7 {

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

String s = “你好世界”;

//byte[] getBytes(Charset charset)

//使用给定的charset将该String编码为字节序列,将结果存储到新的字节数组中。

//String – byte[]

byte[] bytes =s.getBytes(“UTF-8”);

System.out.println(Arrays.toString(bytes));

//String(byte[] bytes, Charset charset)

//构造一个新的String由指定用指定的字节的数组解码charset

//byte[] – String

String ss = new String(bytes,“UTF-8”);

System.out.println(ss);

}

}

结果为

在这里插入图片描述

括号里面的UTF-8可以换成Unicode或者GBK等都可以,但是要注意编码和解码用的charset编码表要一样

字符输出流 OutputStreamWriter(字符转换流)

OutputStreamWriter写数据方法

public void write(int c)

public void write(char[] cbuf)

public void write(char[] cbuf,int off,int len)

public void write(String str)

public void write(String str,int off,int len)

注意:从字符流开始,一次性读取一个字符数组,而不是一个字节数组。用char[] 数组

package review.IO;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

public class Demo8 {

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

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“b.txt”));

//write(int c)

osw.write(97); //a

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

char[] chars = {‘a’,‘b’,‘c’,‘d’,‘e’};

osw.write(chars); //abcde

//write(char[] cbuf,int off,int len) 将字符数组中的一部分写到文件中

char[] chars1 = {‘a’,‘b’,‘c’,‘d’,‘e’};

//从下标1开始读取两个字符

osw.write(chars1,1,2); //bc

//write(String str) 将字符串写入到文件中

osw.write(“hello”); //hello

//write(String str,int off,int len) 将字符串的一部分写入到文件中

String s2 = “hadoop”;

osw.write(“hadoop”,1,2); //ad

osw.flush();

osw.close();

}

}

字符输入流 InputStreamReader
  1. InputStreamReader(InputStream in)

读取数据,根据默认的编码将字节流转换为字符流

创建一个使用默认字符集的InputStreamReader。

  1. InputStreamReader(InputStream in, String charsetName)

读取数据,根据指定的编码将字节流转换为字符流

创建一个使用指定字符集的InputStreamReader。

读取数据的方法:

  1. public int read():一次只读一个字符

  2. public int read(char[] cbuf):一次读取一个字符数组

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

public class Demo9 {

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

//InputStream in = new FileInputStream("a.txt)

InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”));

//一次只读取一个字符

int ch = 0;

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

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

}

isr.close();

}

}

结果为

在这里插入图片描述

可以发现控制台这里输出的是中文字符,而不再是int类型的数字

public class Demo9 {

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

//InputStream in = new FileInputStream("a.txt)

InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”));

//一次读取多个字符,也就是读取一个字符数组

char[] chars = new char[1024];

int len = 0;

while((len=isr.read(chars))!=-1){

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

}

isr.close();

}

}

在这里插入图片描述

字符转换流的简便写法

字符流 = 字节流 + 编码表

OutputStreamWriter = FileOutputStream + 编码表(Unicode)

InputStreamReader = FileInputStream + 编码表(Unicode)

字符输出流 OutputStreamWriter 简便写法 FileWriter

字符输入流 InputStreamReader 简便写法 FileReader

package review.IO;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class Demo11 {

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

FileReader fr = new FileReader(“a.txt”);

FileWriter fw = new FileWriter(“b.txt”);

int len = 0;

char[] chars = new char[1024];

while((len=fr.read(chars))!=-1){

fw.write(chars,0,len);

fw.flush();

}

fw.close();

fr.close();

}

}

结果成功将a.txt里面的内容写入到b.txt里面

注意:当程序中有多个流需要关闭的时候,按照从下到上的顺序关闭。

比如这里先打开的fr,后打开的fw。关闭的时候则先关fw后关fr

字符缓冲输入流 BufferedReader

字符流为了高效读写,也提供了相对应的字符缓冲流

BufferedWriter:字符缓冲输出流

BufferedReader:字符缓冲输入流

BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。

package review.IO;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

public class Demo10 {

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

BufferedReader br = new BufferedReader(new FileReader(“a.txt”));

//一、一次读取一个字符

int ch = 0;

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

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

}

//二、一次读取一个字符数组

int len = 0;

char[] chars = new char[1024];

while((len=br.read(chars))!=-1){

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

}

br.close();

}

}

结果分别是(注意两段代码要分开运行,否则第二段代码读取内容为空,这里是为了直观所以放在了一起)

在这里插入图片描述

在这里插入图片描述

字符缓冲输出流 BufferedWriter

BufferedWriter:字符缓冲输出流

将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。

可以指定缓冲区大小,或者可以接受默认大小。

默认值足够大,可用于大多数用途。

创建方式:

  1. BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流

  2. BufferedWriter(Writer out, int sz) 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

package review.IO;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

public class Demo12 {

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

/*

BufferedWriter bw = new BufferedWriter(

new OutputStreamWriter(new FileOutputStream("b.txt)));

这是原来的写法,实在复杂,需要创建一个字节输出流FileOutputStream

然后用OutputStreamWriter将字节输出流转为字符输出流

再将字符输出流添加上缓冲区的功能变成BufferedWriter

*/

BufferedWriter bw = new BufferedWriter(new FileWriter(“b.txt”));

bw.write(97); //a

bw.write(98); //b

bw.write(“hello”); //hello

bw.write(“hadoop”,1,2); //ad

char[] chars = {‘a’,‘b’,‘c’,‘d’};

bw.write(chars); //abcd

bw.write(chars,1,2); //bc

bw.flush();

bw.close();

}

}

特殊方法

字符缓冲流的特殊方法:

BufferedWriter —— public void newLine()写一行行分隔符,用于换行

BufferedReader —— public String readLine()读一行文字,到换行符终止,然后转而读取下一行

package review.IO;

import java.io.*;

public class Demo13 {

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

write();

read();

}

public static void read() throws IOException{

BufferedReader br = new BufferedReader(new FileReader(“a.txt”));

String line = null;

//(line=br.readLine())每次读取文件的一行给line,然后执行while循环体中的打印语句

//所以每次打印一行内容

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

System.out.println(line);

}

br.close();

}

public static void write() throws IOException{

BufferedWriter bw = new BufferedWriter(new FileWriter(“b.txt”));

for(int i=0;i<10;i++){

bw.write(“学习大数据的第 “+i+” 天”);

//newLine()每写完一句就换到下一行

bw.newLine();

bw.flush();

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。

最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。

面试了阿里,滴滴,网易,蚂蚁,最终有幸去了网易【面试题分享】

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-Wt5QzYCW-1713171354629)]

[外链图片转存中…(img-7Lpc9zBJ-1713171354629)]

[外链图片转存中…(img-nI20IOcR-1713171354629)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。

最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。

[外链图片转存中…(img-1IIIn6T0-1713171354630)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 16
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值