整理 JAVA中的IO流 (字符流和字节流两个大类)
发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,java中的io流分为两类,字符和字节:OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。Writ
千家信息网最后更新 2025年01月23日整理 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安全错误
数据库的锁怎样保障安全
数据网络技术排名靠前
建设服务器的图片
股票行情分析软件开发股
5g网络技术面临十大挑战
河南特种网络技术推广
软件开发及应用期刊
怎么查询数据库的列名
数据库免费建造
软件开发转正ppt怎么写
.网络安全生态
数据库到底是干什么的
数据库储存怎么
数学软件开发概述
黄浦区智能化软件开发厂家批发价
软件开发前期需求文档怎么写
网络技术师能为国家做什么贡献
遵义市网络技术人员
数据库查询多个课程平均分
学校开展网络安全教育新闻
挖矿软件开发公司
网络安全系统的技术漏洞
5g网络技术面临十大挑战
数据库自增主键优点
将树莓派挂在服务器上
澳门网络安全法解读
岩土数据库规范编制
ibm7914服务器
湖北鸣客网络技术公司怎么样
怎么在同一个地址下复制数据库
中学生网络安全说课稿