IO流
- 1、前置知识 字符集
- 1.1 标准ASCII
- 1.2 GBK编码
- 1.3 UTF-32
- 1.4 UTF-8
- 1.5 编码和解码方法
- 2、IO流
- 2.1 流的分类
- 2.2 FileInputStream
- 2.2.1 常用方法
- 2.3 FileOutputStram
- 2.3.1 常用方法
- 2.3.2 文件复制案例
- 2.4 释放资源的方式
- 2.4.1 try-catch-finally
- 2.4.2 try-with-resource
1、前置知识 字符集
1.1 标准ASCII
每个字符一个字节,共128个字符,00000000-01111111(第一位都是0
1.2 GBK编码
一个中文字符占两个字节,兼容了ASCII编码。
英文,符号数字等仍然是一个字节,每个汉字的第一位都是1。
1.3 UTF-32
每个字符占四个字节,但是这样太浪费空间了。
1.4 UTF-8
可变编码。汉字占3个字节,数字这些占一个字节。
编码和解码要使用相同的字符集,否则会出现乱码
1.5 编码和解码方法
Java提供了常用的编码和解码方法
String data="cky崔";//1.编码byte[] bytes = data.getBytes();//使用系统默认的编码格式byte[] gbks = data.getBytes("GBK");//使用特定的字符集编码//2.解码String s = new String(bytes); //使用系统默认的格式解码System.out.println(s);//cky崔String gbk1 = new String(gbks);System.out.println(gbk1);//cky�� 乱码 因为我们使用GBK进行编码,但是却用UTF-8进行解码String gbk = new String(gbks, "GBK");//使用特定的格式解码System.out.println(gbk);
2、IO流
2.1 流的分类
2.2 FileInputStream
文件字节输入流,是InputStream 字节输入流这个抽象类的一个实现类,可以把文件磁盘中的数据以字节的形式传输到内存中
2.2.1 常用方法
①read() 每次读取一个字节 并返回该字节的int值 如果没有数据了 返回-1
②每次读取一个字节 性能差 因为IO会利用硬件资源 时间慢 且一次读取一个字节,读取中文时 会乱码
③每次读取多个字节 返回读取的字节数 这里每次读取3个字节
④这种一次读取多个字符,虽然性能得到了提升,但是读取中文时还是会出现乱码问题
package com.cky.file;import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;public class Endecode {public static void main(String[] args) throws Exception {// 1、创建字节文件输入流的管道 以及它要连通的文件
// InputStream fileInputStream = new FileInputStream(new File("E:\\java_code\\project\\hello-app\\a.txt"));//简化写法 直接写路径即可 没必要new一个文件对象InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");int c;//read() 每次读取一个字节 并返回该字节的int值 如果没有数据了 返回-1
// while((c=fis.read())!=-1){
// System.out.print((char)(c));
// }//每次读取一个字节 性能差 因为IO会利用硬件资源 时间慢 且一次读取一个字节,读取中文时 会乱码//每次读取多个字节 返回读取的字节数 这里每次读取3个字节//这种一次读取多个字符,虽然性能得到了提升,但是读取中文时还是会出现乱码问题byte[] bytes = new byte[3];int len; //读取的内容保存在bytes数组中 该数组会重复利用while((len=fis.read(bytes))!=-1){//读取多少 倒出多少String s = new String(bytes,0,len); //最后可能并不会读取刚刚好的字符,这里我们只用解码刚好读入的字节数就可以,如果没有读满,然后全部解码,就会出现内容不一致System.out.print(s);}fis.close();//释放资源}}
将文件的全部内容一次读取如果文件很大,则无法操作
方法1
//简化写法 直接写路径即可 没必要new一个文件对象InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");//使用文件字节输入流 一次读取文件全部字节File file = new File("E:\\java_code\\project\\hello-app\\a.txt");long len=file.length(); //文件是系统资源 存放在硬盘中 可能会很大 所以是long类型byte[] bytes = new byte[(int)len]; //因为是要将文件内容 读取到内容中 内存空间有限 所以都是int类型int read = fis.read(bytes);String s = new String(bytes);System.out.println(s);fis.close();//释放资源
方法2
InputStream fis = new FileInputStream("E:\\java_code\\project\\hello-app\\a.txt");byte[] bytes = fis.readAllBytes();String s = new String(bytes);System.out.println(s);fis.close();//释放资源
2.3 FileOutputStram
文件字节输出流
2.3.1 常用方法
package com.cky.file;import java.io.*;
import java.nio.charset.StandardCharsets;public class Endecode {public static void main(String[] args) throws Exception {// 构建文件字节输出流对象 并且确定与哪个文件相连//该文件可以不存在 如果不存在 会自动创建//默认会覆盖原来的文件 会先清空再写 每次创建一次流对象均是如此//如果想要追加,在后边添加true
// OutputStream fileOutputStream = new FileOutputStream("D:/a.txt");OutputStream fileOutputStream = new FileOutputStream("D:/a.txt",true);fileOutputStream.write(97);//一次添加一个字节fileOutputStream.write('a');byte[] bytes = "abc崔".getBytes();//一次添加多个字节fileOutputStream.write(bytes);fileOutputStream.write("\r\n".getBytes()); //"\r\n" 可以适应各个系统 \n只适用于windowsfileOutputStream.close();//释放资源}}
2.3.2 文件复制案例
package com.cky.file;import java.io.*;
import java.nio.charset.StandardCharsets;public class Endecode {public static void main(String[] args) throws Exception {//照片复制//1、创建一个文件输入流 与原文件相连InputStream inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");//2、创建一个文件输出流 与复制文件 相连OutputStream outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");//创建一个字符数组 用于缓存我们读取到的数据byte[] bytes = new byte[1024];int len;//用于记录我们读取到了多少 字节数据while ((len=inputStream.read(bytes))!=-1){//读多少 写多少outputStream.write(bytes,0,len);}outputStream.close();inputStream.close();System.out.println("复制成功");}}
2.4 释放资源的方式
2.4.1 try-catch-finally
//最后要释放资源 防止在未释放资源之前 发生异常
//在释放资源之前先要判断是否为空 防止在未创建之前 发生异常
package com.cky.file;import java.io.*;
import java.nio.charset.StandardCharsets;public class Endecode {public static void main(String[] args) throws Exception {//最后要释放资源 防止在未释放资源之前 发生异常 InputStream inputStream=null;OutputStream outputStream=null;try {//1、创建一个文件输入流 与原文件相连inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");//2、创建一个文件输出流 与复制文件 相连outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");//创建一个字符数组 用于缓存我们读取到的数据byte[] bytes = new byte[1024];int len;//用于记录我们读取到了多少 字节数据while ((len=inputStream.read(bytes))!=-1){//读多少 写多少outputStream.write(bytes,0,len);}outputStream.close();inputStream.close();System.out.println("复制成功");} catch (IOException e) {e.printStackTrace();}finally {//先要判断是否为空 防止在未创建之前 发生异常if (inputStream!=null)inputStream.close();if (outputStream!=null)outputStream.close();}}}
2.4.2 try-with-resource
这种更简洁
会自动释放资源
为了说明会自动调用 close方法 这里我们自己定义了一个资源
package com.cky.file;public class Myresource implements AutoCloseable {@Overridepublic void close() throws Exception {System.out.println("close方法被执行");}
}
package com.cky.file;import java.io.*;
import java.nio.charset.StandardCharsets;public class Endecode {public static void main(String[] args) throws Exception {//最后要释放资源 防止在未释放资源之前 发生异常try ( InputStream inputStream=new FileInputStream("C:\\Users\\10945\\Desktop\\a\\11.jpg");//这里只能放置资源对象//什么是资源?资源 会实现AutoCloseable接口 并且会有一个close方法。//用完之后会自动调用close 方法OutputStream outputStream=new FileOutputStream("C:\\Users\\10945\\Desktop\\15.jpg");Myresource myresource=new Myresource()){byte[] bytes = new byte[1024];int len;//用于记录我们读取到了多少 字节数据while ((len=inputStream.read(bytes))!=-1){//读多少 写多少outputStream.write(bytes,0,len);}System.out.println("复制完成");} catch (IOException e) {e.printStackTrace();}}}
结果:
复制完成
close方法被执行