Java基础---IO流

IO流

IO流:存储和读取数据的解决方案,用于读写文件里的数据(可以读写文件、或者是网络中的数据…)

I:input O:output

流:像水流一样传输数据

IO流按照流向可以分为输出流和输入流:

输出流:程序->文件

输入流:文件->程序

按照操作文件的类型可以分为字节流和字符流:

字节流:可以操作所有类型的文件

字符流:只能操作纯文本文件

字节流

FileOutputStream

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。

字节输出流基本用法及步骤:

//创建字节输出对象 
细节一:参数为文件路径或者File对象都可以
细节二:如果文件不存在,会创建一个新的文件,前提是父路径存在。
细节三:如果文件存在,则会清空文件
FileOutputStream fos = new FileOutputStream("文件路径");

//写入内容
细节:write方法的参数是整数,但是写到本地文件中的内容是ASCII码上对应的字符。
 fos.write(97);
//释放资源
 fos.close();

写数据的三种方式

void write(int b );//一次写一个字节数据
void write(byte[] b);//一次写一个字节数组数据,可以使用String中的getBytes()方法快速得到byte数组
void write(byte[] b,int off,int len);//一次写一个字节数组的部分内容(off表示起始索引,len表示个数)

换行和续写操作:

换行:
    再次写出一个换行符即可。
    Windows:\r\n
    Linux:   \n.
    Mac:     \r。
    细节:
        在Windows操作系统中,Java对回车换行进行了优化。
        虽然完整的是\n\r,但是是要使用其中一个即可
        Java会底层自动补全。
    建议:
        不要省略,写全了。
续写:
    如果想要续写,打开续写开关即可,
    开关位置:创建对象的第二个参数
    默认false:表示关闭续写,此时创建对象会清空文件
    手动传递true,表示此时创建对象不会清空问价。	

FIleInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中。

字节输入流基本操作及细节:

 //创建对象
细节:
    如果文件不存在,就直接报错。
 FileInputStream fis = new FileInputStream("文件路径");
 //读取
细节1:
    一次读一个字节,读出来的是数据的ASCII码
细节2:
    读到文件末了,read返回-1.
 int a = fis.read();
 System.out.println(a);
 //释放资源
细节:
    每次使用完流后都要释放资源
 fis.close();

循环读取:

FileInputStream fis = new FileInputStream("文件路径");
int b;
while((b = fis.read)!= -1){
    System.out.print(b);
}

简单拷贝操作:

1、创建对象
FileIntputStream fis = new FileIntputStream("原文件路径");
FileOutputStream fos = new FileOutputStream("拷贝文件路径");
2、拷贝
    核心思想:边读边写
int b;
while((b = fis.read())!=-1){
    fos.wirte(b);
}
3、释放资源
    先开的最关闭
fos.close();
fis.close();
//弊端:一次只读一个字节,效率太低,耗时太久。

FileInputStream读取方法

public int read();//一次读一个字节数据
public int read(Byte[] buffer);//一次读一个字节数组数据,每次读取会尽可能把数组装满,数组长度尽量为1024的整数倍

文件拷贝改写:

1、创建对象
FileIntputStream fis = new FileIntputStream("原文件路径");
FileOutputStream fos = new FileOutputStream("拷贝文件路径");
2、拷贝
    核心思想:边读边写
Byte[] b = new Byte[1024*1024*5];
int len;
while((len = fis.read(b))!=-1){
    fos.wirte(b,0,len);
}
3、释放资源
    先开的最关闭
fos.close();
fis.close();

计算机的存储规则(汉字)(GBK):

1、在计算机中,任意数据都是以二进制的形式存储的

2、计算机中最小的存储单元是一个字节

3、ASCII字符集中,一个英文占一个字节

4、简体中文版Windows,默认使用GBK字符集

5、GBK字符集完全兼容ASCII字符集

​ 一个英文占一个字节,二进制第一位是0

​ 一个中文占两个字节,二进制高位字节的第一位是1

Unicode

Unicode字符集的UTF-8编码格式

​ ·一个英文占一个字节,二进制第一位是0,转成十进制是正数

​ ·一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数

注意:UTF-8不是字符集,而是编码规范

如何不产生乱码:

1、不要用字节流读取文本文件
2、编码解码时使用同一个码表,同一个编码方式

Java中编码的方法:

public byte[] getBytes();//使用默认方式进行编码
public byte[] getBytes(String charseName);//使用指定方式进行编码

Java中解码的方法:

String(byte[] bytes);//使用默认方式进行解码
String(byte[] bytes,charseName);//使用指定方法进行解码

字符流

字符流的底层是字节流

字符流 = 字节流+字符集

特点:

输入流:一次读一个字节,遇到中文时,一次读多个字节
输出流:底层会把数据按照指定的编译方式进行编译,再变成字节写到文件中

使用场景:对于纯文本文件的读取操作

FileReader

1、创建字符输入流对象

public FileReader(File file);//创建字符输入流关联本地文件
public FileReader(String pathname);//创建字符输入流关联本地文件
如果文件不存在直接报错

2、读取数据

public int read();//读取数据,读到末尾返回-1
public int read(byte[] buffer);//读取多个数据,读到末尾返回-1 带参=空参+强制类型转换

按字节流进行读取,读到中文,一次读多个字节,读取后解码,返回一个整数
读到文件末尾了,read方法返回-1

3、释放资源

public int close();//释放资源/关流

FileWrite

构造方法:

public FileWrite(File file);//创建字符输出流对象关联本地文件
public FileWrite(String pathname);//创建字符输出流对象关联本地文件
public FileWrite(File file,boolean append);//创建字符输出流对象关联本地文件,续写
public FileWrite(String pathname,boolean append);//创建字符输出流对象关联本地文件,续写

成员方法:

void write(int c);//写出一个字符
void write(String str);//写出一个字符串
void write(String str,int off,int len);//写出一个字符串的一部分
void write(char[] cbuf);//写出一个字符数组
void write(char[] cbuf,int off,int len);//写出一个字符数组的一部分

字符流原理解析

输入流:

1、创建字符流输入对象
    底层:关联文件,并创建缓冲区(长度为8192的字节数组);
2、读取数据
    底层:
    1、判断缓冲区中是否有数据可以读取
    2、缓冲区没有数据:就从文件中读取数据,装到缓冲区中,每次尽可能装满缓冲区,如果文件中也没有数据了,返回-1
    3、缓冲区中有数据:就从缓冲区中读取,
    	空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转为十进制返回
    	有参的read方法:把读取字节、解码、强转三步合并了,强制之后的字符放到数组中

输出流:

public void flush();//将缓冲区中的内容刷新进本地文件中

缓冲流

缓冲流提高性能的原因

·缓冲流自带长度为8192的缓冲区
·可以显著提高字节流的读写功能
·对字符流提高不明显,对字符缓冲流而言的关键点是两个独有方法

字节缓冲流

原理:底层自带了长度为8192的缓冲区提高性能

方法:
public BufferedinputStream(InputStream is);//把基本流包装成高级流,提高读取的效率
public BufferedOutputStream(InputStream is);//把基本流包装成高级流,提高写出的效率

字符缓冲流

原理:底层自带了长度为8192的缓冲区提高性能

public BufferedReader(Reader r);//把基本流变为高级流
public BufferedWriter(Writer w);//把基本流变为高级流

//特有方法
public String readLine();//读取一行数据,如果没有数据可读了,返回null,但是不会读取换行
public void newLine();//跨平台的换行

转换流

是字节流与字符流的桥梁

作用:

·字符转换输入流:InputStreamReader(字节输入流对象)
·字符转换输入流:OutputStreamReader(字节输出流对象)

1、指定字符集读写(已经淘汰)
2、字节流想要使用字符流的方法

序列化流/对象输出操作流

可以把Java中的对象写道本地文件中

构造方法:

public ObjectOutputStream(OutputStream out);//把基本流包装成高级流

成员方法:

public final void writeObject(Object obj);//把对象序列化(写出)到本地文件中去

小细节:

//使用对象输出流	将对象保存到文件中时会出现NotSerializableException异常
解决方案:需要让JavaBean类实现serializable接口
    serializable中没有抽象方法,是标记性接口
    一旦实现这个接口,就表示该类可以被序列化

反序列化流/对象输入操作流

可以把序列化到本地文件中的对象,读取到程序中来

构造方法:

public ObjectInputStream(InputStream out);//把基本流包装为高级流

成员方法:

public Object readObject();// 把序列化到本地文件中的对象,读取到程序中来

细节:需要注意给要序列化的对象进行版本号定义,否则当JavaBean中成员改变时,反序列化时会报错,抛出InvalidClassException异常

例:

private static final long serialVersionUID = -427553587245757343L;//此数据是由IDEA自动生成
//方法:
点击File->点击Settings->在最上面搜索serializable->选择serializable class without 'serialVersionUID'和Transient filed is not initialized on deserialization->点击OK,然后类名会有深色背景,点击,Alt+回车即可

如果类中某个成员不想序列化到本地文件,在该成员数据类型前嘉盛transient关键字即可

存储多个对象时,建议把他们放到集合中,再将集合序列化到本地文件

打印流

分类:打印流一般是指PrintStream和PrintWrite两类

特点:

1、打印流只操作文件的目的地,不操作数据源(只能写,不能读)

2、特有的写出方法可以实现,数据的原样写出

3、特有的写出方法可以实现自动刷新,自动换行,打印一次数据 = 写出 + 换行+刷新

字节打印流

构造方法:

public PrintStream(OutputStream/File/String);//关联字节输出流/文件/文件路径
public PrintStream(String fileName,Charset charset);//指定字符编码
public PrintStream(OutputStream out, boolean autoFlush);//默认自动刷新,字节流底层没有缓冲区,开不开自动刷新都一样
public PrintStream(OutputStream out, boolean autoFlush,String encoding);//指定字符编码并自动刷新

成员方法:

public void write(int b);//常规方法,将指定字节写出
public void println(Xxx xxx);//特有方法:打印任意数据,自动刷新,自动换行
public void print(Xxx xxx);//特有方法:打印任意数据,不换行
public void printf(String format,Object ...args);//特有方法:带有占位符的打印语句,不换行

字符打印流

构造方法:

public PrintStream(Write/File/String);//关联字符输出流/文件/文件路径
public PrintStream(String fileName,Charset charset);//指定字符编码
public PrintStream(OutputStream out, boolean autoFlush);//自动刷新,字符流有缓冲区,需要手动开启自动刷新
public PrintStream(OutputStream out, boolean autoFlush,String encoding);//指定字符编码并自动刷新

成员方法:

public void write(int b);//常规方法,将指定字节写出
public void println(Xxx xxx);//特有方法:打印任意数据,自动刷新,自动换行
public void print(Xxx xxx);//特有方法:打印任意数据,不换行
public void printf(String format,Object ...args);//特有方法:带有占位符的打印语句,不换行

解压缩流

解压的本质是把压缩包中的文件读取出来,按层级拷贝到目的地

方法:

public ZipInputStream(FileInputStream is);//创建解压流
public ZipEntry(Entry e);//创建Entry对象接收压缩包里的内容,压缩包里的内容以Entry的形式读取
public boolean toDirectory();//判断entry是否是文件夹
public Entry getNextEntry();//读取解压流中的entry对象

压缩流

方法:

public ZipOutputStream(FileOutputStream is);//创建压缩流
public putNextEntry(Entry e);//将Entry对象放到压缩流中
  • 21
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值