IO流体系
一、字节流(文件,byte)
1、FileInputStream
- 作用:以
内存
为基准,可以把磁盘文件
中的数据以字节的形式读到内存
中去。 - 实现类:
- public FileInputStream(File file);
- pubilc FileInputStream(String pathname); (推荐使用)
- 方法:
- read(buffer,0,len)(常用,读多少取多少)
2、FileOutputStream
- 作用:以
磁盘
为基准,可以把内存文件
中的数据以字节的形式读到磁盘
中去。 - 实现类:
- public FileOutputStream(File file);
- pubilc FileOutputStream(String pathname); (推荐使用)
- pubilc FileOutputStream(String pathname,true); #加上true读写不会覆盖,变成追加
- 方法:
- write(buffer,0,len)(常用,读多少写多少)
3、读取文本解决中文乱码
-
存在问题:如果文件过大,会出现内存泄露,甚至不执行该操作。
-
解码:
- new String(char c)
- new String(byte[] buffer)
- new String(byte[] buffer, String charsetName)
File file = new File("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/aa.txt");
InputStream is = new FileInputStream(file);
//解决中文3个字节可能会被截断而导致乱码:
//方法一:自定义一个字节数组和文件一样大,一次性读完全部字节
byte[] buffer = new byte[(int) file.length()];
int len = is.read(buffer);
System.out.println(new String(buffer));
//方法二:使用java官方提供的方法,一次性读取完文件,他会把全部字节读取到一个数组中返回。
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
//性能得到提升!!
is.close();
4、字节流案例(拷贝文件)
4.1、try-catch-finally方式(通用)
public class FileCopy {
public static void main(String[] args) throws Exception {
//赋值文件
String copyFile = "/Users/hhc/Documents/DesktopItems/12.11/EN3A4492.jpg";
String target = "/Users/hhc/Documents/DesktopItems/前端/1.jpg";
CustomFileCopy(copyFile,target);
}
public static void CustomFileCopy(String copyFile, String target) throws Exception {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(copyFile);
os = new FileOutputStream(target);
byte[] buffer = new byte[1024*8]; //8KB
int len;
while ((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("文件复制完成!!!");
} catch (IOException e){
e.printStackTrace();
} finally {
try {
if (os != null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (is != null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.2、try-with-resources方式(JDK7及以上)
-
此方式会自动关闭写在try()里面的资源
-
什么是资源:资源一般都实现了AutoCloseable接口。
public class FileCopy2 {
public static void main(String[] args) throws Exception {
//赋值文件
String copyFile = "/Users/hhc/Documents/DesktopItems/12.11/EN3A4492.jpg";
String target = "/Users/hhc/Documents/DesktopItems/前端/1.jpg";
CustomFileCopy(copyFile,target);
}
public static void CustomFileCopy(String copyFile, String target) {
try (
InputStream is = new FileInputStream(copyFile);
OutputStream os = new FileOutputStream(target);
){
byte[] buffer = new byte[1024*8]; //8KB
int len;
while ((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("文件复制完成!!!");
} catch (IOException e){
e.printStackTrace();
}
}
}
二、字符流(文本,char)
1、FileReader
- 作用:以
内存
为基准,可以把磁盘文件
中的数据以字节的形式读到内存
中去。 - 实现类:
- public FileReader(File file);
- pubilc FileReader(String pathname); (推荐使用)
- 方法:
- read(buffer,0,len)(常用,读多少取多少)
2、FileWrite
-
作用:以
磁盘
为基准,可以把内存文件
中的数据以字节的形式读到磁盘
中去。 -
实现类:
- public FileWrite(File file);
- pubilc FileWrite(String pathname); (推荐使用)
- pubilc FileWrite(String pathname,true); #加上true读写不会覆盖,变成追加
-
方法:
- write(String str,0,len)(常用,读多少写多少)
- write(char[] buffer,0,len)(常用,读多少写多少)
-
★★★注意:字符流写出数据后,必须
刷新流
,或者关闭流
,写出去的数据才能生效。- 刷新流:flush()
- 关闭流:close(),关闭流会自动刷新的,所以日常用close。
3、示例
public class WenBenCopy {
public static void main(String[] args) {
String copyWenBenFile = "/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/java/com/hbwe/bb.txt";
String target = "/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/java/com/hbwe/cc.txt";
CustomWenBenCopy(copyWenBenFile,target);
}
public static void CustomWenBenCopy(String copyWenBenFile, String target){
try (
Reader is = new FileReader(copyWenBenFile);
Writer os = new FileWriter(target);
){
char[] buffer = new char[10];
int len;
while ((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("文本文件复制完成!!!");
} catch (IOException e){
e.printStackTrace();
}
}
}
三、IO流进阶
1、缓冲流
- 包装原始流
- 提高读写数据的性能
- 自带8KB的缓冲池,也可自定义大小
1.1、字节缓冲流
- BufferedInputStream(is)
- BufferedOutputStream(os)
1.2、字符缓冲流
- BufferedReader
- 新增方法:readLine(),按行读取,没有数据返回null
- BufferedWtite
- 新增方法:newLine(),换行
1.3、拷贝文件缓冲流优化
public class FileCopy {
public static void main(String[] args) throws Exception {
//赋值文件
String copyFile = "/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/java/com/buffer/bb.txt";
String target = "/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/java/com/buffer/c1.txt";
CustomFileCopy(copyFile,target);
}
public static void CustomFileCopy(String copyFile, String target) {
try (
InputStream is = new FileInputStream(copyFile);
//定义一个字节输入缓冲流
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(target);
//定义一个字节输出缓冲流
OutputStream bos = new BufferedOutputStream(os);
){
byte[] buffer = new byte[1024*8]; //8KB
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
System.out.println("文件复制完成!!!");
} catch (IOException e){
e.printStackTrace();
}
}
}
2、转换流
2.1、字符输入流
-
public InputStreamReader(InputStream is, “GBK”);
-
作用:可以拿到指定编码格式的输入流,将它转换成字符输入流,这样无论是那种编码格式,都不会乱码了。
try ( InputStream is = new FileInputStream("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/bb.txt"); Reader isr = new InputStreamReader(is, "GBK"); //这里写的是bb.txt的编码格式。 BufferedReader br = new BufferedReader(isr); ){ String line; while ((line = br.readLine()) != null){ System.out.println(line); } } catch (IOException e){ e.printStackTrace(); }
2.2、字符输出流
-
public InputStreamReader(InputStream is, “GBK”);
-
作用:可以将输出流转换成自己想要的编码格式。
public class Test02 { public static void main(String[] args) { try ( OutputStream os = new FileOutputStream("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/eeT1.txt"); Writer osw = new OutputStreamWriter(os,"GBK"); //以GBK的编码格式写到eeT1.txt文件中 BufferedWriter bw = new BufferedWriter(osw) ){ bw.write("我是中国人abc"); bw.newLine(); bw.write("我爱你中国abc"); } catch (IOException e){ e.printStackTrace(); } } }
3、打印流
- 底层包装了一个缓冲流,所以不用担心性能。
3.1、PrintStream(字节)
- public PrintStream(OutputStream/File/String)
- public PrintStream(String fileName, Charset charset)
- public PrintStream(OutputStream out, boolean autoFlush)
- public PrintStream(OutputStream out, boolean autoFlush, String encoding)
- 提供的方法:
- write()
- print()
- println() ★★★
3.2、PrintWrite(字符)
- 和PrintStream无异,只不过多了一个Writer。其他俩个写法一样
- public PrintWriter(OutputStream/Writer/File/String)
- public PrintStream(OutputStream out/Writer, boolean autoFlush)
- 提供的方法:
- write()
- print()
- println() ★★★
3.3、应用输出语句重定向
-
具体操作将系统的out设置成自己的输出流。
-
PrintStream ps = new PrintStream(“/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/eeT3.txt”, StandardCharsets.UTF_8);
-
System.setOut(ps)
public class printlnStreamTest2 { public static void main(String[] args) { System.out.println("老当益壮"); System.out.println("自在潜力"); try( PrintStream ps = new PrintStream("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/eeT3.txt", StandardCharsets.UTF_8); ) { System.setOut(ps); System.out.println("魔术大放"); System.out.println("你好明天"); //这两个会输出到指定文件,eeT3.txt。 } catch (Exception e) { e.printStackTrace(); } } }
4、数据流
- 允许把数据和其类型一并写出去。
- 可以将写进去的数据再次读出来。
4.1、DataOutputStream(数据输出流)
- public DataOutputStream(OutputStream out)
- 常用方法:
- writeByte(int v)
- writeInt(int v)
- writeDouble(Double v)
- writeUTF(String str)
4.2、DataInputStream(数据输出流)
- public DataInputStream(InputStream in)
- 常用方法:
- readInt()
- readLong()
- readBoolean()
- readUTF()
5、序列化流
- 将java对象写到文件,或者从文件中读取出来
- 注意,如果对象需要序列化,一定要实现java.io.Serializable接口。
- transient,在对象实体类的字段前加上,代表不参与序列化。
5.1、ObjectOutputStream(对象字节输出流)
- 可以将对象进行序列化:把java对象存入到文件中去。
- public ObjectOutputStream(OutputStream out)
- 方法:
- write(Object o)
5.2、ObjectInputStream(对象字节输入流)
- 可以将对象进行反序列化:把从文件中将java对象读取出来
- public ObjectInputStream(InputStream in)
- 方法:
- readObject()
5.3、示例
public class Test1Object {
public static void main(String[] args) {
try(
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/ttu.txt"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/hhc/Documents/DesktopItems/J2EE/IOTest/src/main/resources/ttu.txt"));
){
User user = new User("admin", "张三", 18, "123456");
oos.writeObject(user);
User u = (User) ois.readObject();
System.out.println(u);
} catch (Exception e) {
e.printStackTrace();
}
}
}