IO无疑是学习每一门语言都要求掌握的编程知识点,一些大型项目都离不开IO的支持,因此掌握IO相关操作,对以后的学习和工作都是很有必要的。IO知识说难不难,但是每到用的时候,我们都需要查阅,本文从Java语言面向对象的特点出发,讲述Java IO的一些知识,仅供参考。
IO 是以流的方式来组织和传播,与流水非常相似。从源头输出不断流淌输入到目的地,中间为了方便,可能还会加上水管来辅助输出,水量小的时候,一滴滴或者涓涓细流,这时候我们可以建筑水坝库存到一定量才释放,有的水流汇入江海,而有的则直接流入千家百户。
在Java IO体系中,根据流的成分不同,可以分为字符流和字节流两种;根据流向不同,可以分为输入流和输出流;根据源头不同,可以分为文件流和内存流;为了便于输出,Java也提供了管道流和缓存流;根据输出目的地不同,可以通过打印流来控制是输出到文件还是其他地方;为了支持序列化,Java还提供了对象流。为了支持数据的访问和保存,Java提供了数据流;为了支持文件的压缩与解压缩,Java提供了文件压缩与解压缩流。以下关于各个流的几个注意点:
1)以内存为参照:流入内存为输入流,流出内存,汇入外地,为输出流。
2)字符流是以字符为单位,主要处理文本文件;字节流以字节为传输单位,可以处理文本,语音和图像等任何信息,字节流的应用范围更广。Java提供了InputStreamReader和OutputStreamWriter来实现字符流与字节流的转换。
3)管道流主要解决进程间通信,应用不多。
4)缓存流为了数据的传输提供了一种包装的形式,例如BufferedReader则提供了readLine()方法,可以更好地处理数据的流通。
5)打印流需要制定流向,可以流向屏幕,可以流向文件,在构造的时候进行装填即可。
6)对象流无疑是将数据以对象的形式保存到文件或其他地方,提供了一种数据持久化方案,配合实现对象序列化,在很多大型项目都有非常重要的使用。
7)用于保存和读取数据,readInt或writeInt方法等
8)Scanner接收用户输入
9)文件压缩和解压缩流
1、下面以一个最简单的文件拷贝的例子,来说明字符流、字节流、输入流、输出流、包装流、打印流的使用。需要注意的时候,在程序执行完,需要关闭打开的所有流。
class FileCopy{ public static void copyByChar(String srcFilePath, String desFilePath){ File srcFile = null; File desFile = null; BufferedReader br = null; PrintWriter pw = null; try{ srcFile = new File(srcFilePath); desFile = new File(desFilePath); br = new BufferedReader(new FileReader(srcFile)); pw = new PrintWriter(new FileWriter(desFile)); String temp = null; while((temp = br.readLine()) != null){ pw.println(temp); pw.flush(); } }catch(Exception e){ e.printStackTrace(); }finally{ try{ pw.close(); br.close(); }catch(Exception e){ e.printStackTrace(); } } System.out.println("copy file by char done"); } public static void copyByByte(String srcFilePath, String desFilePath){ File srcFile = null; File desFile = null; InputStream is = null; OutputStream os = null; try{ srcFile = new File(srcFilePath); desFile = new File(desFilePath); is = new FileInputStream(srcFile); os = new FileOutputStream(desFile); byte buf[] = new byte[1024]; int len = 0; while((len = is.read(buf)) != -1){ os.write(buf,0,len); os.flush(); } }catch(Exception e){ e.printStackTrace(); }finally{ try{ os.close(); is.close(); }catch(Exception e){ } } System.out.println("copy file by byte done"); } }
2、测试内存流
public static void testByArrayStream(String str){ ByteArrayInputStream bais = null; ByteArrayOutputStream baos = null; try{ bais = new ByteArrayInputStream(str.getBytes()); baos = new ByteArrayOutputStream(); for(int i=0;i<str.length();i++){ char c = (char)bais.read(); baos.write(Character.toUpperCase(c)); } System.out.println(baos.toString()); /* byte buf[] = new byte[1024]; int len = bais.read(buf); baos.write(buf,0,len); System.out.println(baos.toString().toUpperCase()); */ }catch(Exception e){ e.printStackTrace(); } }
3、测试管道流
class Sender implements Runnable { private PipedOutputStream out = null; public Sender(){ out = new PipedOutputStream(); } public PipedOutputStream getOut(){ return out; } public void run(){ String message = "hello, moto"; try{ out.write(message.getBytes()); }catch(Exception e){ e.printStackTrace(); }finally{ try{ out.close(); }catch(Exception e){ } } } } class Receiver implements Runnable { private PipedInputStream in = null; public Receiver(){ in = new PipedInputStream(); } public PipedInputStream getIn(){ return in; } public void run(){ byte buf[] = new byte[1024]; int len = 0; try{ len = in.read(buf); }catch(Exception e){ e.printStackTrace(); }finally{ try{ in.close(); }catch(Exception e){ } } System.out.println("recevied:" + new String(buf,0,len)); } }
以上是发送线程和接收线程,为了支持线程通信,需要使用PipedOutpuStream的connect方法连接PipedInputStream。
public static void testPipedStream(){ Sender sender = new Sender(); Receiver receiver = new Receiver(); try{ sender.getOut().connect(receiver.getIn()); }catch(Exception e){ e.printStackTrace(); } new Thread(sender).start(); new Thread(receiver).start(); }
4、Scanner接收用户输入
public static void testScaner(){ Scanner sc = new Scanner(System.in); String name = sc.next(); int age = sc.nextInt(); System.out.println("name="+name+" age="+age); }
5、测试文件压缩流
public static void testFileZip(String srcFilePath, String zipFilePath){ File file = null; InputStream in = null; ZipOutputStream zipOut = null; try{ file = new File(srcFilePath); in = new FileInputStream(file); zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath)); zipOut.putNextEntry(new ZipEntry(file.getName())); zipOut.setComment("hello world"); int temp = 0; while((temp = in.read()) != -1){ zipOut.write(temp); } }catch(Exception e){ e.printStackTrace(); }finally{ try{ zipOut.close(); in.close(); }catch(Exception e){ e.printStackTrace(); } } System.out.println("zip done"); }
6、测试文件解压缩流
public static void testFileUnZip(String zipFilePath){ File file = null; File outFile = null; ZipFile zipFile = null; ZipInputStream zipIn = null; ZipEntry entry = null; InputStream in = null; OutputStream out = null; try{ file = new File(zipFilePath); zipFile = new ZipFile(file); zipIn = new ZipInputStream(new FileInputStream(file)); while((entry = zipIn.getNextEntry()) != null){ System.out.println("un zip " +entry.getName()); outFile = new File("./unzip/" + entry.getName()); if(!outFile.getParentFile().exists()){ outFile.getParentFile().mkdir(); } if(!outFile.exists()){ outFile.createNewFile(); } in = zipFile.getInputStream(entry); out = new FileOutputStream(outFile); int temp = 0; while((temp = in.read()) != -1){ out.write(temp); } } }catch(Exception e){ e.printStackTrace(); }finally{ try{ out.close(); in.close(); zipIn.close(); }catch(Exception e){ e.printStackTrace(); } } System.out.println("un zip done"); }
以上几乎包含了所有Java Io流的操作,关于对象流及其支持的序列化与反序列化特性将在后面介绍。