1、IO概述
Java中的输入输出流–字节流
I:Input输入 从其他储存设备【读】数据到内存中 输入过程
O:Output输入 从内存中【写】数据到其他存储设备 输出过程
1.2、IO的分类
根据数据的流向分为:输入流和输出流。
- 输入流:把数据从 其他设备 上读取到 内存 中的流。
- 输出流 : 把数据从 内存 中写出到 其他设备 上的流。
格局数据的类型分为:字节流和字符流。
- 字节流 : 以字节为单位,读写数据的流。
- 字符流 : 以字符为单位,读写数据的流。
1.3、顶级父类们
1.字节输入流:顶层父类:InputStream --> 抽象类 常见子类:FileInputStream
2.字节输出流: 顶层父类:OutputStream --> 抽象类 常见子类:FileOutputStream
3.字符输入流:顶层父类:Reader --> 抽象类 常见子类:FileReader
4.字符输出流: 顶层父类:Writer --> 抽象类 常见子类:FileWriter
注意事项:
idea默认的编码格式是utf-8
utf-8编码一个中文占三个字节,GBK编码一个中文占2个字节
如果存储和解析的编码不一致,会发生乱码
2、字节流
2.1、一切皆为字节
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
2.2、OutputStream 输出流顶层父类
java.io.OutputStream 抽象类是所有【字节输出流】的父类,用来【写】处字节数据流。
public void close() : 关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() : 刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off,int len) :从指定的字节数组写入 len字节,从偏移量 off开始输0出到此输出流。
public abstract void write(int b) : 将指定的字节输出流。
OutputStream 类及其子类的对象表示一个字节输出流。OutputStream 类的常用子类如下。
- ByteArrayOutputStream 类:向内存缓冲区的字节数组中写数据。
- FileOutputStream 类:向文件中写数据。
- PipedOutputStream 类:连接到一个 PipedlntputStream(管道输入流)。
- ObjectOutputStream 类:将对象序列化。
2.3 、FileOutputStream类
概述:java.io.FileOutputStream,是OutputStream类的子类,表示字节输出流,用来写出字节数据
构造方法
- public File0utputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
- public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
注意:
1.当你创建一个字节输出流对象时,必须传入一个文件路径
2.该路径下,如果没有这个文件,会自动创建该文件(空的)
3.如果有这个文件,就会清空这个文件里的所有数据
代码如下:
package Java2;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class InputTest4 {
public static void main(String[] args) throws FileNotFoundException {
//使用File对象创建流对象
File file=new File("a.txt");
FileOutputStream fos=new FileOutputStream(file);
//使用文件名称创建流对象
FileOutputStream fos1=new FileOutputStream("b.txt");
}
}
写出字节数据
①、写出字节 : write(int b) 方法:将指定的字节写入输出流【一个字节一个字节的写入到硬盘】,代码使用演示:
package Java2;
import java.io.*;
public class OutPutTest1 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/aa");
File f2=new File(f1,"a.txt");
f1.mkdirs();
f2.createNewFile();
//使用OutPutStream输出流完成对文件的写入操作内存输出到文件
OutputStream out=new FileOutputStream(f2);
//out.write(97); //按照解析数字 写入文件中 写入的是97对应的 a
//out.write(bytes); //按照ASCII解析数组 写入文件 写入的: abcdefg
// 写出数据
out.write(97);//写出第1个字节
out.write(98);//写出第2个字节
out.write(99);//写出第3个字节
}
}
输出结果:
abc
②、写出指定长度字节数组: write(byte[] b) :将 b.length字节从指定的字节数组写入到此输出流中【以字节数组的形式写入到硬盘】,代码使用演示:
package Java2;
import java.io.*;
public class OutPutTest2 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/");
File f2=new File(f1,"a.txt");
f1.mkdirs();
f2.createNewFile();
//使用OutPutStream输出流完成对文件的写入操作内存输出到文件
OutputStream out=new FileOutputStream(f2);
//out.write(97); //按照解析数字 写入文件中 写入的是97对应的 a
byte[] bytes={97,98,99,100,101,102,103};
//out.write(bytes); //按照ASCII解析数组 写入文件 写入的: abcdefg
out.write(bytes,2,3);
}
}
输出结果:
cde
FileOutputStream类数据追加续写
public FileOutputStream(File file boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。append:如果是true,代表追加续写的意思(不会清空文件中原有的数据)
如果是false,就会清空文件中原有的数据
这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,fase 表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了,代码使用演示:
package test4;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Scanner;
public class OutPutTest02 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/减肥.txt");
f1.createNewFile();
OutputStream out=new FileOutputStream(f1);
/*Scanner sc=new Scanner(System.in);
System.out.println("请输入: ");
String msg=sc.next();*/
String msg="赶紧减肥";
byte[] bytes=msg.getBytes();//获取字符串对应解析后的byte数组
System.out.println(Arrays.toString(bytes));
out.write(bytes);//把byte数组写入文件,相当于把字符串写入文件中
out.write("\r\n".getBytes());
out.write("第二行".getBytes());
}
}
输出结果
[-24, -75, -74, -25, -76, -89, -27, -121, -113, -24, -126, -91]
写出换行
Windows系统里,换行符号是\r\n.
把以指定是否追加续写了,代码使用演示:
public class OutPutTest02 {
public static void main(String[] args) throws IOException {
File f1=new File("d:/减肥.txt");
f1.createNewFile();
OutputStream out=new FileOutputStream(f1);
String msg="赶紧减肥";
byte[] bytes=msg.getBytes();//获取字符串对应解析后的byte数组
out.write(bytes);//把byte数组写入文件,相当于把字符串写入文件中
out.write("\r\n".getBytes());
out.write("第二行".getBytes());
}
}
回车符\r和换行符\n:
- 回车符:回到一行的开头(return)。
- 换行符:下一行(newline)。
系统中的换行:
- Windows系统里,每行结尾是 回车+换行 ,即\r\n ;
- Unix系统里,每行结尾只有 换行 ,即\n ;
- Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
2.4、字节输入流【InputStream】
因为一个中文字符可能占用多个字节存储,所以Java提供了字符流类,专门来操作文本文件,以字符为单位读写数据
public void close() : 关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中。
InputStream 类及其子类的对象表示字节输入流,InputStream 类的常用子类如下:
- ByteArrayInputStream 类:将字节数组转换为字节输入流,从中读取字节。
- FileInputStream 类:从文件中读取数据。
- PipedInputStream 类:连接到一个 PipedOutputStream(管道输出流)。
- SequenceInputStream 类:将多个字节输入流串联成一个字节输入流。
- ObjectInputStream 类:将对象反序列化。
public static void main(String[] args) throws IOException {
//输出流 内存的内容输出到文件(写操作) 输入流 文件内容输入到内存中(读操作)
File f1=new File("d:/a.txt");
//创建一个输入流 读取这个文件
InputStream input=new FileInputStream(f1);
//读取文件的一个字符,然后把字符转换为对应的数字.如果读取到文件的末尾,返回的是-1
int n;
while ((n=input.read())!=-1) {
System.out.println((char) n);
}
}
2.5、FilelnputStream类
ava.io.FileInputstream 类是文件输入流,从文件中读取字节。
可以使用FileInputStream类,该类是InputStream的子类,提供了基本的文件读取功能。
FileInputStream 常用的构造方法主要有如下两种重载形式。
构造方法
- FileInputStream(File file) :使用File对象创建FileInputStream对象。
- FileInputstream(String name) : 使用给定的文件名name,创建一个FileInputStream对象
使用文件输入流读取文件
文件输入流FileInputStream提供了对文件的存取。为了读取文件,使用文件输入流构造方法来打开一个到达该文件的输入流(源就是这个文件,输入流指向这个文件)。
例如:为了读取一个名为myfile.txt的文件,建立一个文件流对象,代码如下:
FileInputStream istream=new FileInputStream(“myfile.txt”);
或者:File file=newFile(“myfile.txt””);
FileInputStream istream=new FileInputStream(file);
案例:
package test4;
import java.io.*;
public class CopyFileTest05 {
public static void main(String[] args) throws IOException {
//1.定义源文件和目的文件的文件对象
File f1=new File("D:/a.jpg");
File newFile=new File("D:/aa/copy.jpg");
//2.创建目的文件
newFile.createNewFile();
//3.定义输入输出流:使用输入流读取内容 使用输出流写入内容
InputStream in=new FileInputStream(f1);
OutputStream out=new FileOutputStream(newFile);
//练习是容易理解的方式
byte[] buffe=new byte[10];
int n=0;
while (true){
n=in.read(buffe);//读取文件,内容放入buffer数组中,返回的是实际读取的字节数
if (n!=-1){
out.write(buffe,0,n);//把buffer数组从0开始,截取读取到有效字节数n 写入到目的文件中
}else {
break;
}
}
}
}