zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java回顾之I/O

JAVA 回顾
2023-09-11 14:18:01 时间

这篇文章主要回顾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复制文件
     
     1 public static void copyFileByFileOutputStream(File file) throws IOException
     2 {
     3     FileInputStream fis = null;
     4     FileOutputStream fos = null;
     5     try
     6     {
     7         fis = new FileInputStream(file);
     8         fos = new FileOutputStream(file.getName() + ".bak");
     9         byte[] buffer = new byte[1024];
    10         int bytesRead = 0;
    11         while((bytesRead = fis.read(buffer,0,buffer.length)) != -1)
    12         {
    13             fos.write(buffer, 0, bytesRead);
    14         }
    15         fos.flush();
    16     }
    17     catch(Exception ex)
    18     {
    19         System.out.println("Error occurs during copying " + file.getAbsoluteFile());
    20     }
    21     finally
    22     {
    23         if (fis != null) fis.close();
    24         if (fos != null) fos.close();
    25     }
    26 }
     
     
     1 public static void copyFilebyBufferedOutputStream(File file)throws IOException
     2 {
     3     FileInputStream fis = null;
     4     BufferedInputStream bis = null;
     5     FileOutputStream fos = null;
     6     BufferedOutputStream bos = null;
     7     try
     8     {
     9         fis = new FileInputStream(file);
    10         bis = new BufferedInputStream(fis);
    11         fos = new FileOutputStream(file.getName() + ".bak");
    12         bos = new BufferedOutputStream(fos);
    13         byte[] buffer = new byte[1024];
    14         int bytesRead = 0;
    15         while((bytesRead = bis.read(buffer, 0, buffer.length)) != -1)
    16         {
    17             bos.write(buffer, 0, bytesRead);
    18         }
    19         bos.flush();
    20     }
    21     catch(Exception ex)
    22     {
    23         System.out.println("Error occurs during copying " + file.getAbsoluteFile());
    24     }
    25     finally
    26     {
    27         if (fis != null) fis.close();
    28         if (bis != null) bis.close();
    29         if (fos != null) fos.close();
    30         if (bos != null) bos.close();
    31     }
    32 }
     

    这里的代码对异常的处理非常不完整,稍后我们会给出完整严谨的代码。

  下面我们来看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 createFile(String file, int size) throws IOException
    2 {
    3     File temp = new File(file);
    4     RandomAccessFile raf = new RandomAccessFile(temp, "rw");
    5     raf.setLength(size);
    6     raf.close();
    7 }
     
  • 向文件中随机写入数据
     
    1 public static void writeFile(String file, byte[] content, int startPos, int contentLength) throws IOException
    2 {
    3     RandomAccessFile raf = new RandomAccessFile(new File(file), "rw");
    4     raf.seek(startPos);
    5     raf.write(content, 0, contentLength);
    6     raf.close();
    7 }
     

  接下里,我们来看一些其他的常用操作

  • 移动文件
     
    1 public static boolean moveFile(String sourceFile, String destFile)
    2 {
    3     File source = new File(sourceFile);
    4     if (!source.exists()) throw new RuntimeException("source file does not exist.");
    5     File dest = new File(destFile);
    6     if (!(new File(dest.getPath()).exists())) new File(dest.getParent()).mkdirs();
    7     return source.renameTo(dest);
    8 }
     
  • 复制文件
     
     1 public static void copyFile(String sourceFile, String destFile) throws IOException
     2 {
     3     File source = new File(sourceFile);
     4     if (!source.exists()) throw new RuntimeException("File does not exist.");
     5     if (!source.isFile()) throw new RuntimeException("It is not file.");
     6     if (!source.canRead()) throw new RuntimeException("File cound not be read.");
     7     File dest = new File(destFile);
     8     if (dest.exists())
     9     {
    10         if (dest.isDirectory()) throw new RuntimeException("Destination is a folder.");
    11         else
    12         {
    13             dest.delete();
    14         }
    15     }
    16     else
    17     {
    18         File parentFolder = new File(dest.getParent());
    19         if (!parentFolder.exists()) parentFolder.mkdirs();
    20         if (!parentFolder.canWrite()) throw new RuntimeException("Destination can not be written.");
    21     }
    22     FileInputStream fis = null;
    23     FileOutputStream fos = null;
    24     try
    25     {
    26         fis = new FileInputStream(source);
    27         fos = new FileOutputStream(dest);
    28         byte[] buffer = new byte[1024];
    29         int bytesRead = 0;
    30         while((bytesRead = fis.read(buffer, 0, buffer.length)) != -1)
    31         {
    32             fos.write(buffer, 0, bytesRead);
    33         }
    34         fos.flush();
    35     }
    36     catch(IOException ex)
    37     {
    38         System.out.println("Error occurs during copying " + sourceFile);
    39     }
    40     finally
    41     {
    42         if (fis != null) fis.close();
    43         if (fos != null) fos.close();
    44     }
    45 }
     
  • 复制文件夹
     
     1 public static void copyDir(String sourceDir, String destDir) throws IOException
     2 {
     3     
     4     File source = new File(sourceDir);
     5     if (!source.exists()) throw new RuntimeException("Source does not exist.");
     6     if (!source.canRead()) throw new RuntimeException("Source could not be read.");
     7     File dest = new File(destDir);
     8     if (!dest.exists()) dest.mkdirs();
     9     
    10     File[] arrFiles = source.listFiles();
    11     for(int i = 0; i < arrFiles.length; i++)
    12     {
    13         if (arrFiles[i].isFile())
    14         {
    15             BufferedReader reader = new BufferedReader(new FileReader(arrFiles[i]));
    16             BufferedWriter writer = new BufferedWriter(new FileWriter(destDir + "/" + arrFiles[i].getName()));
    17             String line = null;
    18             while((line = reader.readLine()) != null) writer.write(line);
    19             writer.flush();
    20             reader.close();
    21             writer.close();
    22         }
    23         else
    24         {
    25             copyDir(sourceDir + "/" + arrFiles[i].getName(), destDir + "/" + arrFiles[i].getName());
    26         }
    27     }
    28 }
     
  • 删除文件夹
     
     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 long getFolderSize(String dir)
     2 {
     3     long size = 0;
     4     File file = new File(dir);
     5     if (!file.exists()) throw new RuntimeException("dir does not exist.");
     6     if (file.isFile()) return file.length();
     7     else
     8     {
     9         String[] arrFileName = file.list();
    10         for (int i = 0; i < arrFileName.length; i++)
    11         {
    12             size += getFolderSize(dir + "/" + arrFileName[i]);
    13         }
    14     }
    15     
    16     return size;
    17 }
     
  • 将大文件切分为多个小文件
     
     1 public static void splitFile(String filePath, long unit) throws IOException
     2 {
     3     File file = new File(filePath);
     4     if (!file.exists()) throw new RuntimeException("file does not exist.");
     5     long size = file.length();
     6     if (unit >= size) return;
     7     int count = size % unit == 0 ? (int)(size/unit) : (int)(size/unit) + 1;
     8     String newFile = null;
     9     FileOutputStream fos = null;
    10     FileInputStream fis =null;
    11     byte[] buffer = new byte[(int)unit];
    12     fis = new FileInputStream(file);
    13     long startPos = 0;
    14     String countFile = filePath + "_Count";
    15     PrintWriter writer = new PrintWriter(new FileWriter( new File(countFile)));
    16     writer.println(filePath + "\t" + size);
    17     for (int i = 1; i <= count; i++)
    18     {
    19         newFile = filePath + "_" + i;
    20         startPos = (i - 1) * unit;
    21         System.out.println("Creating " + newFile);
    22         fos = new FileOutputStream(new File(newFile));
    23         int bytesRead = fis.read(buffer, 0, buffer.length);
    24         if (bytesRead != -1)
    25         {
    26             fos.write(buffer, 0, bytesRead);
    27             writer.println(newFile + "\t" + startPos + "\t" + bytesRead);
    28         }
    29         fos.flush();
    30         fos.close();
    31         System.out.println("StartPos:" + i*unit + "; EndPos:" + (i*unit + bytesRead));
    32     }
    33     writer.flush();
    34     writer.close();
    35     fis.close();
    36 }
     
  • 将多个小文件合并为一个大文件
     
     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 }
     
  • 执行外部命令
     
     1 public static void execExternalCommand(String command, String argument)
     2 {
     3     Process process = null;
     4     try
     5     {
     6         process = Runtime.getRuntime().exec(command + " " + argument);
     7         InputStream is = process.getInputStream();
     8         BufferedReader br = new BufferedReader(new InputStreamReader(is));
     9         String line = null;
    10         while((line = br.readLine()) != null)
    11         {
    12             System.out.println(line);
    13         }
    14     }
    15     catch(Exception ex)
    16     {
    17         System.err.println(ex.getMessage());
    18     }
    19     finally
    20     {
    21         if (process != null) process.destroy();
    22     }
    23 }