Java之I/O流

编程入门 行业动态 更新时间:2024-10-27 00:34:48

<a href=https://www.elefans.com/category/jswz/34/1770091.html style=Java之I/O流"/>

Java之I/O流

在学习I/O流之前我们需要大致了解一下字符集编码的详细情况

字符集编码

注:字符编码和解码要使用相同的字符集,否则会出现乱码
英文数字一般不会出现乱码,许多字符集都兼容了ascll编码
在Java中我们默认使用的是UTF-8编码

Java中的I/O流通常包括两大类——字节流和字符流

字节流和字符流对比

1.字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件

2.字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了

字节流的各类流之间的关系

作为初学者的我们可能都会有这样一个疑问:
什么是输入流,什么是输出流,而且有什么区别,分别是什么时候使用?
A:我们首先要明白:输入输出是相对于程序本身而言
B: 比如:输入流相对于程序本身而言就是从文件中输入到程序里面------换句话说就是读文件
想当然那么输出流就是从文件中输出到文件中-----写文件

字节流各种子类对比—这里以字节输入流为例

1.InputStream:InputStream是所有字节输入流的抽象基类,前面说过抽象类不能被实例化,实际上是作为模板而存在的,为所有实现类定义了处理输入流的方法。2.FileInputSream:文件输入流,一个非常重要的字节输入流,用于对文件进行读取操作。3.PipedInputStream:管道字节输入流,能实现多线程间的管道通信。4.ByteArrayInputStream:字节数组输入流,从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去。5.FilterInputStream:装饰者类,具体的装饰者继承该类,这些类都是处理类,作用是对节点类进行封装,实现一些特殊功能。6.DataInputStream:数据输入流,它是用来装饰其它输入流,作用是“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。7.BufferedInputStream:缓冲流,对节点流进行装饰,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送,效率更高。8.ObjectInputStream:对象输入流,用来提供对基本数据或对象的持久存储。通俗点说,也就是能直接传输对象,通常应用在反序列化中。它也是一种处理流,构造器的入参是一个InputStream的实例对象。

字符流的各类流之间的关系----以输入流为例

两大父类:Writer Reader

1.InputStreamReader(转换流的代表):从字节流到字符流的桥梁(InputStreamReader构造器入参是FileInputStream的实例对象),它读取字节并使用指定的字符集将其解码为字符。它使用的字符集可以通过名称指定,也可以显式给定,或者可以接受平台的默认字符集。2.BufferedReader:从字符输入流中读取文本,设置一个缓冲区来提高效率。BufferedReader是对InputStreamReader的封装,前者构造器的入参就是后者的一个实例对象。3.FileReader:用于读取字符文件的便利类,new FileReader(File file)等同于new InputStreamReader(new FileInputStream(file, true),"UTF-8"),但FileReader不能指定字符编码和默认字节缓冲区大小。4.PipedReader :管道字符输入流。实现多线程间的管道通信。5.CharArrayReader:从Char数组中读取数据的介质流。6.StringReader :从String中读取数据的介质流。

WriterReader结构类似,方向相反,不再赘述。唯一有区别的是,Writer的子类PrintWriter

缓冲流和缓冲池

字节流的缓冲区

逐个字节对文件进行读写效率很低(文件在硬盘中,我们的程序在内存中,而计算机对内存的操作是很快的,所以我们可以通过手动设置一个字节缓冲区对文件进行读写的操作)

package IO.File.Stream;import java.io.FileInputStream;
import java.io.IOException;public class FileInput2 {public static void main(String[] args) throws IOException {FileInputStream file2=new FileInputStream("data/java.txt");byte []bytes=new byte[1024];//设置一个1kb大小的字节形式的数组作为缓冲区int len;while((len= file2.read(bytes))!=-1){//将读到的字节数储存在bytes数组中,并返回读取的字节数,返回值不为-1说明还有字节没读完System.out.print(new String(bytes,0,len));//将指定长度的字节数组转化为字符串}file2.close();}
}

字节缓冲流

在Java中有缓冲流内置了缓冲池,可以大大的提高读写效率
同时可以通过构造方法,扩大缓冲池的大小
但是需要注意:缓冲池的大小不是越大越好,在一定程度内可以提高提高读写效率
达到一定程度后,效率的提升就不是很明显了,反而会导致内存占用过多,得不偿失

package IO.File.Stream;public class Demo_BufferedStream{public static void main(String[] args) throws IOException{//1.创建字节缓冲,输入输出流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\a.flv"));BufferedOutputStream bos = new BufferedOutputStream(new FileInputStream("D:\\b.flv"));//2.读写操作int i;while((i=bis.read())!=-1){bos.write(i);}//3.关闭流释放资源bis.close();bos.close();}
}

补充1:文件操作+案例(File类的常用方法需要掌握)

package IO.File;import java.io.File;
import java.io.IOException;public class file_abilities {public static void main(String[] args) throws IOException {File f1 = new File("D:\\微信文件保存\\wx.txt");//在指定目录下创建文件(文件不存在就创建文件并返回true,存在就返回false  )System.out.println(f1.createNewFile());
//        delete()方法用于删除文件/目录(相对路径和绝对路径)File f2=new File("D:\\微信文件保存\\JavaSE");//创建单级目录System.out.println(f1.mkdir());File f3=new File("D:\\微信文件保存\\JavaWeb\\HTML");System.out.println(f3.mkdirs());//创建多级目录}
}

文件查询案例 -----结合此案例可以更好的理解并熟悉File类相应的方法与操作

package IO.File.Stream;import java.io.File;
import java.io.IOException;public class SearchFile {public static void main(String[] args) throws IOException {//需要在哪个文件夹中查询File f1 = new File("D:/");search(f1, "Whale.exe");}public static void search(File f1, String name) throws IOException {if (f1.isFile() || !f1.exists() || f1 == null) {System.out.println("无法搜索!!!");return;}File[] files = f1.listFiles();////文件夹不为空且里面有文件if (files != null && files.length > 0) {for (File e : files) {if (e.isFile()) {//关键操作if (e.getName().contains(name)) {System.out.println("搜索成功,文件路径为:" + e.getAbsolutePath());//如果需要查询并打开,可以添加如下语句,执行相应的程序
//                        Runtime run=Runtime.getRuntime();
//                        run.exec(e.getAbsolutePath());}} //递归操作else {search(e, name);}}}}
}

补充2:输出语句的重定向

System.out.println();相信大家都很熟悉了,那out是什么呢?
out其实是一个输出流对象,默认时out的值null,故默认我们输出到的时控制台
但我们可以通过System类的setout方法对输出语句重定向更新为新的输出流对象,从而达到相应的开发目的
下面的案例就是一个很好的体现:

package IO.File.Stream;import java.io.IOException;
import java.io.PrintStream;
//输出语句的重定向
public class printstream {public static void main(String[] args) {System.out.println("老骥伏枥");//默认out为null->consoletry (PrintStream printStream = new PrintStream("data/TX.txt")) {System.setOut(printStream);//重新设置out对象System.out.println("志在千里");}catch (IOException e){e.printStackTrace();}}
}

补充3:数据输出流的实际使用案例

在这里推荐大家在I/O流中的异常处理中使用try-with-resource语句,而不是直接抛出异常
这样可以避免忘记释放资源导致文件读写失败,同时又处理了异常
为以后的开发保持一个良好的习惯

package IO.File.Stream;import java.io.*;public class otherbytestream {public static void main(String[] args) {File file = new File("java.txt");
//   DataInputStream本身还是一种字节输入流(数据流),但相较于fileinputstream他拥有可以自动解析编码的方法(方便写基本数据类型的数据)try(DataOutputStream dataOutputStream=new DataOutputStream(new FileOutputStream(file))){dataOutputStream.writeInt(111);}catch (IOException e){e.printStackTrace();}try(DataInputStream dataInputStream=new DataInputStream(new FileInputStream(file))){System.out.println(dataInputStream.readInt());}catch(IOException e){e.printStackTrace();}}
}

补充4:对象输出流实际使用案例分析

对对象的读写操作,要求该对象是可序列化的/反序列化
在Java中提供了相应的接口可以为对象实现序列化操作
如果对象中的某个成员不想序列化可以通过transient修饰来解决

package IO.object;import java.io.Serializable;public class User implements Serializable {private String name;private String password;private int num;private char gender;public User() {}public User(int num, char gender, String name, String password) {this.num=num;this.gender=gender;this.name=name;this.password=password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getNum() {return num;}public void setNum(int num) {this.num = num;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}@Overridepublic String toString() {return num+","+gender+","+name+","+password;}
}
package IO.object;import java.io.*;
//对象的读取操作
public class objecttest1 {public static void main(String[] args) {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("data/object.txt"))) {User user=new User(1,'男',"YK0307","1243566");objectOutputStream.writeObject(user);}catch (IOException e){e.printStackTrace();}try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("data/object.txt"))) {//返回是是Object类型的,需要强制转化为User类型的User user1=(User) objectInputStream.readObject();System.out.println(user1);}catch (Exception e){e.printStackTrace();}}
}

更多推荐

Java之I/O流

本文发布于:2024-03-04 02:35:08,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1708040.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!