文章目录 前言一、IO流的分类二、流的原理及流的数量三、Java IO流对象1. 输入字节流InputStream2. 输出字节流OutputStream 前言 "io流"(Inpu
"io流"(Input/Output stream)指的是Java中用于处理输入输出(I/O)数据的机制。
在Java中,所有的输入和输出都被抽象为“流”对象,并通过输入流读取数据、输出流写入数据。
Java的I/O包提供了丰富的类和方法来支持不同类型的流,输入流和输出流之间可以自由地进行转换。它们分别主要包括字节流和字符流两种类型。其中,字节流是操作二进制数据的流,
可以处理任何类型的数据,常见的例如InputStream和OutputStream;字符流则是处理字符数据的流,其主要使用Reader和Writer接口。
Java中的IO流可以对文件、网络套接字等的数据进行读写操作,这些操作涉及到打开、关闭、查找、修改和删除文件、创建及维护网络连接等等一系列活动。因此,掌握Java中IO流的知识,有助于我们实现更加高效准确地操作文件、网络数据等各种实用应用。
可以从三个不同的维度进行分类:
• 1、按照流的方向(输出输入都是站在程序所在内存的角度划分的)
• 输入流:只能从中读取数据【主要由InputStream和Reader作为基类】
• 输出流:只能向其写入数据【主要由outputStream和Writer作为基类】
• 2、按照流的操作颗粒度划分
• 字节流:以字节为单元,可操作任何数据【主要由InputStream和outPutStream作为基类】
• 字符流:以字符为单元,只能操作纯字符数据,比较方便【主要由Reader和Writer作为基类】
• 3、按照流的角色划分
• 节点流:可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,也叫【低级流,主要由】
• 处理流:用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能,也叫【高级流】
• 1、流的原理解析
流其实我们可以想象成一个“水管”,源端和目的端就是两个“水桶”,数据是通过这个“水管”进行流动传输的,以InputStream和Reader为例,水管的每个“水滴”就是具体的数据,如果是字节流,那么一个“水滴”就是一个字节,如果是字符流,那么一个“水滴”就是一个字符。
当创建一个流对象的时候,如fis=new FileInputStream(“…\xx\xx.txt”),记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从InputStream或者Reader里面取出一个或者多个“水滴”后,记录指针自定向后移动;除此之外,InputStream和Reader里面都提供了一些方法来控制记录指针的移动。
2. java的流的图结构:
定义和结构说明:
InputStream 是所有的输入字节流的父类,它是一个抽象类。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。
意思是FileInputStream类可以通过一个String路径名创建一个对象,FileInputStream(String name)。而DatainputStream必须装饰一个类才能返回一个对象,DataInputStream(InputStream in)。
【案例 】读取文件内容
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; in.read(b); in.close(); System.out.println(new String(b)); }}
注意:
该示例中由于b字节数组长度为1024,如果文件较小,则会有大量填充空格。我们可以利用in.read(b);的返回值来设计程序,如下案例:
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; int len=in.read(b); in.close(); System.out.println("读入长度为:"+len); System.out.println(new String(b,0,len)); }}
注意:
观察上面的例子可以看出,我们预先申请了一个指定大小的空间,但是有时候这个空间可能太小,有时候可能太大,我们需要准确的大小,这样节省空间,那么我们可以这样做:
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[(int)f.length()]; in.read(b); System.out.println("文件长度为:"+f.length()); in.close(); System.out.println(new String(b)); }}
注意:
有时候我们不知道文件有多大,这种情况下,我们需要判断是否独到文件的末尾。
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; int count =0; int temp=0; while((temp=in.read())!=(-1)){ b[count++]=(byte)temp; } in.close(); System.out.println(new String(b)); }}
定义和结构说明:
OutputStream 是所有的输出字节流的父类,它是一个抽象类。
ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,
ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。具体例子跟InputStream是对应的。
1.向文件中写入字符串
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); OutputStream out =new FileOutputStream(f); String str="Hello World"; byte[] b=str.getBytes(); out.write(b); out.close(); }}
2.向文件中追加新内容
import java.io.*;class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); OutputStream out =new FileOutputStream(f,true);//true表示追加模式,否则为覆盖 String str="Rollen"; //String str="\r\nRollen"; 可以换行 byte[] b=str.getBytes(); for (int i = 0; i < b.length; i++) { out.write(b[i]); } out.close(); }}
3. 复制文件
import java.io.*;class hello{ public static void main(String[] args) throws IOException { if(args.length!=2){ System.out.println("命令行参数输入有误,请检查"); System.exit(1); } File file1=new File(args[0]); File file2=new File(args[1]); if(!file1.exists()){ System.out.println("被复制的文件不存在"); System.exit(1); } InputStream input=new FileInputStream(file1); OutputStream output=new FileOutputStream(file2); if((input!=null)&&(output!=null)){ int temp=0; while((temp=input.read())!=(-1)){ output.write(temp); } } input.close(); output.close(); }}
3.缓存流的使用(BufferedInputStream/BufferedOutputStream,BufferedReader/BufferedWriter)
import java.io.*;public class TestBufferStream {public static void main (String[] args) throws IOException{BufferedInputStream bis=null;BufferedOutputStream bos=null;try {FileInputStream fis = new FileInputStream("C:\\Users\\41639\\Desktop\\java\\FileText\\src\\TestFileImportStream.java");FileOutputStream fos = new FileOutputStream("C:\\Users\\41639\\Desktop\\java\\temp\\out2.java");bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);byte[] b = new byte[1024];int off=0;while ((off=bis.read(b))>0) {bos.write(b,0,off);}bis.close();bos.close();}catch (IOException e) {e.printStackTrace();}finally {bis.close();bos.close();}}}
他们最基本的其实也是FileInputStream和FileOutputStream,在这个“流”的基础上,又加了缓存的功能流BufferedInputStream和BufferedOutputStream。
4.转换流的使用(InputStreamReader/OutputStreamWriter)
字面意思理解,转化流就是用来转化的,那么到底是什么转什么呢?我们可以通过以下的例子来熟悉。读取键盘输入的每一行内容,并写入到文本中,直到遇到over行结束输入
public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\41639\\Desktop\\java\\temp\\test1031.txt"));String line =null;while ((line=br.readLine())!=null) {if ("over".contentEquals(line)) {break;}bw.write(line);bw.newLine();bw.flush();} bw.close(); br.close();}
5.对象流的使用(FileInputStream/ObjectOutputStream)
import java.io.*;public class ObjectStreamTest {public static void main(String[] args) throws Exception{try {Person P=new Person("Jeccica",26);FileOutputStream fos=new FileOutputStream("C:\\Users\\admin\\Desktop\\Java\\temp\\22.txt");ObjectOutputStream oos=new ObjectOutputStream(fos);oos.writeObject(P);oos.flush();oos.close();}catch(FileNotFoundException e) {e.printStackTrace();}catch(IOException e) {e.printStackTrace();}FileInputStream fis=new FileInputStream("C:\\Users\\admin\\Desktop\\Java\\temp\\22.txt");ObjectInputStream ois=new ObjectInputStream(fis);Person P2=(Person)ois.readObject();System.out.println(P2.name+"的年龄为"+P2.age);}}class Person implements Serializable{String name=null;int age=0;Person(String _name,int _age){name=_name;age=_age;}}
字节数组流的使用(ByteArrayInputStream/ByteArrayOutputStream)【通常结合数据流DataInputStream/DataOutputStream】
public static void main(String[] args) {ByteArrayOutputStream baos=new ByteArrayOutputStream();//创建字节数组流,同时会在内存里面创建数组DataOutputStream dos=new DataOutputStream(baos);//对字节数组流外封装成数据处理流try {dos.writeDouble(Math.random());//利用数据流里面的写入方法,写一个Double类型的随机数据dos.writeBoolean(true);ByteArrayInputStream bias=new ByteArrayInputStream(baos.toByteArray());//toByteArray()方法是创建一个新分配的字节数组。数组的大小和当前输出流的大小。这里指的是baos这个字节数组System.out.println(bias.available());DataInputStream dis=new DataInputStream(bias);System.out.println(dis.readDouble());System.out.println(dis.readBoolean());dos.close();dis.close();}catch (IOException e) {e.printStackTrace();}}
来源地址:https://blog.csdn.net/m0_68987535/article/details/131156724
--结束END--
本文标题: Java io流 详解
本文链接: https://lsjlt.com/news/411191.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-04-01
2024-04-03
2024-04-03
2024-01-21
2024-01-21
2024-01-21
2024-01-21
2023-12-23
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0