计算机上数据的传输可以看做是一种数据的流动 按照流动的方向 以内存为基准 分为 输入input 和 输出output
即 流向内存是输入流 流出内存的输出流
流:数据(字符 字节)
1个字符=2个字节 1个字节=8个二进制位
Java中I/O操作是使用 java.io
包下的内容进行输入输出操作
一切文件数据(文本 图片 视频等)在存储时都是以二进制数字的形式保存的 都是一个一个的字节
(因为计算机只能识别0101的二进制)
在传输时一样如此 因此 字节流可以传输任意类型的文件数据
在操作流的时候 无论使用什么样的流对象 底层传输的始终为二进制数据
java.io.InputStream
抽象类是表示字节输入流的所有类的超类(父类)
可以读取字节信息到内存中
它定义了字节输入流的基本共性功能方法
InputStream有很多子类 FileInputStream是其中一个
java.io.FileInputStream
继承了InputStream
作用:将硬盘的文件中的数据读取到内存中
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个FileInputStream 该文件由文件系统中的路径名 name命名
FileInputStream(File file) : 通过打开与实际文件的连接来创建一个FileInputStream 该文件由文件系统中的File对象 file命名
参数(读取文件的数据源):
String name:文件的路径
File file:文件
构造方法内部执行流程:
1、创建一个FileInputStream对象
2、将FileInputStream对象指向构造方法中要读取的文件
读取数据的原理(硬盘–>内存):Java程序 --> JVM --> OS(操作系统) --> OS调用读取数据的方法来读取文件
字节输入流 - 使用步骤★:
1、创建FileInputStream对象 构造方法中绑定要读取的数据源
2、调用FileInputStream对象中的read()方法 读取文件
3、释放资源(流的使用会占用一定的内存 使用完毕要将内存清空 提高程序的效率)
1、读取字节: read()
方法 每次读取一个字节的数据 转换为int类型
指针默认指向第一个字节
每读取一个字节之后指针向后移动一位
当读取到文件末尾(文件末尾有一个看不见的结束标记) 则返回 -1
public static void main(String[] args) throws IOException {
// 创建FileInputStream对象 构造方法中绑定要读取的数据源
FileInputStream fis=new FileInputStream("F:\\IdeaProjects\\filetest\\a.txt");
// 调用FileInputStream对象中的read()方法 读取文件
// read()方法 每次读取一个字节的数据 提升为int类型 读取到文件末尾返回 -1
int read = fis.read();
System.out.println(read);// 97
read = fis.read();
System.out.println(read);// 98
read = fis.read();
System.out.println(read);// 99
read = fis.read();
System.out.println(read);// -1 到结尾了
// 释放资源
fis.close();
}
用循环简化步骤:
(read=fis.read())!=-1 布尔表达式:
1、fis.read():读取一个字节
2、read=fis.read():将读取到的字节赋值给变量read
3、(read=fis.read())!=-1 判断read遍历是否不等于-1
public static void main(String[] args) throws IOException {
// 创建FileInputStream对象 构造方法中绑定要读取的数据源
FileInputStream fis=new FileInputStream("F:\\IdeaProjects\\filetest\\a.txt");
// 循环优化 不知文件多少字节 因此while循环 循环到-1则结束
int read=0;
while ((read=fis.read())!=-1)
{
System.out.print((char) read);// abc
}
// 释放资源
fis.close();
}
2、使用字节数组读取: read(byte[] b)
从输入流中读取一定数量的字节 并将其存储在缓冲区数组b中
每次读取b的长度个字节到数组中 返回读取到的有效字节个数
当读取到末尾时 返回 -1
参数byte[] b的作用:起到缓冲作用 存储每次读取到的多个字节
数组长度一般定义为1024(即1kb)或1024的整数倍
返回值int的意义:每次读取的有效字节个数
在这里 需要用到类型的转换:
String(byte[] bytes):将字节数组转换为字符串
String(byte[] bytes,int offset,int length):将字节数组的一部分转换为字符串 offset:开始索引 length:个数
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("F:\\IdeaProjects\\filetest\\a.txt");
byte[] bytes=new byte[2];
int read = fis.read(bytes);
System.out.println(read);// 2 每次读取的字节个数
System.out.println(new String(bytes));// ab
read = fis.read(bytes);
System.out.println(read);// 1 每次读取的字节个数
System.out.println(new String(bytes));// cb
read = fis.read(bytes);
System.out.println(read);// -1 每次读取的字节个数
System.out.println(new String(bytes));// cb
fis.close();
}
原理:
从文件中每次读取传入的字节数组的个数的字节
读出来存放到传入的字节数组中
返回值为每次读取的有效字节
后面读取的字节会覆盖掉缓冲区数组中同样位置的字节
例如:缓冲区数组长度两位 只读取了一位字节 那么只会覆盖掉数组中第一位的字节 第二位字节保留不变
用循环简化步骤:
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("F:\\IdeaProjects\\filetest\\a.txt");
// 使用循环优化 不知道文件共有多少字节 因此使用while循环
// 结束条件:读取到-1
byte[] bytes=new byte[1024];// 存储读取到的多个字节(1kb)
int read=0;// 记录每次读取的有效字节个数
while ((read=fis.read(bytes))!=-1)
{
//String(byte[] bytes,int offset,int length):将字节数组的一部分转换为字符串 offset开始索引 length个数
// 读取完后 若读取的字节的大小少于总空间大小 则在输出读取的字节之后会输出一堆多余的空格
System.out.println(new String(bytes,0,read));
}
fis.close();
}
java.io.OutputStream
抽象类是表示字节输出流的所有类的超类(父类)
将指定的字节信息写出到目的地
它定义了字节输出流的基本共性功能方法
OutputStream有很多子类 FileOutputStream是其中一个
java.io.FileOutputStream
继承了OutputStream
作用:将内存中的数据写入到硬盘的文件中
public FileOutputStream(String name)
: 创建文件输出流以指定的名称写入文件
public FileOutputStream(File file)
:创建文件输出流以写入由指定的 File对象表示的文件
参数(写入数据的目的地):
String name:目的地是一个文件的路径
File file:目的地是一个文件
构造方法内部执行流程:
1、创建一个FileOutputStream对象
2、根据构造方法中传递的文件/文件路径来创建一个空的文件
3、将FileOutputStream对象指向创建好的文件
写入数据的原理(内存–>硬盘):Java程序 --> JVM --> OS(操作系统) --> OS调用写数据的方法将数据写入到文件中
字节输出流 - 使用步骤★:
1、创建FileOutputStream对象 构造方法中传递写入数据的目的地
2、调用FileOutputStream对象中的write()方法 将数据写入到文件中
3、释放资源(流的使用会占用一定的内存 使用完毕要将内存清空 提高程序的效率)
写数据的时候 会将十进制的整数转换为二进制的整数
因此 若输入的是97 实际上写入的并不是97 而是1100001
fos.write(1100001) 97 --> 1100001
硬盘中存储的数据都是字节
1个字节=8个比特位
任意文本编辑器在打开文件的时候 都会先查询编码表 将字节转换为字符展示出来
1、写出字节: write(int b)
方法 每次可以写出一个字节数据
public static void main(String[] args) throws IOException {
// 创建FileOutputStream对象 构造方法中传递写入数据的目的地
FileOutputStream fos=new FileOutputStream("F:\\IdeaProjects\\filetest\\a.txt");
//调用FileOutputStream对象中的write()方法 将数据写入到文件中
fos.write(97);
//释放资源
fos.close();
}
2、写出字节数组: write(byte[] b)
每次可以写出数组中的数据
若写的第一个字节是0-127的正数 则显示的时候会查询ASCII码表
若写的第一个字节是负数 则第一个字节和第二个字节组成一个中文显示 则显示的时候会查询系统默认码表
public static void main(String[] args) throws IOException {
// 创建FileOutputStream对象
FileOutputStream fos=new FileOutputStream(new File("F:\\IdeaProjects\\filetest\\b.txt"));
// 调用write(byte[] b)方法将数据写入到文件中
// byte[] bytes={78,79,80};// NOP
byte[] bytes={-78,79,80};// 睴P
fos.write(bytes);
//释放资源
fos.close();
}
3、写出指定长度字节数组: write(byte[] b, int off, int len)
每次写出从off索引开始 len个字节的数据
write(byte[] b, int off, int len)
传入参数:
int off:数组的开始索引 从0开始
int len:写几个字节
public static void main(String[] args) throws IOException {
// 创建FileOutputStream对象
FileOutputStream fos=new FileOutputStream(new File("F:\\IdeaProjects\\filetest\\c.txt"));
// 调用write(byte[] b,int off,int len)方法将字节数组的一部分写入到文件中
byte[] bytes={78,79,80};
fos.write(bytes,1,2);// OP
//释放资源
fos.close();
}
public static void main(String[] args) throws IOException {
// 创建FileOutputStream对象
FileOutputStream fos=new FileOutputStream(new File("F:\\IdeaProjects\\filetest\\c.txt"));
// 用String类的byte[] getBytes()方法将字符串转换为字节数组写入
byte[] bytes = "帅哥".getBytes();
System.out.println(Arrays.toString(bytes));// [-27, -72, -123, -27, -109, -91] 在UTF-8中 三个字节一个中文
fos.write(bytes);
//释放资源
fos.close();
}
每次程序运行 创建输出流对象 都会清空目标文件中的数据
那么 如何能够追加写新数据?
FileOutputStream提供了一个“开关”
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件
参数:
File file/String name 写入数据的目的地
boolean append:追加写开关
true:创建对象不会覆盖原文件 会继续在文件末尾追加写数据
false:创建一个新文件 覆盖原文件
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("F:\\IdeaProjects\\filetest\\c.txt",true);
fos.write("你好帅啊".getBytes());
fos.close();
}
需添加换行符号
Windows换行符:\r\n
Linux换行符:/n
OS X换行符:/r
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("F:\\IdeaProjects\\filetest\\c.txt",true);
for (int i=0;i<10;i++)
{
fos.write("你好帅啊".getBytes());
fos.write("\r\n".getBytes());
}
fos.close();
}