I/O流
一.IO流概述
I/O流是处理设备之间的一个数据传输;站在内存的角度来看流的流向
1.按照流向分可分为
输入流InputStream :硬盘——>内存
输出流OutPutStream:内存——>硬盘
2. 按照数据类型可分为
字节流和字符流
二.字节流
1.概述
可以读写任意类型的文件
字节流的抽象基类有:
InputStream ,OutputStream。
2.文件输出流(OutputStream)
(1)关联文件
输入流所关联的的文件,如果该文件不存在,会自动帮你创建
FileOutputStream out = new FileOutputStream("a.txt");
(2)写数据
out.write(100);//一次写入一个字节,输出的是d
out.write(300);//超出了一个字节,会丢弃掉多余字节
byte[] bytes={100,102,103}
out.write(bytes);//一次写入一个字节数组
out.write(bytes,2,2);//一次写入字节数组的一部分,从2索引开始,写2个字节
out.write(“你”.getBytes());//写入汉字
out.write("\r\n".getBytes());//写入一个回车换行符
out.flush();//刷新该流的缓存
out.close();//关闭流,流用完之后必须释放资源
追加写入
FileOutputStream out = new FileOutputStream("a.txt",true);//true代表追加写入;false代表不追加写入
3.文件输入流(InputStream)
(1)关联文件
FileInputStream in = new FileInputStream("a.txt");
注意
输入流所关联的文件必须存在,不存在就会报错
(2)写数据
in.read();//一次读取一个字节,读完后读取不到返回-1
//举例如下:
FileInputStream in = new FileInputStream("a.txt");
byte[] bytes = new byte[1024];//创建一个字节数组,充当缓冲区
int len = in.read(bytes);//一次读取1024个字节,放到这个缓冲区里面
System.out.println(len); //这个len他实际读取到的长度
String s = new String(bytes,0,len);//读取到字节的一部分,把字节数组转换成字符串
System.out.println(s);
in.close();//用完之后释放资源
4.文件的复制
(1)方式一:读取一个字节,写入一个字节来复制
package org.westos.demo3;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class lianxi {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("D:\\a.txt");
FileOutputStream out = new FileOutputStream("D:\\b.txt");
int l=0;
while ((l=in.read())!=-1){
out.write(l);
out.flush();
}
in.close();
out.close();
}
}
//将a.txt文件复制到b.txt中
(2)方式二;读取一个字节数组,写入一个字节数组来复制
package org.westos.demo3;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class lianxi {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("D:\\曾经的你.mp3");
FileOutputStream out = new FileOutputStream("E:\\曾经的你.mp3");
int l=0;
byte[] bytes = new byte[1024];
while ((l=in.read(bytes))!=-1){
out.write(bytes,0,l);
out.flush();
}
in.close();
out.close();
}
}
//将D盘目录下的音乐复制到E盘
5.高效的输入输出流
BufferedInputStream 和 BufferedOutputStream
关联文件用法:
BufferedInputStream bfr = new BufferedInputStream(new FileInputStream("E:\\曾经的你.mp3"));
其他用法和输入输出流类似,但更加高效
二.字符流
1.概述
只能读写文本文件
字符流的抽象基类:
Reader , Writer。
2.文件输入流(InputStreamReader)
(1)概述
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
(2)用法
InputStreamReader in = new InputStreamReader(new FileInputStream("a.txt"));
int ch = in.read(); //一次读取一个字符,读取不到返回 -1
------------------------------------------------------------------
char[] chars=new char[1024];//字符数组,充当缓冲区
int len = in.read(chars); //返回值,是实际读取到的字符个数
---------------------------------------------------------------
String trim = new String(chars,0,len);//把字符数组转换成字符串
--------------------------------------------------------------
String s = String.valueOf(chars);
System.out.println(s);//打印文件内容
3.文件输出流(OutputStreamWriter)
(1)概述
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
(2)用法
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));//
out.write("你好");//写入字符
out.flush();
out.close();
//复制文件部分代码
char[] chars=new char[1000];
int len=0;//用来记录你读取到的那个字符
while ((len=in.read(chars))!=-1){
out.write(chars,0,len);
out.flush();
}
out.close();
6.高效的字符流
(1)BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
(2)BufferedWriter
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
> BufferedWriter bfw = new BufferedWriter(new FileWriter("aa.txt"));
(3)案例演示
BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("aa.txt"));
char[] chars = new char[1024];
int len = 0;
while ((len=bfr.read(chars)) != -1) {
bfw.write(chars, 0, len);
bfw.flush();
}
bfr.close();
bfw.close();
(4)特有方法
readLine() 一次读取一行内容
BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("aa.txt"));
String line=null;
while ((line=bfr.readLine())!=null){
bfw.write(line);
bfw.newLine(); //写出一个换行符,具有平台兼容性
bfw.flush();
}
bfr.close();
bfw.close();
5.Scanner
(1)概述
InputStream in = System.in; //in 关联的是键盘
(2)构造方法
Scanner(File source)
构造一个新的 Scanner,它生成的值是从指定文件扫描的。
Scanner(InputStream source)
构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。
(3)案例演示
Scanner scanner = new Scanner(new File("a.txt"));
while (scanner.hasNextLine()){
String s = scanner.nextLine();
System.out.println(s);//打印文件内容
}
### 6.便捷流
**(1)概述**
>是输入输出流 子类, 唯一缺点,就是不能指定编码,他也没有特有方法,都是从父类继承下来的
```javascript
FileReader in = new FileReader("a.txt");
FileWriter out = new FileWriter("b.txt");
7.编码与解码
(1)编码
把字符串转换成字节数组,把看的懂的变成看不懂的
String str="你好";
byte[] bytes = str.getBytes(); //采用默认的码表进行编码
byte[] bytes1 = str.getBytes("utf-8");//采用指定的码表进行编码
(2)解码
把字节数组转换成字符串 把看不懂的,变成看的懂的
String s = new String(bytes);//采用默认的码表进行解码
String s = new String(bytes1,"utf-8");//采用指定的码表进行解码
System.out.println(s);
注意:如果遇到乱码的,可能是因为编解码用的不是同一个码表
三.各种流
1.数据输入输出流
DataInputStreatm DataOutputStreatm
特点:可以写基本类型,怎么写的怎么读,顺序不要乱
2.内存操作流
内存操作流不关联任何文件,只是内存中对数据进行读写
(1)操作字节数组
ByteArrayOutputStream:
此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray () 和 toString () 获取数据。
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write("123".getBytes());
out.write("456".getBytes())
byte[] allBytes = out.toByteArray();;//取出缓冲区中的数据
String s = new String(allBytes);
System.out.println(s);
ByteArrayInputStream
ByteArrayInputStream in= new ByteArrayInputStream(allBytes);
byte[] bytes=new byte[1024*8];
int len = in.read(bytes);
String s1 = new String(bytes, 0, len);
System.out.println(s1);
此流关闭无效,所以无需关闭
(2)操作字符数组
CharArrayWrite和CharArrayReader
CharArrayWriter writer = new CharArrayWriter();
writer.write("abc");
//取出缓冲区中的数据
char[] chars = writer.toCharArray();
System.out.println(String.valueOf(chars));
System.out.println(new String(chars));
System.out.println(writer.toString());
(3)操作字符串
StringWriter和StringReader
StringWriter stringWriter = new StringWriter();
stringWriter.write("abc");
stringWriter.append("abc");
String s = stringWriter.toString();
System.out.println(s);
3.字节打印流
打印流:只操作目的地,不关联源文件
PrintStream printStream = new PrintStream(new FileOutputStream("b.txt"));
printStream.write("字节打印流".getBytes());
printStream.print(true);
printStream.println(100);
printStream.close();
4.字符打印流
打印流:只操作目的地,不关联源文件
PrintWriter writer = new PrintWriter(new FileOutputStream("c.txt"),true);
writer.println("abc");
writer.flush();
writer.close();
5.键盘录入的第二种方式
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
System.out.println("请输入数据");
String s = reader.readLine();
//自定义一个结束标记
if("886".equals(s)){
break;
}
System.out.println(s);
}
6.随机访问流(RandomAccessFile)
(1)概述:
特点:能读能写,有一个文件指针,能够记录文件读写的位置
此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;
rw 模式,可读可以写
RandomAccessFile ra = new RandomAccessFile(new File("e.txt"), "rw");
boolean b = ra.readBoolean();
//获取文件指针的位置
long filePointer = ra.getFilePointer();
System.out.println(filePointer);
7.序列化与反序列化流
(1)序列化(ObjectOutputStream )
把对象保存到,硬盘上
Student student = new Student("zhangsan",23);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.txt"));
out.writeObject(student);
out.close();
(2)反序列化(ObjectInputStream)
把对象读取到内存中
ObjectInputStream objin = new ObjectInputStream(new FileInputStream("student.txt"));
Object obj = objin.readObject();
Student student= (Student) obj;
System.out.println(student.getName());
System.out.println(student.getAge());
1.把一个对象,序列化的硬盘上,有个要求,要求该类实现一个Serializable接口,然后该类的对象,才能正常序列化
2.再实现了Serializable接口之后,最好再写一个 public static final long serialVersionUID = 42L;
8.Properties
Properties 属性集合,经常用它来读写配置文件 属于双列集合
Properties properties = new Properties();//他规定了键值 是String类型
properties.put("aaa","bbb");
Object aaa = properties.get("aaa");
System.out.println(aaa);
Properties properties = new Properties();
//读取配置文件
//要求配置文件键值用等号 = 连接
properties.load(new FileReader("User.properties"));
System.out.println(properties);