整理 JAVA中的IO流 (字符流和字节流两个大类)
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,java中的io流分为两类,字符和字节:OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。Writ
千家信息网最后更新 2025年12月02日整理 JAVA中的IO流 (字符流和字节流两个大类)
java中的io流分为两类,字符和字节:
- OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。
- Writer和Reader字符流的父类,抽象。
实际上在流的操作中,底层与文件进行读写的都是字节流,因为即使是字符流的对象,其最终实现读写的也是用的字节流。
- 操作文件的字节子类FileOutputStream和FileInputStream。
记住,这里面写出和读入的都是字节。
class useByteStream{ /** * 使用文件输出字节流 * */ public static void testFileOutputStream() { OutputStream out = null; try { File f = new File(".\\log\\test.txt"); //out = new FileOutputStream(f); out = new FileOutputStream(f,true); //追加方式记录到文件 String str = "Hello World!!!"; byte b[] = str.getBytes(); out.write(b); out.close(); } catch(FileNotFoundException e) { } catch(IOException e) { } } /** * 使用文件输入字节流 */ public static void testFileInputStream() { InputStream out = null; try { File f = new File(".\\log\\test.txt"); out = new FileInputStream(f); String str = "Hello World!!!"; byte b[] = new byte[1000]; int len = out.read(b); System.out.println(new String(b,0, len) ); out.close(); } catch(FileNotFoundException e) { } catch(IOException e) { } }};- 操作文件的字符子类FileWriter和FileReader
class useCharStream{ /** * 使用文件字符输出流 */ public static void testFileWriter() { Writer w = null; try { File f = new File(".\\log\\test2.txt"); w = new FileWriter(f,true); //追加方式 w.write("hello world\r\n"); w.close(); } catch(FileNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } /** * 使用文件字符输入流 */ public static void testFileReader() { Reader w = null; try { File f = new File(".\\log\\test2.txt"); w = new FileReader(f); char c[] = new char[1024]; w.read(c); System.out.println(c); w.close(); } catch(FileNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } }};两个转换类,OutputStreamWriter,负责将写入字符流转为字节流,InputStreamReader,负责读取字节流转为字符流。
FileWriter的直接父类是OutputStreamWriter,并非Writer。
FileReader的直接父类是InputStreamReader,并非Reader。
因此,最终写入文件和从文件读出的都是字节流。以上都是基于文件流操作,接下来是基于内存操作流,如果只是写业务代码应该很少会用到。
- 内存操作流
ByteArrayInputStream\ByteArrayOutputStream。
class useMemoryStream{ /** * 使用内存操作流,字节 */ public static void testByteArray() { String str = "Hello world"; ByteArrayInputStream bis = null; ByteArrayOutputStream bos = null; bis = new ByteArrayInputStream(str.getBytes()); bos = new ByteArrayOutputStream(); int temp =0; while((temp=bis.read())!=-1) { char c = (char)temp; bos.write(Character.toUpperCase(c)); } String newStr = bos.toString(); try { bis.close(); bos.close(); } catch(IOException e) { e.printStackTrace(); } System.out.println(newStr); }};- 另外,管道流可以实现两个线程之间的通信。
PipedInputStream 和 PipedOutputStream。
PipedOutputStream通过connect方法与PipedInputStream建立连接,后续PipedOutputStream.write的内容,就会PipedInputStream.read方法读取
class Send implements Runnable{ private PipedOutputStream pos = null; public Send() { this.pos = new PipedOutputStream(); } public void run() { String str = "Hello world!!!"; try { try { Thread.sleep(2000); } catch(InterruptedException e) { e.printStackTrace(); } this.pos.write(str.getBytes()); System.out.println("thread:"+Thread.currentThread().getId()+",Send string:"+str); } catch(IOException e) { e.printStackTrace(); } try { this.pos.close(); } catch(IOException e) { e.printStackTrace(); } } public PipedOutputStream getPos() { return this.pos; }};class Receive implements Runnable{ private PipedInputStream pis = null; public Receive() { this.pis = new PipedInputStream(); } public void run() { byte b[] = new byte[1024]; int len =0; try { len = this.pis.read(b); //阻塞方式 } catch(IOException e) { e.printStackTrace(); } try { pis.close(); } catch(IOException e) { e.printStackTrace(); } System.out.println("thread:"+Thread.currentThread().getId()+",receive:"+new String(b,0,len)); } public PipedInputStream getPis() { return this.pis; }};class pipedTest{ public void pipedStream() { Send s = new Send(); Receive r = new Receive(); try { s.getPos().connect(r.getPis()); } catch(IOException e) { e.printStackTrace(); } new Thread(r).start(); new Thread(s).start(); }};以上都是无缓存的,考虑到一般场景下,提高使用性能,最好使用有缓存的字符流:BufferedReader和BufferedWriter。
BufferedReader
只能接受输入为字符流,不能为字节流。所以有时候会使用InputStreamReader来转换字节流给字符流使用。还有BufferedWriterclass useBuffer{ public static void testBufferReader() { BufferedReader buf = null; //此处用到了字节流转字符流的类InputStreamReader,这是因为BufferedReader只能接收字符流 buf = new BufferedReader(new InputStreamReader(System.in)); String str =null; try { str = buf.readLine(); } catch(IOException e) { e.printStackTrace(); } System.out.println("输出的内容为:"+str); } public static void testBufferWriter() { File f = new File(".\\log\\test2.txt"); try { //默认缓冲区大小 8K 可以通过 new BufferedWriter(new FileWriter(f),1024);指定大小为1K BufferedWriter out =new BufferedWriter(new FileWriter(f)); out.write("123321123355555", 0, 10); out.write("\r\n"); out.close(); } catch (IOException e) { e.printStackTrace(); } }};SCanner类,输入数据类。
使用方法和BufferedReader类类似,并且方便验证数据类型。class useScan{ public static void testScan() { Scanner scan = new Scanner(System.in); //以回车作为输入的结束符号,否则默认是空格 scan.useDelimiter("\r\n"); if(scan.hasNextInt()==true) { int str = scan.nextInt(); System.out.println("int "+str); } else { String str = scan.next(); System.out.println("string "+str); } }};scan.hasNext支持正则表达式。比如hasNext("^\\d{4}-\\d{2}-\\d{2}$")就是日期格式yyyy-MM-dd的正则表达式,通过next("^\\d{4}-\\d{2}-\\d{2}$")。
字符
文件
字节
输入
两个
内存
方式
方法
输出
内容
大小
子类
数据
正则
缓存
表达式
流转
接下来
业务
之间
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
唯一网络技术
碧蓝航线各服务器兑换
暑期网络安全小报
食安网络安全
宁波互动博物馆软件开发
益阳串口服务器怎么收费
如果网络安全实名制
网络安全专业工作方向
isc在网络安全是什么意思
宁波动能服务器价格
mc小游戏服务器ip大全
抢占数据库
网络安全工作忙吗
网络安全事件2022年
数据库表无法导入的解决方法
国家网络安全宣传自查
服务器ip安全策略禁端口
软件开发实用的试题
dbms对数据库的安全
明日之后各个服务器如何刷金条
国内网络技术排名
网络安全的现状与隐患
mac学习数据库
万方数据库检索
数据库中的信息服务如何勾选
ais船舶软件开发源码
淘宝租我的世界怎么租服务器
网络服务器性能
商城网站用什么服务器好
不需要备案的云服务器