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只适用于windows
fileOutputStream.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 {
@Override
public 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方法被执行