java文件流

来源:互联网 发布:淘宝神笔怎么用 编辑:程序博客网 时间:2024/06/05 21:17

JAVA中的I/O流以及文件操作

一 JAVA语言中主要通过流来完成IO操作。

流:计算机的输入输出之间流动的数据序列,也是类的对象。java中的流方式就像是建立在数据交换源和目的之间的一条通信路径。

数据源:计算机中的数据源是指可以提供数据的地方,包括键盘,磁盘文件,网络接口等。

输入流:从程序外部传向程序的流。输入流只能从中读数据。

输出流: 从程序传到外部的流。输出流只能向其写入数据。

所谓的输入和输出是以程序为中心的,数据流向程序即输入流,数据从程序中流出即输出流。

二 字节流

字节流是以字节为传输单位的数据读写形式,用于直接读取二进制数据,如图像和声音文件等。

InputStream和OutputStream分别为面向字节的输入流类的父类和输出流类的父类。InputStream和OutputStream都是抽象类。

FileInputStream和FileOutputStream是文件流类,他们是InputStream和OutputStream的子类。

FileInputStream类的一般用法是:先创建一个FileInputStream对象关联到要读取的文件,然后调用read方法读取字节数据到程序中,再进行其他处理。因为read方法是按字节的读入的,所以汉字被读入时会出现乱码。

FileOutputStream类的一般用法是:先创建一个FileOutputStream对象关联到要写入的文件,然后调用write方法将字节数据写到程序中。如果进行写操作的文件不存在,则自动创建该文件,但是如果文件所在的路径也不存在,则运行时会报错。

例如 FileOutputStream fos = new FileOutputStream("D:\\test.txt");是不会报错的,

      FileOutputStream fos = new FileOutputStream("D:\\tmp\\test.txt");如果之前在D盘中没有tmp这个文件夹,那么此时运行这条语句会报错。

 

代码如下

复制代码
 1 package 文件操作_FileInputStream和FileOutputStream; 2  3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7  8 public class FileDemo { 9     public static void main(String[] args) {10         try {11             FileInputStream fis = new FileInputStream("D:\\test.txt");12             int  ch = fis.read();13             while (ch != -1) {14                 System.out.print((char) ch);15                 ch = fis.read();16             }17 //            byte[] buffer = new byte[8];18 //            fis.read(buffer);19 //            for (int i = 0; i < buffer.length; i++) {20 //                System.out.print((char) buffer[i]);21 //            }22             FileOutputStream fos = new FileOutputStream("D:\\test1.txt");23             byte[] b = {'a', 'c', 'd', 'e', 'x'};24             fos.write(b);25             fis.close();26             fos.close();27         } catch (FileNotFoundException e) {28             // TODO Auto-generated catch block29             e.printStackTrace();30         } catch (IOException e) {31             e.printStackTrace();32         }33     }34     35 36 }
复制代码

 

缓存流 BufferedInputStream 和 BufferedOutputStream

使用缓存流可以提高大文件的读写效率。例如从文件读入数据时,每次从输入流中读取较大的数据量存入内存缓冲区,具体的读操作针对该缓冲区进行;执行缓冲输出时,每次将输出流中的数据写入到内存缓冲区,知道缓冲区写满,才将数据写入到最终的介质中。

使用缓存流的缺点:当计算机突然关闭时,可能会丢失数据。通过清空缓冲区的数据可以减少这种情况的发生,使用flush()方法即可。

代码如下

复制代码
 1 package 文件操作_BufferedInputStream; 2  3 import java.io.BufferedInputStream; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7  8 public class BufferDemo { 9     public static void main(String[] args) {10         try {11             FileInputStream fis = new FileInputStream("D:\\test.txt");12             BufferedInputStream bis = new BufferedInputStream(fis); //默认的输入缓冲区是2048B13             int ch = bis.read();14             while (ch != -1) {15                 System.out.print((char)ch);16                 ch = bis.read();17             }18                     19         } catch (FileNotFoundException e) {20             // TODO Auto-generated catch block21             e.printStackTrace();22         } catch (IOException e) {23             e.printStackTrace();24         }25     }26 27 }
复制代码

 

三 字符流

Reader 和 Writer类是所有字符流的父类。一次读取或是写入两个字节,16位,即一个Unicode字符,因此可以使用字符流直接读写汉字内容。

BufferedReader 和 BufferedWriter类的用法示例

复制代码
 1 package 文件操作_字符流_BufferedReader和BufferedWriter; 2  3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileNotFoundException; 6 import java.io.FileReader; 7 import java.io.FileWriter; 8 import java.io.IOException; 9 10 public class BufferedDemo {11     public static void main(String[] args) {12         try {13             FileReader fr = new FileReader("D:\\test.txt");14             BufferedReader br = new BufferedReader(fr);15             FileWriter fw = new FileWriter("D:\\test1.txt");16             BufferedWriter bw = new BufferedWriter(fw);17             String str = br.readLine();18             while (str != null) {19                 bw.write(str);20                 bw.newLine();21                 str = br.readLine();22             }23             br.close();24             bw.close();25         } catch (FileNotFoundException e) {26             // TODO Auto-generated catch block27             e.printStackTrace();28         } catch (IOException e) {29             e.printStackTrace();30         }31     }32 33 }
复制代码

 

四 File文件类

File aa = new File(aaName); 这里的aa可以指向文件,也可以指向文件夹


在进行文件的操作时,若操作的对象是文件,那么在进行文件的创建,删除,复制之前,

(1)需要判断文件是否存在,
(2)以及File所指向的对象是一个文件还是一个文件夹(目录) 
(3)该文件所在的文件夹是否存在,file.getParentFile().exists()
 (4)若文件所在的文件夹不存在,需要建立其父文件夹,若未建立成功,返回false 
       if (!file.getParentFile().mkdirs()) return false;

在对文件夹(目录)进行操作时,

(1)首先判断 dirName 是不是以文件分隔符 File.separator结尾,如果不是,

     则 dirName += File.separator;

(2)需要判断 File dir = new File(dirName) 中的dir是不是存在以及指向的是不是一个文件夹 dir.exists() dir.isDirctory();
(3) 在对文件夹进行复制,删除等操作时,一般会用到递归,因为文件夹里面有时候会存在子文件夹。

 

程序示例1 删除指定目录下的文件

复制代码
 1 package 输入输出流_删除指定目录下的文件; 2  3 import java.io.File; 4  5 //delete()方法可以删除文件和文件夹,当成功删除文件或文件夹后,返回true  否则返回false 6 //在使用delete()方法时,如果此路径名表示一个文件夹(目录),则此目录必须为空才能删除 7 //(若要删除文件夹,需要先删除文件夹中的文件和文件夹,才能删除该文件夹) 8 public class FileDemo_05 { 9     10     public static boolean deleteFilesOrDir (String fileName) {//判断将指定文件或文件夹删除是否成功11         File file = new File(fileName);12         if (!file.exists()) {   //指定的文件或文件夹不存在,返回false13             System.out.println("文件删除失败,因为文件" + fileName + "不存在");14             return false;15         } else {  //指定的文件或是文件夹存在16             if (file.isFile()) {   //若file 是文件17                 return FileDemo_05.deleteFiles(fileName);18             } else {              //若file是文件夹19                 return FileDemo_05.deleteDir(fileName);20             }21         }22         23     }24     25     public static boolean deleteFiles(String fileName) { //判断删除指定文件是否成功26         File file = new File(fileName);27         if ( file.exists() && file.isFile() ) {28             if (file.delete()) {29                 System.out.println("文件" + fileName + "删除成功!");30                 return true;31             } else {32                 System.out.println("文件" + fileName + "删除失败!");33                 return false;34             }35         } else {36             System.out.println("文件删除失败 : " + fileName + "文件不存在!");37             return false;38         }39         40     }41     42     public static boolean deleteDir(String dir) { //判断删除指定文件夹以及文件夹下的文件是否成功43          if (!dir.endsWith(File.separator)) {44              dir += File.separator;45          }46          File dirFile = new File(dir);47          if (!dirFile.exists() || !dirFile.isDirectory()) {48              System.out.println("文件夹删除失败!" + dir + "文件夹不存在");49              return false;50          }51          boolean flag = true;52          File[] files = dirFile.listFiles();53          for (int i = 0; i < files.length; i++) {54              if (files[i].isFile()) {            //删除文件55                  flag = FileDemo_05.deleteFiles(files[i].getAbsolutePath());56                  if (!flag) {57                      break;58                  }59              } else if (files[i].isDirectory()) {  //删除子文件夹,此处为递归60                  flag = FileDemo_05.deleteDir(files[i].getAbsolutePath());61                  if (!flag) {62                      break;63                  }64              } 65          }66          if (!flag) {67              System.out.println("删除文件夹失败");68          }69          if (dirFile.delete()) {70              System.out.println("文件夹" + dir + "删除成功!");71              return true;72          } else {73              return false;74          }75     }76     77     78 79 }
复制代码

程序示例2 移动指定目录下的文件,该程序用到了 程序示例1

复制代码
  1 package 输入输出流_移动指定目录下的文件;  2   3 import java.io.File;  4   5 public class FileDemo_06 {  6     //英东某个指定的文件,但移动成功后不会覆盖已存在的文件  7     public static boolean moveA_File(String sourceFileName, String targetFileName) {  8         return FileDemo_06.moveA_File(sourceFileName, targetFileName, false);  9     } 10      11     //移动某个指定的文件,但移动成功后可以根据isOverlay的值来决定是否覆盖已存在的目标文件 12     public static boolean moveA_File(String sourceFileName, String targetFileName, 13                                         boolean isOverlay) { 14         File sourceFile = new File(sourceFileName); 15         if (!sourceFile.exists()) { 16             System.out.println("文件" + sourceFileName + "不存在,移动失败"); 17             return false; 18         } else if (!sourceFile.isFile()) { 19             System.out.println(sourceFileName + "不是文件,移动失败"); 20             return false; 21         } 22         File targetFile = new File(targetFileName); 23         if (targetFile.exists()) { 24             if (isOverlay) { 25                 System.out.println("目标文件已经存在,准备删除它"); 26                 if (!FileDemo_05.deleteFilesOrDir(targetFileName)) { 27                     System.out.println("文件移动失败,文件" + targetFileName + "删除失败"); 28                     return false; 29                 }  30             } else { 31                 System.out.println("文件移动失败,因为文件" + targetFileName + "已经存在"); 32                 return false; 33             } 34         } else { 35             if (!targetFile.getParentFile().exists()) { 36                 System.out.println("文件" + targetFile + "所在的目录不存在,正在创建"); 37                 if (!targetFile.getParentFile().mkdirs()) { 38                     System.out.println("移动文件失败,因为创建文件坐在的文件夹失败"); 39                     return false; 40                 } 41             } 42         } 43          44         //移动源文件至目标文件 45         if (sourceFile.renameTo(targetFile)) { 46             System.out.println("移动源文件" + sourceFileName + "到" + targetFileName  47                     + "成功" ); 48             return true; 49         } else { 50             System.out.println("移动源文件" + sourceFileName + "到" + targetFileName  51                     + "失败" ); 52             return false; 53         } 54          55          56     } 57      58     public static boolean moveDir(String sourceDirName, String targetDirName) { 59         //默认为不覆盖目标文件 60         return FileDemo_06.moveDir(sourceDirName, targetDirName, false); 61     } 62      63     //移动某个指定的目录,但移动成功后可以根据isOverlay的值来决定是否覆盖当前已存在的目标目录 64     public static boolean moveDir(String sourceDirName, String targetDirName, 65                                 boolean isOverlay) { 66         //判断原目录是否存在 67         File sourceDir = new File(sourceDirName); 68         if (!sourceDir.exists()) { 69             System.out.println("源目录" + sourceDirName + "不存在,移动目录失败"); 70             return false; 71         } else if (!sourceDir.isDirectory()) { 72             System.out.println("移动目录失败," + sourceDirName + "不是目录"); 73             return false; 74         } 75         //如果目标文件名不是以文件分割符结尾,自动添加文件分隔符 76         if (!targetDirName.endsWith(File.separator)) { 77             targetDirName += File.separator; 78         } 79         File targetDir = new File(targetDirName); 80         //如果目标文件夹存在 81         if (targetDir.exists()) { 82             if (isOverlay) { 83                 //允许删除则删除已存在的目标目录 84                 System.out.println("该目录已经存在,准备删除它"); 85                 if (!FileDemo_05.deleteFilesOrDir(targetDirName)) { 86                     System.out.println("移动目录失败,因为目标目录已经存在。   删除目录" +  87                         targetDirName + "失败!"                        ); 88                 } 89             } else { 90                 System.out.println("移动目录失败:该目录" + targetDirName + "已存在!"); 91                 return false; 92             } 93         } else { 94             //创建目标目录 95             System.out.println("该目录不存在,正在创建"); 96             if (!targetDir.mkdirs()) { 97                 System.out.println("移动目录失败: 创建目标目录失败"); 98                 return false; 99             }100         }101         boolean flag = true;102         //移动原目录下的文件和子目录到目标目录下103         File[] files = sourceDir.listFiles();104         for (int i = 0; i < files.length; i++) {105             //移动子文件106             if (files[i].isFile()) {107                 flag = FileDemo_06.moveA_File(files[i].getAbsolutePath(),108                         targetDirName + files[i].getName(), isOverlay);109                 if (!flag) {110                     break;111                 }112             } else if (files[i].isDirectory()) { //移动子目录113                 flag = FileDemo_06.moveDir(files[i].getAbsolutePath(),114                         targetDirName + files[i].getName(), isOverlay);115                 if (!flag) {116                     break;117                 }118                 119             }120         }121         122         if (!flag) {123             System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "失败");124             return false;125         }126         //删除原目录127         if (FileDemo_05.deleteDir(sourceDirName)) {128             System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "成功");129             return true;130         } else {131             System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "失败");132             return false;133         }134     }135     136     137     public static void main(String[] args) {138         //移动文件,如果目标文件存在,则替换139         System.out.println("调用moveA_File方法的结果如下");140         String sourceFileName = "D:\\aa\\temp\\key.txt";141         String targetFileName = "D:\\bbb\\ddd\\";142         FileDemo_06.moveA_File(sourceFileName, targetFileName);143         //移动目录,如果目标目录存在,则不覆盖144         System.out.println("\n调用moveDir方法的结果如下");145         String sourceDir = "D:\\aa";146         String targetDir = "C:\\mm";147         FileDemo_06.moveDir(sourceDir, targetDir,false);148     }149     150 151 }
复制代码