整理 JAVA中的IO流 (字符流和字节流两个大类)
发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,java中的io流分为两类,字符和字节:OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。Writ
千家信息网最后更新 2024年11月29日整理 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安全错误
数据库的锁怎样保障安全
网络安全主要是干嘛
网络安全检查报告几个
国云网络技术有限
开封php服务器
云服务器存储空间多少T
软件开发概要设计文档范例
天马网络安全手抄报
应用软件开发的一般流程
关于数据库的安全性不
数据库中日期拼接函数
网络安全答案2021
软件开发名片设计
软件开发工程师层级
上海无线网络技术创新服务
计算机网络技术专业的自我
个人网络安全发声承诺书
校园网设计网络安全需求
东莞软件开发驻厂费用
关于核酸数据库论文
核鑫网络技术有限公司
神通数据库服务器名
浙江软件开发解决方案定制
软件开发纠纷起诉期
光遇可以转服务器吗
戴尔存储服务器中小企业
设计博客所用数据库知识
渝北区有哪些软件开发公司
wow地区服务器
单位维护网络安全
保定民宿软件开发