Java回顾之I/O
我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容。
工作后,使用的技术随着项目的变化而变化,时而C#,时而Java,当然还有其他一些零碎的技术。总体而言,C#的使用时间要更长一些,其次是Java。我本身对语言没有什么倾向性,能干活的语言,就是好语言。而且从面向对象的角度来看,我觉得C#和Java对我来说,没什么区别。
这篇文章主要回顾Java中和I/O操作相关的内容,I/O也是编程语言的一个基础特性,Java中的I/O分为两种类型,一种是顺序读取,一种是随机读取。
我们先来看顺序读取,有两种方式可以进行顺序读取,一种是InputStream/OutputStream,它是针对字节进行操作的输入输出流;另外一种是Reader/Writer,它是针对字符进行操作的输入输出流。
下面我们画出InputStream的结构
- FileInputStream:操作文件,经常和BufferedInputStream一起使用
- PipedInputStream:可用于线程间通信
- ObjectInputStream:可用于对象序列化
- ByteArrayInputStream:用于处理字节数组的输入
- LineNumberInputStream:可输出当前行数,并且可以在程序中进行修改
下面是OutputStream的结构
- PrintStream:提供了类似print和println的接口去输出数据
下面我们来看如何使用Stream的方式来操作输入输出
- 使用InputStream读取文件
1 public static byte[] readFileByFileInputStream(File file) throws IOException 2 { 3 ByteArrayOutputStream output = new ByteArrayOutputStream(); 4 FileInputStream fis = null; 5 try 6 { 7 fis = new FileInputStream(file); 8 byte[] buffer = new byte[1024]; 9 int bytesRead = 0; 10 while((bytesRead = fis.read(buffer, 0, buffer.length)) != -1) 11 { 12 output.write(buffer, 0, bytesRead); 13 } 14 } 15 catch(Exception ex) 16 { 17 System.out.println("Error occurs during reading " + file.getAbsoluteFile()); 18 } 19 finally 20 { 21 if (fis !=null) fis.close(); 22 if (output !=null) output.close(); 23 } 24 return output.toByteArray(); 25 }
1 public static byte[] readFileByBufferedInputStream(File file) throws Exception 2 { 3 FileInputStream fis = null; 4 BufferedInputStream bis = null; 5 ByteArrayOutputStream output = new ByteArrayOutputStream(); 6 try 7 { 8 fis = new FileInputStream(file); 9 bis = new BufferedInputStream(fis); 10 byte[] buffer = new byte[1024]; 11 int bytesRead = 0; 12 while((bytesRead = bis.read(buffer, 0, buffer.length)) != -1) 13 { 14 output.write(buffer, 0, bytesRead); 15 } 16 } 17 catch(Exception ex) 18 { 19 System.out.println("Error occurs during reading " + file.getAbsoluteFile()); 20 } 21 finally 22 { 23 if (fis != null) fis.close(); 24 if (bis != null) bis.close(); 25 if (output != null) output.close(); 26 } 27 return output.toByteArray(); 28 }
- 使用OutputStream复制文件使用FileOutputStream复制文件使用BufferedOutputStream复制文件
这里的代码对异常的处理非常不完整,稍后我们会给出完整严谨的代码。
下面我们来看Reader的结构
这里的Reader基本上和InputStream能够对应上。
Writer的结构如下
下面我们来看一些使用Reader或者Writer的例子
- 使用Reader读取文件内容
1 public static String readFile(String file)throws IOException 2 { 3 BufferedReader br = null; 4 StringBuffer sb = new StringBuffer(); 5 try 6 { 7 br = new BufferedReader(new FileReader(file)); 8 String line = null; 9 10 while((line = br.readLine()) != null) 11 { 12 sb.append(line); 13 } 14 } 15 catch(Exception ex) 16 { 17 System.out.println("Error occurs during reading " + file); 18 } 19 finally 20 { 21 if (br != null) br.close(); 22 } 23 return sb.toString(); 24 }
- 使用Writer复制文件
1 public static void copyFile(String file) throws IOException 2 { 3 BufferedReader br = null; 4 BufferedWriter bw = null; 5 try 6 { 7 br = new BufferedReader(new FileReader(file)); 8 bw = new BufferedWriter(new FileWriter(file + ".bak")); 9 String line = null; 10 while((line = br.readLine())!= null) 11 { 12 bw.write(line); 13 } 14 } 15 catch(Exception ex) 16 { 17 System.out.println("Error occurs during copying " + file); 18 } 19 finally 20 { 21 if (br != null) br.close(); 22 if (bw != null) bw.close(); 23 } 24 }
下面我们来看如何对文件进行随机访问,Java中主要使用RandomAccessFile来对文件进行随机操作。
- 创建一个大小固定的文件创建大小固定的文件
- 向文件中随机写入数据向文件中随机插入数据
接下里,我们来看一些其他的常用操作
- 移动文件移动文件
- 复制文件复制文件
- 复制文件夹复制文件夹
- 删除文件夹
1 public static void del(String filePath) 2 { 3 File file = new File(filePath); 4 if (file == null || !file.exists()) return; 5 if (file.isFile()) 6 { 7 file.delete(); 8 } 9 else 10 { 11 File[] arrFiles = file.listFiles(); 12 if (arrFiles.length > 0) 13 { 14 for(int i = 0; i < arrFiles.length; i++) 15 { 16 del(arrFiles[i].getAbsolutePath()); 17 } 18 } 19 file.delete(); 20 } 21 }
- 获取文件夹大小获取文件夹大小
- 将大文件切分为多个小文件将大文件切分成多个小文件
- 将多个小文件合并为一个大文件
1 public static void linkFiles(String countFile) throws IOException 2 { 3 File file = new File(countFile); 4 if (!file.exists()) throw new RuntimeException("Count file does not exist."); 5 BufferedReader reader = new BufferedReader(new FileReader(file)); 6 String line = reader.readLine(); 7 String newFile = line.split("\t")[0]; 8 long size = Long.parseLong(line.split("\t")[1]); 9 RandomAccessFile raf = new RandomAccessFile(newFile, "rw"); 10 raf.setLength(size); 11 FileInputStream fis = null; 12 byte[] buffer = null; 13 14 while((line = reader.readLine()) != null) 15 { 16 String[] arrInfo = line.split("\t"); 17 fis = new FileInputStream(new File(arrInfo[0])); 18 buffer = new byte[Integer.parseInt(arrInfo[2])]; 19 long startPos = Long.parseLong(arrInfo[1]); 20 fis.read(buffer, 0, Integer.parseInt(arrInfo[2])); 21 raf.seek(startPos); 22 raf.write(buffer, 0, Integer.parseInt(arrInfo[2])); 23 fis.close(); 24 } 25 raf.close(); 26 }
- 执行外部命令执行外部命令