整理 JAVA中的IO流 (字符流与字节流两个大类)
发布时间:2023-06-16 14:02:53 所属栏目:教程 来源:
导读:java中的io流分为两类,字符和字节:
OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。
Writer和Reader字符流的父类,抽象。
实际上在流的操作中,底层
OutputStream和InputStream字节流的父类,抽象。OutputStream有两个提供了实现的接口closable和flushable。
Writer和Reader字符流的父类,抽象。
实际上在流的操作中,底层
|
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来转换字节流给字符流使用。还有BufferedWriter class 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}$")。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
