IO流 :
一 流的分类
1.按操作数据单位不同分为:字节流(8 bit)(视频,音频,图片),字符流(16 bit)(文本文件)
2.按数据流的流向不同分为:输入流,输出流
3.按流的角色的不同分为:节点流,处理流
@Test
public void test2(){
FileInputStream fis = null;
try {
//1.创建File对像
File file = new File("hello.txt");
//2.创建流的对像
fis = new FileInputStream(file);
//3.读取文件内容
byte[] b = new byte[5];
int len = 0;
while((len = fis.read(b)) != -1){
// for (int i = 0; i < len; i++) {
// System.out.print((char)b[i]);
// }
System.out.print(new String(b,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//4.关流
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转换流
作用 : 1.将字节流可以转成字符流
2.对文件内容进行转码(比如将GBK 转成 UTF-8)
注意:读取文件内容的时候 输入流的编码格式和文件的编码格式必须保持一致
/*
* InputStreamReader : 将字节流转换成字符流
*/
@Test
public void test() throws Exception{
File file = new File("aaa.txt");
FileInputStream fis = new FileInputStream(file);
//创建一个转换流的对象 : 将字节流转换成了字符流
InputStreamReader isr = new InputStreamReader(fis);
char[] c = new char[100];
int len = 0;
while((len = isr.read(c)) != -1){
System.out.println(new String(c,0,len));
}
isr.close();
fis.close();
}
/*
* OutputStreamWriter : 将字符流转成字节流
*/
@Test
public void test2() throws Exception{
FileOutputStream fos = new FileOutputStream("bbb.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write("中国中国我爱你".toCharArray());
FileInputStream fis = new FileInputStream("bbb.txt");
byte[] b = new byte[2024];
int len = 0;
while((len = fis.read(b))!=-1){
System.out.println(new String(b, 0, len));
}
System.out.println();
osw.flush();
osw.close();
fos.close();
}
转码
注意:读取文件内容的时候 输入流的编码格式和文件的编码格式必须保持一致
@Test
public void test3() throws Exception{
FileInputStream fis = new FileInputStream("char8.txt");
InputStreamReader isr = new InputStreamReader(fis,"gbk");
FileOutputStream fos = new FileOutputStream("char9.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
//读写内容
char[] c = new char[500];
int len = 0;
while((len = isr.read(c)) != -1){
osw.write(c, 0, len);
}
//关流
osw.close();
isr.close();
fos.close();
fis.close();
}
/*
* FileOutputStream
* 注意 : 要写入到的文件可以不存在。
* FileOutputStream(File file, boolean append) :
* append如果为true : 内容在原来的基础上进行追加
* append如果为false : 内容会覆盖原来的内容
* 默认是false
*/
@Test
public void test() throws Exception{
//1.创建File对像
File file = new File("aaa.txt");
//2.创建流的对象
FileOutputStream fos = new FileOutputStream(file,false);
//3.写内容
fos.write("fffff".getBytes());
//4.关流
fos.close();
}
一边读一边写
@Test
public void test2() throws Exception{
//1.创建File对像
File file = new File("hello.txt"); //读取的文件
File file2 = new File("ccc.txt"); //写入内容的的文件
//2.创建流
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file2);
//3.一边读一边写
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1){
//将内容写出去
fos.write(b, 0, len);
}
//4.关流
fis.close();
fos.close();
}
实现复制的功能
@Test
public void test3(){
String desc = "C:\\Users\\Administrator\\Desktop\\bbb.avi";
String src = "C:\\Users\\Administrator\\Desktop\\aaa.avi";
long start = System.currentTimeMillis();
copy(desc, src);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
public void copy(String desc,String src){
FileOutputStream fos = null;
FileInputStream fis = null;
try {
//1.创建File对象
File file = new File(desc); //复制的文件的路径
File file2 = new File(src); //被复制的文件的路径
//2 创建流
fis = new FileInputStream(file2);
fos = new FileOutputStream(file);
//3 一边读一边写
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1){
fos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关流
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
打印流 (了解)
FileOutputStream fos = new FileOutputStream("text.txt");
// 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
PrintStream ps = new PrintStream(fos, true);
// 把标准输出流(控制台输出)改成文件
if (ps != null) {
System.setOut(ps);
}
for (int i = 0; i <= 10; i++) { // 输出ASCII字符
// System.out.print((char) i);
// if (i % 50 == 0) { // 每50个数据一行
// System.out.println(); // 换行
// }
System.out.print("a");
}
ps.close();
缓冲流 : 提高读取和写入的效率
/*
* new BufferedInputStream(InputStream in)
*/
@Test
public void test() throws Exception{
//创建节点流
FileInputStream fis = new FileInputStream("aaa.txt");
//创建缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
//读内容
byte[] b = new byte[1024];
int len = 0;
while((len = bis.read(b)) != -1){
System.out.println(new String(b,0,len));
}
//关流(从外向内关流)
bis.close();
fis.close();
}
/*
* new BufferedOutputStream(OutputStream out)
*/
@Test
public void test2() throws Exception{
//创建节点流
FileOutputStream fos = new FileOutputStream("bbb.txt");
//创建缓冲流
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写内容
bos.write("cccccccccccccccccccccc".getBytes());
//关流
bos.close();
fos.close();
}
/*
* 使用缓冲流进行文件的复制
*/
@Test
public void test3(){
String desc = "C:\\Users\\Administrator\\Desktop\\bbb.avi";
String src = "C:\\Users\\Administrator\\Desktop\\aaa.avi";
long start = System.currentTimeMillis();
copy(desc, src);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
public void copy(String desc,String src){
FileOutputStream fos = null;
FileInputStream fis = null;
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try {
//1.创建File对象
File file = new File(desc); //复制的文件的路径
File file2 = new File(src); //被复制的文件的路径
//2 创建流
fis = new FileInputStream(file2);
fos = new FileOutputStream(file);
//创建缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3 一边读一边写
byte[] b = new byte[1024];
int len = 0;
while((len = bis.read(b)) != -1){
bos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关流
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
数据流(了解)
/*
* 写入到文件的类型的顺序 应该和读取文件内容类型的 顺序保持一致 否则会导致内错,或者异常
*/
@Test
public void test() throws Exception{
FileInputStream fis = new FileInputStream("faaa.txt");
DataInputStream dis = new DataInputStream(fis);
int readInt = dis.readInt();
String readUTF = dis.readUTF();
String readUTF2 = dis.readUTF();
String readUTF3 = dis.readUTF();
float readFloat = dis.readFloat();
dis.close();
fis.close();
}
@SuppressWarnings("resource")
@Test
public void test2() throws Exception{
FileOutputStream fos = new FileOutputStream("faaa.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(111);
dos.writeUTF("?#====");
dos.writeUTF("abcd");
dos.writeUTF("defgg");
dos.writeFloat(12.3f);
dos.close();
fos.close();
}
}
字符流
- 字节流和字符流使用场景:
- 字节流 : 如果需要复制一些文件我们会考虑使用字节流
- 字符流 : 如果需要读取一些中文那么这个时候会考虑使用字符流
/*
* FileReader
*/
@Test
public void test() throws Exception{
FileReader reader = new FileReader("hello.txt");
char[] c = new char[1024];
int len = 0;
while((len = reader.read(c)) != -1){
for (int i = 0; i < len; i++) {
System.out.print(c[i]);
}
// System.out.println(new String(c,0,len));
}
reader.close();
}
/*
* FileWriter
*/
@Test
public void test2() throws Exception{
//创建流
FileWriter writer = new FileWriter("abc.txt");
//写内容
writer.write("中国人中国啦啦啦啦".toCharArray());
//关流
writer.close();
}
/*
* 一边读一边写
*/
@Test
public void test3() throws Exception{
//创建流
FileReader reader = new FileReader("abc.txt");
FileWriter writer = new FileWriter("cba.txt");
//一边读一边写
char[] c = new char[100];
int len = 0;
while((len = reader.read(c)) != -1){
writer.write(c, 0, len);
}
//关流
writer.close();
reader.close();
}
对象流
注意:
* 一 序列化的对象所在的类必须实现Serializable接口
* 二 所在类中的引用数据类型也必须实现Serializable接口
* 三 显示声明private static final long serialVersionUID = 10000000546546546L;
* 注意:
* 1.也可以不显示声明,但是如果不显示声明的话就不要修改原来的类中的内容。
* 如果需要修改建议大家显示的去声明且声明的版本号和序列化时的版本号保持一致。
* 2.如果没有显示的声明程序也会自动添一个版本号,但是如果序列化中的那个类进行修改了,那么版本号会发生改变。
* transient 修饰的属性不可序列化
* static修饰的属性也不可以序列化
*
* 序列化 : 将内存中的对象写到磁盘上
* 反序列化 : 将磁盘上的对象的内容进行读取,读取到内存
@Test
public void test() throws Exception{
FileInputStream fis = new FileInputStream("object.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object readObject = ois.readObject();
Person person = (Person) readObject;
person.show();
System.out.println(person.aa);
ois.close();
fis.close();
}
@Test
public void test2() throws Exception{
FileOutputStream fos = new FileOutputStream("object.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person person = new Person("aaa",18,new Address("国王街"));
person.aa = "ccc";
oos.writeObject(person);
oos.close();
fos.close();
}
字符缓冲流
FileReader reader = new FileReader("cba.txt");
BufferedReader br = new BufferedReader(reader);
FileWriter writer = new FileWriter("dcc.txt");
BufferedWriter bw = new BufferedWriter(writer);
//一边读一边写
// char[] c = new char[100];
// int len = 0;
// while((len = br.read(c)) != -1){
// bw.write(c, 0, len);
// }
// String readLine = br.readLine(); //读一行 如果读完了返回null
String str = "";
while((str = br.readLine()) != null){
// System.out.println(str);
bw.write(str);
bw.newLine(); //换行
}
// bw.flush(); //将内存中的数据刷到磁盘上
//关流
bw.close(); //在关闭流的同时调用了flush方法
br.close();
writer.close();
reader.close();
}
/*
* 总结
*/
@Test
public void test() throws Exception{
new FileOutputStream(new File("aaa.txt"), true); //true是追加 false是覆盖
new FileWriter(new File("aaa.txt"), true); //true是追加 false是覆盖
// new PrintStream(fos, true); //true是否自动刷新
new BufferedReader(new InputStreamReader(System.in),1); //1是指的在内存中缓存区域的大小
}
随机存取文件流
@Test
public void test5() throws Exception{
RandomAccessFile ra = new RandomAccessFile("acc.txt", "rw");
// * 1.先将指针移动到c的后面
ra.seek(3);
// * 2.读取c后面的内容并保存
// String str = ra.readLine();
String str = "";
byte[] b = new byte[1024];
int len = 0;
while((len = ra.read(b)) != -1){
// str += new String(b,0,len);
String s = new String(b,0,len);
str += s;
}
// * 3.回移指针移动到c的后面
ra.seek(3);
// * 4.将AAA写入(写入后会进行覆盖 -- abcAAAg)
ra.write("AAA".getBytes());
// * 5.继续将原来保存的内容向后写
ra.write(str.getBytes());
ra.close();
}
/*
* 文件中的内容 : abcdefg
*
* 需求:在c的后面插入AAA
*
* 1.先将指针移动到c的后面
* 2.读取c后面的内容并保存
* 3.回移指针移动到c的后面
* 4.将AAA写入(写入后会进行覆盖 -- abcAAAg)
* 5.继续将原来保存的内容向后写
*/
@Test
public void test4() throws Exception{
RandomAccessFile ra = new RandomAccessFile("acc.txt", "rw");
//移动指针
ra.seek(3); //将指针移动到3的位置
ra.write("AAA".getBytes());
ra.close();
}
/*
* 从某个位置向后读
*/
@Test
public void test3() throws Exception{
RandomAccessFile ra = new RandomAccessFile("acc.txt", "rw");
//移动指针
ra.seek(3); //将指针移动到3的位置
String readLine = ra.readLine();
System.out.println(readLine); //defg
ra.close();
}
/*
* 读
*/
@Test
public void test() throws Exception{
RandomAccessFile ra = new RandomAccessFile("acc.txt", "rw");
byte[] b = new byte[1024];
int len = 0;
while((len = ra.read(b)) != -1){
System.out.print(new String(b,0,len));
}
ra.close();
}
/*
* 写
*/
@Test
public void test2() throws Exception{
RandomAccessFile ra = new RandomAccessFile("acc.txt", "rw");
ra.write("abcdefg".getBytes());
ra.close();
}