概述
Java IO是一套Java 用来读写数据(输入和输出)的API,大部分程序都需要处理一些输入,并由输入产生一些输出(PS: 输入和输出是相对CPU而言的,input 就是从外面到CPU,output就是从CPU到外面,CPU是主人公)。java.io 包下有大约80多个类,大概可以分成四组:
1.基于字节操作的I/O接口: InputStream和OutputStream
2.基于字符操作的I/O接口:Writer和Reader
3.基于磁盘操作的I/O接口:File
4.基于网络操作的I/O接口:Socket
java.io 包下的类如下:
File类
Java IO API中的File类可以让你访问底层文件系统,通过File类。你可以做到如下几点:
1.检测文件是否存在 (file.exists())
2.读取文件长度 (file.length())
3.重命名或者移动文件(file.renameTo(new File(“c:\data\new-file.txt”));)
4.删除文件(file.delete())
5.检测某个路径是文件还是目录。(file.isDirectory())
6.读取目录中的文件列表。(String[] fileNames = file.list())
PS: 在项目中用相对路径读取文件
运用相对路径读取文件,其实就是要找到Java编译(class 文件所在的目录)后的存放目录,然后在该目录下找文件。读取方法有如下两种。
public class RelativePath { public static void main(String[] args) { // 方法一 String fileName = ReaderTest.class.getResource("/inputTest.txt").getFile(); System.out.println("*****方法一相对路径读取到的文件地址:"+fileName); // 方法二 String fileName1 = Thread.currentThread().getContextClassLoader().getResource("inputTest.txt").getFile(); System.out.println("*****方法二相对路径读取到的文件地址:"+fileName1); } }
运行结果:
输入和输出
输入流 用来表示那些从不同数据源产生输入的类。这些数据源包括:
1.字节数组
2.String 对象
3.文件
4.“管道”,工作方式与实际管道类似,即,从一端输入,从另一端输出
5.一个由其他种类的流组成的序列,以便我们可以将它们收集合并到一个流内
输出流: 决定输出所要去往的目标,目标包括:
字节数组
文件
管道
基于字节操作的I/O接口: InputStream和OutputStream
InputStream 的类图
每个子类的功能以及使用如下图表所示:
运用InputStream的实现类读取文件
1.方法1️⃣
/** * 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。 * 当然也是可以读字符串的。 * * @param fileName */ public static void readString1(String fileName) throws IOException { // FileInputStream 用于读取诸如图像数据之类的原始字节流,读取字符流,请使用FileReader InputStream is = new FileInputStream(fileName); StringBuilder stringBuilder; try { stringBuilder = new StringBuilder(); byte[] bytes = new byte[1024]; int len; while ((len=is.read(bytes))>0) { stringBuilder.append(bytes,0,len); } } finally { if (is != null) { is.close(); } } System.out.println("读取到的结果:" + stringBuilder.toString()); }
2.方法2️⃣
/** * 按字节读取字符串,一次性读取完 * @param fileName * @throws IOException */ public static void readString2(String fileName) throws IOException { InputStream inputStream = new FileInputStream(fileName); try { // size 为字串的长度 ,这里一次性读完 byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); System.out.println("读取到的结果是:"+new String(bytes,"UTF-8")); } finally { if (inputStream != null) { inputStream.close(); } } }
按行读取数据
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file),"UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); while (StringUtils.isNotBlank(line = bufferedReader.readLine())) { System.out.println("读取到的结果是:"+line); }
OutputStream 的类图
每个子类的功能和使用如下图表所示:
运用OutputStream的实现类写入文件
1.方法1️⃣
使用FileOutputStream进行写入。
/** * 使用FileOutputStream * @param file * @throws IOException */ public static void writeStringToFile1(File file) throws IOException { FileOutputStream fos = new FileOutputStream(file); try { fos.write("www.jay".getBytes()); fos.flush(); } finally { if (fos != null) { fos.close(); } } }
2.方法2️⃣
使用PrintStream进行写入
/** * 使用PrintStream写入 * @param file * @throws FileNotFoundException */ public static void writeStringToFile2(File file) throws FileNotFoundException { PrintStream printStream = null; try { printStream = new PrintStream(new FileOutputStream(file)); printStream.append("你好"); printStream.append("java"); } finally { if (printStream != null) { printStream.close(); } } }
3.方法3
通过 IOUtil 进行数据操作
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); IOUtils.copy(inputStream, outputStream); byte[] buffer=outputStream.toByteArray()
或者
byte[] buff = new byte[1024]; BufferedInputStream bis = null; OutputStream os = null; try { os = new ByteArrayOutputStream(); bis = new BufferedInputStream(stream); int len; while ((len = bis.read(buff)) >0) { os.write(buff, 0, len); } os.flush(); }catch (IOException e) { e.printStackTrace(); } finally { if (bis != null) { IOUtils.closeQuietly(bis); } IOUtils.closeQuietly(os); }
基于字符操作的I/O接口:Writer和Reader
Reader 和Writer 与InputStream和OutputStream 的最大区别是,InputStream和OutputStream是基于字节操作的I/O接口。而Reader 和Writer是基于字符操作I/O 接口。通过InputStreamReader适配器可以把InpuStream转换成Reader。通过OutputStreamWriter 适配器可以把OutputStream 转换成Writer。
如下图表示在两个继承层次结构中,信息的来源于去处。
Reader 的类图
运用Reader的实现类读取文件内容(只能读取字符流)
1.方法1️⃣
public static void readFileToString1(String fileName ) throws IOException { File file = new File(fileName); FileReader fileReader = new FileReader(file); int length = Integer.valueOf(String.valueOf(file.length())); //定义一个大小等于文件大小的字符数组 char[] chars = new char[length]; StringBuilder str = new StringBuilder(); try { int data; while ((data=fileReader.read(chars))>0) { System.out.println("读取到的字符是="+data); str.append(chars); } System.out.println("读取到的结果:"+str.toString()); } finally { if (fileReader != null) { fileReader.close(); } } }
2.方法2️⃣
/** * InputStreamReader+BufferedReader读取字符串 , * InputStreamReader类是从字节流到字符流的桥梁, * 按行读对于要处理的格式化数据是一种读取的好方式 * @param fileName * @throws IOException */ public static void readFileToString2(String fileName) throws IOException { BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName)); try { StringBuilder stringBuilder = new StringBuilder(); String data = null; while ((data = bufferedReader.readLine()) != null) { stringBuilder.append(data); } System.out.println("读取到的结果:"+stringBuilder.toString()); } finally { if (bufferedReader != null) { bufferedReader.close(); } } }
Writer 的类图
运用Writer的实现类写入内容到文件
1.方法1️⃣
/** * 使用BufferedWriter写入 * @param file * @throws IOException */ public static void writeStringToFile1(FileWriter file) throws IOException { BufferedWriter bufferedWriter = new BufferedWriter(file); bufferedWriter.append("bufferedWriter"); bufferedWriter.append("测试2111"); bufferedWriter.close(); }
2.方法2️⃣
/** * 使用PrintWriter写入 * @param fileWriter * @throws IOException */ public static void writeStringToFile2(FileWriter fileWriter) throws IOException { PrintWriter printWriter = new PrintWriter(fileWriter); printWriter.append("printWriter"); printWriter.append("实验"); printWriter.close(); }
3.方法三
利用字节流向文件中写入数据。
//创建文件 File file = new File("test.txt"); //写入数据 OutputStream os = null; try { os = new FileOutputStream(file); String testStr = new String("I LOVE YOU"); os.write(testStr.getBytes()); os.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (os != null) { os.close(); } }
总结
本文首先介绍了java.io 包中的重要接口和类,如InputStream接口,OutputStream接口,Reader接口和Writer接口。然后,通过几个小demo阐述了如何运用这些接口的实现类来操作文件。希望多读者朋友有所帮助。
源代码
https://github.com/XWxiaowei/JavaCode/tree/master/io-study-demo