目录
void write(byte[] data,int offset,int len)
String(byte[] data,Charset cn)
块读写:
块读:一次性读取一组字节的方式
InputStream中定义了块读的方法
int read(byte[] data)
- 一次性读取给定字节数组总长度的字节量并存入到该数组中。
- 返回值为实际读取到的字节数。如果返回值为-1表示本次没有读取到任何字节已经是流的末尾了
块写:一次性写出一组字节的方式
OutputSteream中定义了块写的方法
void write(byte[] data)
- 一次性将给定数组中所有字节写出
package io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("image.jpg"); FileOutputStream fos = new FileOutputStream("image1.jpg"); int d; while ((d = fis.read() )!= -1){ fos.write(d); } System.out.println("复制完毕"); fis.close(); fos.close(); } }
void write(byte[] data,int offset,int len)
- 一次性将data数组中从下标offset处开始的连续len个字节一次性写出
package io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * 提高每次读写的数据量减少读写次数,可以提高读写效率 */ public class CopyDemo2 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("image.jpg"); FileOutputStream fos = new FileOutputStream("image2.jpg"); byte[] data = new byte[1024*10]; int d; long start = System.currentTimeMillis(); while ((d= fis.read(data)) != -1){ fos.write(data,0,d);//void write(byte[] data,int offset,int len):将给定的字节数组中从offset处开始的连续len个字节写出 } long end = System.currentTimeMillis(); System.out.println("复制完毕!耗时:"+(end-start)+"ms"); fis.close(); fos.close(); } }
文件输出构造器
-
覆盖模式:当文件流创建时发现指定的文件已经存在了,那么会将该文件内容清空。
-
覆盖模式
FileOutputStream(String path)
FileOutputStream(File file)
上述两种构造器创建的文件输出流为覆盖模式 -
追加模式:当文件流创建时发现指定的文件已经存在了,那么文件数据全部保留通过该流新写出的数据会被陆续的追加到文件中。
-
追加模式
FileOutputStream(String path,boolean append)
FileOutputStream(File file,boolean append)
如果第二个参数为true,那么当前文件输出流就开启了追加模式
package io;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 写出文本数据
*/
public class WriteStringDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt",true);//如果第二个参数为true,那么当前文件输出流就开启了追加模式
// String line = "正在努力学Java~";
// byte[] data = line.getBytes(StandardCharsets.UTF_8);
// fos.write(data);
//
// fos.write("为了找到好工作。".getBytes(StandardCharsets.UTF_8));
fos.write("加油!".getBytes(StandardCharsets.UTF_8));
System.out.println("写出完毕!");
fos.close();
}
}
文件输入构造器:
读取文本数据:先将文件中的字节读取出来,然后再将这些字节按照对应的字符集转换为字符串即可
package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 读取文本数据
*/
public class ReadStringDemo {
public static void main(String[] args) throws IOException {
/*
1:先从fos.txt中读取所有的字节
2:再将这些字节转换为字符串
*/
//1
File file = new File("fos.txt");
long len = file.length();//文件名长度
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int)len];//创建一个与文件长度等长的字节数组
fis.read(data);//一口气将文件所有字节读入到data数组中(块读)
//2将data数组中所有字节按照UTF-8编码还原为字符串
String line = new String(data, StandardCharsets.UTF_8);
System.out.println(line);
fis.close();
}
}
String(byte[] data,Charset cn)
将data数组中的所有字节按照指定的字符集转换为字符串String line = new String(data, StandardCharsets.UTF_8);//将字符串先还原成0,1方式
高级流
java将IO分为两类
节点流:"低级流"
-
特点:直接链接程序与另一端的"管道",是真实读写数据的流
-
IO一定是建立在节点流的基础上进行的
-
文件流就是典型的节点流(低级流)
处理流:"高级流"
-
特点:不能独立存在,必须链接在其他流上
-
目的:当数据经过当前高级流时可以对数据进行某种加工操作,来简化我们的同等操作
-
实际开发中我们经常"串联"一组高级流最终到某个低级流上,使读写数据以流水线式的加工处理完成。这一操作也被成为"流的链接"。流链接也是JAVA IO的精髓所在。
高级流---缓冲流:
-
作用:加快读写效率,通常缓冲是最终链接在低级流上的流
BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos);
-
使用缓冲流完成文件复制操作:
package io; import java.io.*; /** * 使用缓冲流完成文件复制操作 */ public class CopyDemo3 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("image.jpg"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("image3.jpg"); BufferedOutputStream bos = new BufferedOutputStream(fos); int d; long start = System.currentTimeMillis(); while ((d = bis.read()) != -1){ bos.write(d); } long end = System.currentTimeMillis(); System.out.println("复制完毕!用时:"+(end-start)+"ms"); bis.close(); bos.close(); } }
内部定义了一个属性byte buf[]。它等同于我们之前练习复制案例时的块写操作。
并且默认创建时,该buf数组的长度为8192(8kb)长度。
缓冲流在读写数据时**总是以块读写数据**(默认是8kb)来保证读写效率的
缓冲流提供了多种构造器,可以自行指定缓冲区大小。
-
使用缓冲流完成文件复制操作:
由于缓冲输出流会将写出的数据装满内部缓冲区(默认8kb的字节数组)后才会进行一次真实的写出操作。当我们的数据不足时,如果想要及时写出数据,可以调用缓冲流的flush()方法,强制将缓冲区中已经缓存的数据写出一次。
package io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 缓冲输出流的写缓冲问题
*/
public class BosFlushDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bos.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String line = "super idol的笑容都没你的甜";
byte[] data = line.getBytes(StandardCharsets.UTF_8);
bos.write(data);
// bos.flush();
System.out.println("写出完毕");
bos.close();
}
}
flush的传递
- bos.flush():强制将缓冲流的缓冲区(内部维护的字节数组)中已经缓存的字节一次性写出
- flush()方法是被定义在java.io,Flushable中 而字节输出的超类
flush()方法是被定义在java.io.Flushable中。而字节输出流的超类java.io.OutputStream实现了该接口,这意味着所有的字节输出流都有flush方法。而除了缓冲流之外的高级流的flush方法作用就是调用它链接的流的flush方法将该动作传递下去。最终传递给缓冲流来清空缓冲区。
高级流---对象流
对象输出流:(OOS)java.io.ObjectOutputStream
-
作用:将我们的java对象进行序列化
-
序列化:将一个对象转换为一组可被传输或保存的字节。这组字节中除了包含对象本身的数据外,还会包含结构信息。
-
序列化的意义:
-
实际开发中,我们通常会将对象
- 写入磁盘,进行长久保存
- 在网络间两台计算机中的java间进行传输
无论是保存在磁盘中还是传输,都需要将对象转换为字节后才可以进行。
-