一、概念
1、IO 流 -- I input O output Stream
2、IO流--> 输入输出流 所谓的入和出都是相应于内存的。
txt --> java(JVM ,内存) 输入流
java代码 String a = "hello world" --> txt 输出流
3、按照传输的数据类型 分为 字节流 和 字符流
字节 --> byte = 8 bit --> 电影、音乐, 图片 -> 每一个电影以及音乐缺少一点点都可以导致整部电影播放不了,所以需要细粒度的传输。 可以表示英文的,英文的字符可以用一个字节表示
字符 --> char 两个 --> 文本的
一个字符到底等于多少字节
需求文档中经常提到某个输入框最大允许输入XX个字节,测试时我们一般认为一个占两个字节。
但其实不同的字符所占的字节是不同的。
ASCII码:
一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。
一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。如一个ASCII码就是一个字节。
UTF-8编码:
一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
Unicode编码:
一个英文等于两个字节,一个中文(含繁体)等于两个字节。
符号:
英文标点占一个字节,中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。
二、各种流的父类
字节流的两个父类:
- 字节输入流:InputStream
- 字节输出流:OutputStream
字符流的两个父类:
- 字符读入流:Reader
- 字符写出流:Writer
- 四大父类流, 都是抽象类, 都不能实例化对象。 因此, 需要借助他们的子类实现数据的读写。
- 流对象一旦实例化完成, 将建立一个程序与文件之间的连接。 这个连接会持有这个文件。 如果这个连接不断, 此时这个文件就是一个被使用中的状态, 此时将无法对这个文件进行其他的操作, 例如删除。
- 一个流在使用完成之后, 切记! 一定要进行流的关闭。
三、前期准备的知识点
1、位置问题 —你想操作的文件所在的位置
绝对路径和相对路径<br />
找老闫:
绝对路径 --> 地球\中国\河南\郑州\二七区\海为科技园\12楼8教室
相对路径 --> 你需要知道你当前的位置在哪里,老闫在哪里
王博老师--> 9教室
告诉别人: 我们班对面
2、在不同的操作系统中分隔符是不一样的
目录分隔符: windows \ linux /<br /> 路径分隔符: windows ; linux :<br /> 我们总不能还得考虑运行环境吧,于是乎java想了一个解决方案:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22131196/1647568650439-b93b548b-1edf-4252-a3f1-033a3cfe9d72.png#clientId=ua3767072-3cac-4&from=paste&id=ufc20077c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=381&originWidth=1014&originalType=binary&ratio=1&size=53054&status=done&style=none&taskId=u030cd954-c850-45ba-b788-ec750dd3b38)
package com.qfedu.day14;
import java.io.File;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 9:58
* @Version 1.0
*/
public class Demo01 {
public static void main(String[] args) {
String a = "A";
char b = 'A';
System.out.println(File.separator); // String
String str = "C:\\abc\\a.txt";
System.out.println(File.separatorChar);// char 类型
System.out.println(File.pathSeparator);
System.out.println(File.pathSeparatorChar);
}
}
3、常用类File
File常用的构造方法:
package com.qfedu.day14;
import java.io.File;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 10:02
* @Version 1.0
*/
public class Demo02 {
/**
* 学习File 类的用法
* @param args
*/
public static void main(String[] args) {
/**
* File 类的构造方法
*/
// 构造方法一: 通过一个参数创建file
File file = new File("C:\\Users\\User\\Desktop\\大数据教学大纲.txt");
System.out.println(file.exists());
File file2 = new File("C:\\Users\\User\\Desktop\\a.txt");
System.out.println(file2.exists());
// 构造方法二:根据两个参数决定一个路径
File file3 = new File("C:\\Users\\User\\Desktop","a.txt");
// 文件夹也可以是File类的实例化对象
File director = new File("C:\\Users\\User\\Desktop");
File file4 = new File(director, "a.txt");
}
}
File类的常用方法:
package com.qfedu.day14;
import java.io.File;
import java.io.IOException;
import java.util.Date;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 10:02
* @Version 1.0
*/
public class Demo03 {
/**
* 学习File 类的用法
* @param args
*/
public static void main(String[] args) throws IOException {
/**
* File 类的构造方法
*/
// 构造方法一: 通过一个参数创建file
File file = new File("C:\\Users\\User\\Desktop\\大数据教学大纲.txt");
System.out.println(file.exists());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println(file.canExecute());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isHidden());
System.out.println(file.getAbsolutePath());
System.out.println(file.getName());
System.out.println(file.getParent());
System.out.println(file.lastModified());
long time = file.lastModified();
Date date = new Date(time);
System.out.println(date);
File file2 = new File("C:\\Users\\User\\Desktop\\a.txt");
if(!file2.exists()){
file2.createNewFile();
}
file2.delete();
}
}
四、字节流操作
输入字节流
每次读取一个字节的方式,效率较低
package com.qfedu.day14;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 11:17
* @Version 1.0
*/
public class Demo06 {
public static void main(String[] args) {
// 这个地方 a.txt // 指的是classes文件夹 表现形式就是 项目目录下
try(InputStream fileInputStream = new FileInputStream("a.txt")){
// 每次读取一个字节 --> 这个字节可以读取英文的字符
// a --> 占两个字节是错误的,占一个
/**
* read() 字节流每次读取一个字节
* 如果读取到-1 说明结束了
*/
/*int read = fileInputStream.read();
System.out.println((char)read);
int read2 = fileInputStream.read();
System.out.println((char)read2);
int read3 = fileInputStream.read();
System.out.println((char)read3);
int read4 = fileInputStream.read();
System.out.println((char)read4);
int read5 = fileInputStream.read();
System.out.println((char)read5);
int read6 = fileInputStream.read();
System.out.println(read6);
System.out.println((char)-1);
System.out.println((char)-2);*/
/**
* 使用循环的方式获取字节流
*
*/
int a ;
while( (a = fileInputStream.read()) != -1){
System.out.print((char)a);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
每次读取一个数组的长度,效率高,推荐
package com.qfedu.day14;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 11:17
* @Version 1.0
*
* read 每次读取一个字节,太慢了,提升一下效率
*/
public class Demo08 {
public static void main(String[] args) {
// 这个地方 a.txt // 指的是classes文件夹 表现形式就是 项目目录下
try(InputStream fileInputStream = new FileInputStream("a.txt")){
// 拉煤的车,数组的长度就是 车的载重
byte[] bytes = new byte[2];
/* // 这个方法指的是使用一个数组去承载想要读取的数据
fileInputStream.read(bytes);
// 现在有一个byte数组,里面有数据,怎么转String
System.out.println(new String(bytes));
fileInputStream.read(bytes);
System.out.println(new String(bytes));
// read 通过数组读取,读取的个数是返回值。
fileInputStream.read(bytes);
System.out.println(new String(bytes, 0, 1));
//System.out.println(new String(bytes));*/
int num;
while( (num = fileInputStream.read(bytes)) != -1){
System.out.print(new String(bytes, 0, num));
}
}catch (Exception e){
e.printStackTrace();
}
}
}
字节输出流:
每次写一个字节:
package com.qfedu.day14;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 11:39
* @Version 1.0
*/
public class Demo07 {
public static void main(String[] args) {
try (OutputStream outputStream = new FileOutputStream("C:\\Users\\User\\Desktop\\b.txt")) {
String str = "HelloWorld";
byte[] bytes = str.getBytes();
// outputStream 有一个方法,每次写一个字节
for (byte b:bytes) {
outputStream.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
拷贝功能
package com.qfedu.day14;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 14:49
* @Version 1.0
*
* 拷贝功能
*/
public class Demo09 {
public static void main(String[] args) {
File file = new File("C:\\Users\\User\\Pictures\\mmexport1647173350471.jpg");
String name = file.getName();
try(
InputStream inputStream = new FileInputStream(file);
FileOutputStream outputStream = new FileOutputStream("D:\\"+name)
){
byte[] arr =new byte[3];
int num ;
while((num = inputStream.read(arr)) != -1){
outputStream.write(arr,0,num);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
五、字符流操作
读取文本内容:
package com.qfedu.day14;
import java.io.FileReader;
import java.io.Reader;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 15:09
* @Version 1.0
*/
public class Demo10 {
public static void main(String[] args) {
try(Reader reader = new FileReader("C:\\Users\\User\\Desktop\\b.txt")){
char[] arr = new char[8];
int num;
while((num =reader.read(arr)) != -1){
String s = new String(arr, 0, num);
System.out.print(s);
}
}catch (Exception e){
}
}
}
写入文本内容:
package com.qfedu.day14;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStream;
import java.io.Writer;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 11:39
* @Version 1.0
*/
public class Demo11 {
public static void main(String[] args) {
try (Writer writer = new FileWriter("C:\\Users\\User\\Desktop\\c.txt",true)) {
String str = "HelloWorld";
char[] bytes = str.toCharArray();
// outputStream 有一个方法,每次写一个字节
for (char b:bytes) {
writer.write(b);
}
writer.write('\n');
// 强制将缓存中的数据刷入到文件中
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
尝试使用字符流去拷贝图片,发现可以拷贝,但是打不开,拷贝失败:
package com.qfedu.day14;
import java.io.*;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/18 14:49
* @Version 1.0
*
* 拷贝功能
*/
public class Demo12 {
/**
* 字节流: 适用于 所有情况 文字\图片\视频
* 字符流: 可以用于文字的。
* @param args
*/
public static void main(String[] args) {
File file = new File("C:\\Users\\User\\Pictures\\mmexport1640224454506.jpg.jpg");
String name = file.getName();
try(
FileReader inputStream = new FileReader(file);
FileWriter outputStream = new FileWriter("D:\\"+name)
){
char[] arr =new char[10];
int num ;
while((num = inputStream.read(arr)) != -1){
outputStream.write(arr,0,num);
}
outputStream.flush();
}catch (Exception e){
e.printStackTrace();
}
}
}