java的IO的流向
IO流的方向是相对的,所以选取java程序为参考点,流入java程序叫输入流,流出java程序的输出流
以下是io流的分类
•按操作数据单位不同分为:流 字节流**(8 bit)** ,字符流**(16 bit)**
•按数据流的流向不同分为: 输入流,输出流
其中Writer,Reader是抽象类,InputStream,OutputStream也是抽象类java.io.InputStream和OutputStream是所有字节流的超类.java.io.Reader和Writer是所有字符流的超类
以下是我整理的常见oi流的类,只是我见到的
FileInputStream/文件字节输入流
最常见read()返回一个字节的数据。小例子练习先向fos.dat文件写入"abcdefghijklmnopqrstuvwxyz"再用fileInputStream对象读取。
public class FISDemo {
public static void main(String[] args) throws IOException {
// 文件创建fos.dat文件
File file = new File("fos.dat");
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
//写入一串数字
fos.write(("abcdefghijklmnopqrstuvwxyz").getBytes());
FileInputStream fis = new FileInputStream(file);
int len = 0;
long t1 = System.currentTimeMillis();
while ((len = fis.read()) != -1) {
System.out.print( len+" ");
}
System.out.println();
long t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
}
}
FileOutupStream
FileOutStream常用write(). 将指定的字节写入此文件输出流。小练习将A~Z写入根目录的fos.dat文件中
public class FOSDemo {
public static void main(String[] args) throws IOException {
File file = new File("fos.dat");
// FileOutputStream构造器 有true和没有true的区别
// 没有true 每次执行会覆盖之前文件里fos.dat
// 有true的情况 不会清空fos.dat的内容继续往后追加
FileOutputStream fos = new FileOutputStream(file,true);//写
for (int i = 0; i < 26; i++) {
fos.write(65 + i);
}
fos.close();
}
}
小练习用FileInputStream和FileOutputStream实现图片的复制
public class CopyOf {
public static void main(String[] args) throws IOException {
// 把海贼女帝的image.png文件 复制成 image_cp.png/前提是image.png图片要存在
// 并记录复制时间
FileInputStream fis = new FileInputStream("image.png");
FileOutputStream fos = new FileOutputStream("image_cp.png");
int cd;
long start = System.currentTimeMillis();
while ((cd = fis.read()) != -1){
fos.write(cd);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕");
System.out.println("复制所花" +(end - start)+"ms");
fis.close();
fos.close();
}
}
BufferedInputStream/缓冲字节输入流
BufferedInputStream继承FilterInputStream ,它的优势是先从缓冲区读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件),下面用BufferedInputStream和FileInputStream来读同一文件fot.dat里面是vue.js看看那个读取速度更快
明显看到BufferedInputStream的读取速度更快。
ObjectOutputStream和ObjectInputStream
- 这两个都是字节流。ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化【把java对象以字节写入磁盘文件中】
- ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化【将磁盘中的对象数据字节转换成java对象】为一个对象,并将其返回
public class Person implements Serializable{
private String name;
private String gender;
private int age;
private String[] otherInfo;
public Person(String name, String gender, int age, String[] otherInfo) {
this.name = name;
this.gender = gender;
this.age = age;
this.otherInfo = otherInfo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getOtherInfo() {
return otherInfo;
}
public void setOtherInfo(String[] otherInfo) {
this.otherInfo = otherInfo;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", otherInfo=" + Arrays.toString(otherInfo) +
'}';
}
}
public class OOSDemo {
//一个Person对象有 name、age、gender、otherInfo属性
// 实现序列化接口 用一个对象输出流 写入F:\person.text保存
public static void main(String[] args) throws IOException {
// 将一个Person对象写入person.obj中保存
String name = "周大嘟";
String gender = "男";
int age = 23;
String[] otherInfo = {"唱","t跳","rap","篮球"};
Person p = new Person(name, gender, age, otherInfo);
FileOutputStream fos = new FileOutputStream("F:\\person.text");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
oos.close();
}
}
public class OISDemo {
//读取已经生成的F:\person.text中的信息
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("F:\\person.text");
ObjectInputStream ois = new ObjectInputStream(fis);
Person person = (Person) ois.readObject();
System.out.println(person);
}
}
BufferedReader类
从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行。是高级流一般嵌套低级流。BufferedReader和BufferedWriter在内存中会自带一个8kb的字节缓冲区,并提供了一个的方法readLine();方法。每次读取一行内容, 缓冲流内部默认的缓冲区大小(字节数组大小)为8Kb我们可以通过重载的构造器,在第二个参数上通过整数来指定需要的缓冲区大小。
关于BufferedReader小练习
/**
* 利用缓冲字符输入流将./ooday09/io目录下的所有.java文件内容输入到控制台
* 1:先使用File定位目录./src/main/java
* 2:利用File的listFiles方法加上文件过滤器获取该目录下的所有.java文件
* 3:遍历每一个文件,利用文件输入流读取文件,进行流连接为BufferedReader
* 4:参照BRDemo.java案例,将文件内容按行读取出来并输出到控制台.
*/
public class Test7 {
public static void main(String[] args) throws IOException {
File dir = new File("./ooday09/io");//这路径写你的
//用拉姆达表达式过滤器获取该目录下的所有.java文件
File[] subs = dir.listFiles(f->f.getName().endsWith(".java"));
for(File sub : subs){
FileInputStream fis = new FileInputStream(sub);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
}
结果太长就不展示了。
InputStreamReader
InputStreamReader是字节流到字符流的桥接器,继承Reader抽象类读取字节流通过指定的字符集解码为字符流,可以通过名称指定字符集,也可以通过显示指定,或者不指定则为平台默认的字符集每次调用InputStreamReader的read()方法,都会从底层字节流读取一个或多个字节为了能够有效地将字节转换为字符,可以预先从底层流读取比满足当前读取操作所需的字节更多的字节;
为了提高效率,可以把一个InputStreamReader包装在一个BufferedReader中
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
InputStreamReader小练习
用InputStreamReader读取某个文件并输出的控制台
public class ISRDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("./ooday09/io/ISRDemo.java");
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
int d;
while((d= isr.read())!=-1){
System.out.print((char)d);
}
isr.close();
}
}
PrintWriter
是具有自动行刷新的缓冲字符输出流(内部总是连接。BufferedWriter作为缓冲)特点:可以自动行刷新,且可以安行写出字符串。
PrintWriter小练习【在控制台输出一行一行内容并写入到fos.txt】
public class PWDemo2 {
public static void main(String[] args) throws FileNotFoundException {
//在fos.txt往后追加,之前的内容不删除
FileOutputStream fos = new FileOutputStream("fos.txt",true);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw,true);
// 控制行输出字符串 并写入文件
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请输入");
String vv = sc.nextLine();
if ("exit".equals(vv)){
break;
}
//pw.write(vv);
pw.println(vv);
}
pw.close();
}
}