java  基础知识之IO总结

java  基础知识之IO总结

     我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容。

  工作后,使用的技术随着项目的变化而变化,时而C#,时而Java,当然还有其他一些零碎的技术。总体而言,C#的使用时间要更长一些,其次是Java。我本身对语言没有什么倾向性,能干活的语言,就是好语言。而且从面向对象的角度来看,我觉得C#和Java对我来说,没什么区别。

  这篇文章主要回顾Java中和I/O操作相关的内容,I/O也是编程语言的一个基础特性,Java中的I/O分为两种类型,一种是顺序读取,一种是随机读取。

  我们先来看顺序读取,有两种方式可以进行顺序读取,一种是InputStream/OutputStream,它是针对字节进行操作的输入输出流;另外一种是Reader/Writer,它是针对字符进行操作的输入输出流。

  下面我们画出InputStream的结构

  

  1. FileInputStream:操作文件,经常和BufferedInputStream一起使用
  2. PipedInputStream:可用于线程间通信
  3. ObjectInputStream:可用于对象序列化
  4. ByteArrayInputStream:用于处理字节数组的输入
  5. LineNumberInputStream:可输出当前行数,并且可以在程序中进行修改

  下面是OutputStream的结构

  

PrintStream:提供了类似print和println的接口去输出数据

  下面我们来看如何使用Stream的方式来操作输入输出

使用InputStream读取文件

使用FileInputStream读取文件信息
public static byte[] readFileByFileInputStream(File file) throws IOException
{
  ByteArrayOutputStream output = new ByteArrayOutputStream();
  FileInputStream fis = null;
  try
  {
    fis = new FileInputStream(file);
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while((bytesRead = fis.read(buffer, 0, buffer.length)) != -1)
    {
      output.write(buffer, 0, bytesRead);
    }
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during reading " + file.getAbsoluteFile());
  }
  finally
  {
    if (fis !=null) fis.close();
    if (output !=null) output.close();
  }
  return output.toByteArray();
}
使用BufferedInputStream读取文件
public static byte[] readFileByBufferedInputStream(File file) throws Exception
{
  FileInputStream fis = null;
  BufferedInputStream bis = null;
  ByteArrayOutputStream output = new ByteArrayOutputStream();
  try
  {
    fis = new FileInputStream(file);
    bis = new BufferedInputStream(fis);
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while((bytesRead = bis.read(buffer, 0, buffer.length)) != -1)
    {
      output.write(buffer, 0, bytesRead);
    }
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during reading " + file.getAbsoluteFile());
  }
  finally
  {
    if (fis != null) fis.close();
    if (bis != null) bis.close();
    if (output != null) output.close();
  }
  return output.toByteArray();
}

使用OutputStream复制文件

使用FileOutputStream复制文件
public static void copyFileByFileOutputStream(File file) throws IOException
{
  FileInputStream fis = null;
  FileOutputStream fos = null;
  try
  {
    fis = new FileInputStream(file);
    fos = new FileOutputStream(file.getName() + ".bak");
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while((bytesRead = fis.read(buffer,0,buffer.length)) != -1)
    {
      fos.write(buffer, 0, bytesRead);
    }
    fos.flush();
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during copying " + file.getAbsoluteFile());
  }
  finally
  {
    if (fis != null) fis.close();
    if (fos != null) fos.close();
  }
}
使用BufferedOutputStream复制文件
public static void copyFilebyBufferedOutputStream(File file)throws IOException
{
  FileInputStream fis = null;
  BufferedInputStream bis = null;
  FileOutputStream fos = null;
  BufferedOutputStream bos = null;
  try
  {
    fis = new FileInputStream(file);
    bis = new BufferedInputStream(fis);
    fos = new FileOutputStream(file.getName() + ".bak");
    bos = new BufferedOutputStream(fos);
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while((bytesRead = bis.read(buffer, 0, buffer.length)) != -1)
    {
      bos.write(buffer, 0, bytesRead);
    }
    bos.flush();
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during copying " + file.getAbsoluteFile());
  }
  finally
  {
    if (fis != null) fis.close();
    if (bis != null) bis.close();
    if (fos != null) fos.close();
    if (bos != null) bos.close();
  }
}

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

  下面我们来看Reader的结构

  

  这里的Reader基本上和InputStream能够对应上。  

  Writer的结构如下

  

  下面我们来看一些使用Reader或者Writer的例子

使用Reader读取文件内容

使用BufferedReader读取文件内容
public static String readFile(String file)throws IOException
{
  BufferedReader br = null;
  StringBuffer sb = new StringBuffer();
  try
  {
    br = new BufferedReader(new FileReader(file));
    String line = null;

    while((line = br.readLine()) != null)
    {
      sb.append(line);
    }
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during reading " + file);
  }
  finally
  {
    if (br != null) br.close();
  }
  return sb.toString();
}

使用Writer复制文件

使用BufferedWriter复制文件
public static void copyFile(String file) throws IOException
{
  BufferedReader br = null;
  BufferedWriter bw = null;
  try
  {
    br = new BufferedReader(new FileReader(file));
    bw = new BufferedWriter(new FileWriter(file + ".bak"));
    String line = null;
    while((line = br.readLine())!= null)
    {
      bw.write(line);
    }
  }
  catch(Exception ex)
  {
    System.out.println("Error occurs during copying " + file);
  }
  finally
  {
    if (br != null) br.close();
    if (bw != null) bw.close();
  }
}

  下面我们来看如何对文件进行随机访问,Java中主要使用RandomAccessFile来对文件进行随机操作。

创建一个大小固定的文件

创建大小固定的文件
public static void createFile(String file, int size) throws IOException
{
  File temp = new File(file);
  RandomAccessFile raf = new RandomAccessFile(temp, "rw");
  raf.setLength(size);
  raf.close();
}

向文件中随机写入数据

向文件中随机插入数据
public static void writeFile(String file, byte[] content, int startPos, int contentLength) throws IOException
{
  RandomAccessFile raf = new RandomAccessFile(new File(file), "rw");
  raf.seek(startPos);
  raf.write(content, 0, contentLength);
  raf.close();
}

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

移动文件

移动文件
public static boolean moveFile(String sourceFile, String destFile)
{
  File source = new File(sourceFile);
  if (!source.exists()) throw new RuntimeException("source file does not exist.");
  File dest = new File(destFile);
  if (!(new File(dest.getPath()).exists())) new File(dest.getParent()).mkdirs();
  return source.renameTo(dest);
}

复制文件

复制文件
public static void copyFile(String sourceFile, String destFile) throws IOException
{
  File source = new File(sourceFile);
  if (!source.exists()) throw new RuntimeException("File does not exist.");
  if (!source.isFile()) throw new RuntimeException("It is not file.");
  if (!source.canRead()) throw new RuntimeException("File cound not be read.");
  File dest = new File(destFile);
  if (dest.exists())
  {
    if (dest.isDirectory()) throw new RuntimeException("Destination is a folder.");
    else
    {
      dest.delete();
    }
  }
  else
  {
    File parentFolder = new File(dest.getParent());
    if (!parentFolder.exists()) parentFolder.mkdirs();
    if (!parentFolder.canWrite()) throw new RuntimeException("Destination can not be written.");
  }
  FileInputStream fis = null;
  FileOutputStream fos = null;
  try
  {
    fis = new FileInputStream(source);
    fos = new FileOutputStream(dest);
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while((bytesRead = fis.read(buffer, 0, buffer.length)) != -1)
    {
      fos.write(buffer, 0, bytesRead);
    }
    fos.flush();
  }
  catch(IOException ex)
  {
    System.out.println("Error occurs during copying " + sourceFile);
  }
  finally
  {
    if (fis != null) fis.close();
    if (fos != null) fos.close();
  }
}

复制文件夹

复制文件夹
public static void copyDir(String sourceDir, String destDir) throws IOException
{

  File source = new File(sourceDir);
  if (!source.exists()) throw new RuntimeException("Source does not exist.");
  if (!source.canRead()) throw new RuntimeException("Source could not be read.");
  File dest = new File(destDir);
  if (!dest.exists()) dest.mkdirs();

  File[] arrFiles = source.listFiles();
  for(int i = 0; i < arrFiles.length; i++)
  {
    if (arrFiles[i].isFile())
    {
      BufferedReader reader = new BufferedReader(new FileReader(arrFiles[i]));
      BufferedWriter writer = new BufferedWriter(new FileWriter(destDir + "/" + arrFiles[i].getName()));
      String line = null;
      while((line = reader.readLine()) != null) writer.write(line);
      writer.flush();
      reader.close();
      writer.close();
    }
    else
    {
      copyDir(sourceDir + "/" + arrFiles[i].getName(), destDir + "/" + arrFiles[i].getName());
    }
  }
}

删除文件夹

删除文件夹
public static void del(String filePath)
{
  File file = new File(filePath);
  if (file == null || !file.exists()) return;
  if (file.isFile())
  {
    file.delete();
  }
  else
  {
    File[] arrFiles = file.listFiles();
    if (arrFiles.length > 0)
    {
      for(int i = 0; i < arrFiles.length; i++)
      {
        del(arrFiles[i].getAbsolutePath());
      }
    }
    file.delete();
  }
}

获取文件夹大小

获取文件夹大小
public static long getFolderSize(String dir)
{
  long size = 0;
  File file = new File(dir);
  if (!file.exists()) throw new RuntimeException("dir does not exist.");
  if (file.isFile()) return file.length();
  else
  {
    String[] arrFileName = file.list();
    for (int i = 0; i < arrFileName.length; i++)
    {
      size += getFolderSize(dir + "/" + arrFileName[i]);
    }
  }

  return size;
}

将大文件切分为多个小文件

将大文件切分成多个小文件
public static void splitFile(String filePath, long unit) throws IOException
{
  File file = new File(filePath);
  if (!file.exists()) throw new RuntimeException("file does not exist.");
  long size = file.length();
  if (unit >= size) return;
  int count = size % unit == 0 ? (int)(size/unit) : (int)(size/unit) + 1;
  String newFile = null;
  FileOutputStream fos = null;
  FileInputStream fis =null;
  byte[] buffer = new byte[(int)unit];
  fis = new FileInputStream(file);
  long startPos = 0;
  String countFile = filePath + "_Count";
  PrintWriter writer = new PrintWriter(new FileWriter( new File(countFile)));
  writer.println(filePath + "\t" + size);
  for (int i = 1; i <= count; i++)
  {
    newFile = filePath + "_" + i;
    startPos = (i - 1) * unit;
    System.out.println("Creating " + newFile);
    fos = new FileOutputStream(new File(newFile));
    int bytesRead = fis.read(buffer, 0, buffer.length);
    if (bytesRead != -1)
    {
      fos.write(buffer, 0, bytesRead);
      writer.println(newFile + "\t" + startPos + "\t" + bytesRead);
    }
    fos.flush();
    fos.close();
    System.out.println("StartPos:" + i*unit + "; EndPos:" + (i*unit + bytesRead));
  }
  writer.flush();
  writer.close();
  fis.close();
}

将多个小文件合并为一个大文件

将多个小文件合并成一个大文件
public static void linkFiles(String countFile) throws IOException
{
  File file = new File(countFile);
  if (!file.exists()) throw new RuntimeException("Count file does not exist.");
  BufferedReader reader = new BufferedReader(new FileReader(file));
  String line = reader.readLine();
  String newFile = line.split("\t")[0];
  long size = Long.parseLong(line.split("\t")[1]);
  RandomAccessFile raf = new RandomAccessFile(newFile, "rw");
  raf.setLength(size);
  FileInputStream fis = null;
  byte[] buffer = null;

  while((line = reader.readLine()) != null)
  {
    String[] arrInfo = line.split("\t");
    fis = new FileInputStream(new File(arrInfo[0]));
    buffer = new byte[Integer.parseInt(arrInfo[2])];
    long startPos = Long.parseLong(arrInfo[1]);
    fis.read(buffer, 0, Integer.parseInt(arrInfo[2]));
    raf.seek(startPos);
    raf.write(buffer, 0, Integer.parseInt(arrInfo[2]));
    fis.close();
  }
  raf.close();
}

执行外部命令

执行外部命令
public static void execExternalCommand(String command, String argument)
{
  Process process = null;
  try
  {
    process = Runtime.getRuntime().exec(command + " " + argument);
    InputStream is = process.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String line = null;
    while((line = br.readLine()) != null)
    {
      System.out.println(line);
    }
  }
  catch(Exception ex)
  {
    System.err.println(ex.getMessage());
  }
  finally
  {
    if (process != null) process.destroy();
  }
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java 基础知识之网络通信(TCP通信、UDP通信、多播以及NIO)总结

    java 基础知识之网路通信总结 在这篇文章里,我们主要讨论如何使用Java实现网络通信,包括TCP通信.UDP通信.多播以及NIO. TCP连接 TCP的基础是Socket,在TCP连接中,我们会使用ServerSocket和Socket,当客户端和服务器建立连接以后,剩下的基本就是对I/O的控制了. 我们先来看一个简单的TCP通信,它分为客户端和服务器端. 客户端代码如下: 简单的TCP客户端 import java.net.*; import java.io.*; public class

  • 新手了解java 多线程基础知识(一)

    目录 1.基本概念 2.多线程的创建 3.Thread类方法介绍 总结 1.基本概念 程序.进程.线程 程序(program)是为完成特定任务.用某种语言编写的一组指令的集 合.即指一段静态的代码,静态对象. 进程(process)是程序的一次执行过程,或是正在运行的一个程序.是 一个动态的过程:有它自身的产生.存在和消亡的过程--具有生命 周期.可以理解为一个正在运行的软件. 线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行 路径.可以理解为一个软件的功能. 多线程程序的

  • Java基础教程之理解Annotation详细介绍

    Java基础之理解Annotation 一.概念  Annontation是Java5开始引入的新特征.中文名称一般叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类.方法.成员变量等)进行关联. 更通俗的意思是为程序的元素(类.方法.成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或框架使用的. Annontation像一种修饰符一样,应用于包.类型.构造方法.方法.成员变量.参数及本地变量的声明语句中.

  • java基础之Collection与Collections和Array与Arrays的区别

    java基础之Collection与Collections和Array与Arrays的区别 1.Collection 在Java.util下的一个接口,它是各种集合结构的父接口.继承与他的接口主要有Set 和List. 2.Collections java.util下的一个专用静态类,它包含有各种有关集合操作的静态方法. 提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. Array与Arrays的区别 1.数组类Array  Java中最基本的一个存储结构. 提供了动态创建和访问

  • 新手了解java 多线程基础知识(二)

    目录 一.线程的生命周期 JDK中用Thread.State类定义了线程的几种状态: 二.线程同步 1.为什么要有线程同步 2.synchronized 2.1同步代码块 2.2同步方法 3.Lock锁 总结 一.线程的生命周期 JDK中用Thread.State类定义了线程的几种状态: 要想实现多线程,必须在主线程中创建新的线程对象.Java语言使用 Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常 要经历如下的五种状态: 新建:当一个Thread类或其子类的对象被声明并

  • java 基础知识之IO总结

    java  基础知识之IO总结     我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容. 工作后,使用的技术随着项目的变化而变化,时而C#,时而Java,当然还有其他一些零碎的技术.总体而言,C#的使用时间要更长一些,其次是Java.我本身对语言没有什么倾向性,能干活的语言,就是好语言.而且从面向对象的角度来看,我觉得C#和Java对我来说,没什么区别. 这篇文章主要回顾Java中和I/O操作相关的内容,I/O也是编程语言的一个基础特性,Java中的I/O分为两

  • java  基础知识之IO总结

    java  基础知识之IO总结     我计划在接下来的几篇文章中快速回顾一下Java,主要是一些基础的JDK相关的内容. 工作后,使用的技术随着项目的变化而变化,时而C#,时而Java,当然还有其他一些零碎的技术.总体而言,C#的使用时间要更长一些,其次是Java.我本身对语言没有什么倾向性,能干活的语言,就是好语言.而且从面向对象的角度来看,我觉得C#和Java对我来说,没什么区别. 这篇文章主要回顾Java中和I/O操作相关的内容,I/O也是编程语言的一个基础特性,Java中的I/O分为两

  • Java基础知识汇总

    Java基础知识 1.Java语言的优点: 1)Java是纯面向对象语言 2)与平台无关性,一次编译到处运行 3)Java提供了狠多内置类库 4)提供了对web应用的支持 5)具有较好的安全性(数组边界检测.Bytecode检测)和健壮性(强制型机制.垃圾回收器.异常处理) 6)去除c++难以理解的一些特性(头文件 指针 运算符重载 多重继承) 2.java与c++的异同: 1)Java为解释型语言,c++为编译型语言,java会慢但是跨平台 2)Jave为纯面向对象,c++既面向对象又能面向过

  • Java基础知识杂文

    1.基本概念 IO是主存和外部设备(硬盘.终端和网络等)拷贝数据的过程.IO是操作系统的底层功能实现,底层通过I/O指令进行完成. 所有语言运行时系统提供执行I/O较高级别的工具.(c的printfscanf,java的面向对象封装) 2.Java标准io回顾 Java标准IO类库是io面向对象的一种抽象.基于本地方法的底层实现,我们无须关注底层实现.InputStream\OutputStream(字节流):一次传送一个字节.Reader\Writer(字符流):一次一个字符. 3.nio简介

  • 详解Java基础知识——JDBC

    JDBC Java DataBase Connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装. JDBC提供了很多接口,然后不同数据库厂商去实现这个接口,到底底层如何去实现,不同的数据库不一样,不同的数据库厂商需要提供接口实现类(驱动类.驱动程序 Driver.驱动) 我们连接不同的数据库,我们只需要使用不同的驱动即可. J:Java:提供访问数据库的规范(接口), DBC:接口的实现,厂商去实现这个接口. JD

  • Java基础知识之注解、元注解

    目录 注解 注解作用 Java预定义的注解 自定义注解 元注解 实例: 注解使用总结 总结 注解 Java注解也称Java标注,是jdk1.5(5.0)后的新特征.Java语言中的类.方法.变量.参数和包等都可以被标注.和Javadoc不同,Java注解可以通过反射获取标注内容,在编译器生成类文件时,标注可以被嵌入到字节码中,Java虚拟机可以保留标注内容,在运行时可以获取到标注内容,当然它也支持自定义Java标注 功能:用于说明程序 用途:一般用在框架中使用 格式:@AnnotationNam

  • java基础知识 super和this使用解析

    这篇文章主要介绍了java基础知识 super和this使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 super关键字的用法有三种: 1.在子类的成员方法中,访问父类的成员变量 2.在子类的成员方法中,访问父类的成员方法 3.在子类的构造方法中,访问父类的构造方法 this和super区别 super关键字用来访问父类内容,this关键字用来访问本类内容. 1.在本类的成员方法中,访问本类的成员变量 2.在本类的成员方法中,访问本类的

  • 浅谈Java基础知识之BigDecimal

    一.基本使用 使用示例: // 初始化 BigDecimal bd1=new BigDecimal("456"); BigDecimal bd2=new BigDecimal("123"); // 加 BigDecimal add=bd1.add(bd2); // 减 BigDecimal subtract=bd1.subtract(bd2); // 乘 BigDecimal multiply=bd1.multiply(bd2); // 除 BigDecimal d

  • Java基础知识总结之继承

    一.继承的基本概念 什么是继承呢? 我们可以想一下,既然是"继承",那么它必须是在两个或多个类之间所发生的关系吧,这样我们就可以说:这个类继承自什么类,假如只有一个类的话,它既无法继承别的类,而且也没有别的类来继承它,这就构不成什么继承关系了哈,理清楚了这一层关系之后我们再来谈谈它继承了什么呢? 既然说什么什么类继承自什么什么类,那它肯定要从继承的那个类中继承点什么呀!我们把发生继承关系的这两个类称为父类和子类,子类可以继承父类的属性和方法,这个就是继承的基本概念,下面我们来系统的学习

随机推荐