整理 JAVA中的IO流 (字符流和字节流两个大类)
发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,java中的io流分为两类,字符和字节:OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。Writ
千家信息网最后更新 2024年09月22日整理 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安全错误
数据库的锁怎样保障安全
鸿信网络技术工作室存在吗
以色列网络安全系统排名
广东江门erp软件开发
虹口区专业软件开发质量保障
高中教务系统软件开发
下拉服务器
金蝶服务器端改客户端
网络安全人才渠口
企业服务器价格表
维普数据库怎么查找专业领域
网络安全法宣传标语图片
oracle数据库部署文档
计算机学软件就是软件开发吗
网络安全专业技术资格考试
数据库当中有哪些技术
天成网络技术开发公司
10万台服务器
数据库引用字段怎么找到
对软件开发大概了解多少
北京字跳动网络技术有限公司
mysql数据库求和
永盟网络技术有限公司官网
数据库审计技术加密
飞书怎么软件开发
最新nvidia服务器显卡
重庆邮电网络安全课程试卷
质量网络技术开发
学计算机网络技术需要配电脑吗
什么叫串口服务器
晋城感严网络技术有限公司