第十四章 java IO

java IO

IO:记住一句话,以程序为中心,进入程序--读取(输入流);从程序中出来--输出流

输入流:数据源到程序(InputStream、Reader读进来)

输出流:程序到目的地(OutputStream、Writer写出去)

一、流分类

字节流:按照字节读取数据(InputStream、OutputStream)

字符流:按照字符读取数据(Reader、Writer) ,因为文件 编码的不同,从而有了对字符进行高效操作的字符流对象。

原理:底层还是基于字节流操作,自动搜寻了指定的码表。

字节流:

字节流.png

字符流:

字符流.png

二、File类

2.1 常用方法

API 说明
pathSeparator separator 路径 路径分隔符
File(String parent,String child) File(File parent, String child) File(String name) 构造器 没有盘符以user.dir作为相对目录
getName() getPath() getAbsolutePath() getParent() 文件名、路径名
exists() isFile() isDirectory() 判断状态
length() 文件长度
createNewFile() delete() 创建新文件 删除文件
mkdir() mkdirs() 创建目录,如果父目录链不存在一同创建
list() 下级名称
listFiles() 下级文件
listRoots() 根路径

2.2 IO流

总揽IO流.png
2.2.1 四大抽象类
抽象类 说明 常用方法
InputStream 字节输入流的父类,数据单位为字节。 • int read()• void close()
OutputStream 字节输出流的父类,数据单位为字节。 • void write(int)• void flush()• void close()
Reader 字符输入流的父类,数据单位为字符。 • int read()• void close()
Writer 字符输出流的父类,数据单位为字符。 • void write(String)• void flush()• void close()

2.3 构建File对象的三种方式

//1、构建File对象
String  src="D:/java/IO/io.png";
File src =new File(path);
System.out.println(src.length());

//2.父路径+子文件名
src =new File("D:/java/IO","io.png");//严格的父路径+子文件名
src =new File("D:/java","/IO/io.png");//只要路径能拼接成功就行,无论怎么分割

//3.父对象+子文件名
src =new File(new File("D:/java/IO"),"io.png");

2.4 文件操作

//文件状态
src = new File("xxx");
if(null==src||!src.exists()){
    System.out.println("文件不存在");
}else{
    if(src.isFile()){
        System.out.println("文件操作");
    }else{
        System.out.println("文件夹操作");
    }
}

//文件长度 length() ---字节数
File src =new File("D:/java/IO/io.png");
System.out.println(src.length());

//创建文件  删除文件
//不是文件夹
File src =new File("D:/java/IO/io.png");
boolean flag=src.createNewFile(); //不存在创建,存在创建成功
System.out.prinln(flag); 
//删除文件
flag =src.delete(); 

//------------------文件夹操作
//mkdir()  :必须保证上一级目录存在,
//mkdirs()  : 不必保证上一级目录是否存在,若不存在 就会自动创建,(推荐使用)
//list():列出下一级名称
//listFiles(): 列出下一级对象  list()和listFiles()如果想列出所有下一级(仅仅一级)的所有文件或者对象需要遍历
//listRoots():根路径
//---打印子孙级目录和文件名称
main()
File src = new File("D:/java/IO/io.png");
printName(src,0);
//printName函数名
public static void printName(File src,int deep){
for(int i=0;i<deep;i++){
    System.out.print("-"); //有几层打印几个
}
//打印名称
System.out.println(src.getName);
if(null==src||!src.exists()){
    return;
}else if(src.isDirectory()){//目录
    for(File s:src.listFiles()){
        printName(s,deep+1);//递归体
    }
}
}

//统计文件夹的大小
private static long len=0;
public static void count(File src){
    //获取大小
    if(null!=src&&src.exists()){
        if(src.isFile()){//大小
            len+=src.length();
        }else {//子孙级
            for(File s:src.listFiles()){
                count(s); //递归
            }
        }
    }
}

三、 IO流操作的基本步骤

1、创建源

2、选择流

3、操作流

4、释放资源

 //1、创建源
  File src = new File("abc.txt");
  //2、选择流
  InputStream  is =null;
  try {
  is =new FileInputStream(src);
  //3、操作 (读取)
  int temp ;
  while((temp=is.read())!=-1) {
  System.out.println((char)temp);
  } 

  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=is) {
  is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }

3.1 FileInputStream、FileOutputStream

FileInputStream:通过字节的方式读取文件,适合读取所有 类型的文件(图像、视频等), 全字符请考虑FileReader

FileOutputStream:通过字节的 方式写出或追加数据到文件, 适合所有类型的文件(图像、视 频等),全字符请考虑 FileWriter

以下实例完成文件拷贝:

 //文件字节输入流
 //1、创建源
  File src = new File("abc.txt");
  //2、选择流
  InputStream  is =null;
  try {
  is =new FileInputStream(src);
  //3、操作 (分段读取)
  byte[] flush = new byte[1024*10]; //缓冲容器
  int len = -1; //接收长度
  while((len=is.read(flush))!=-1) {
  //字节数组-->字符串 (解码)
  String str = new String(flush,0,len);
  System.out.println(str);
  } 

  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=is) {
  is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 ​
 //文件字节输出流  --(文件拷贝)
 //1、创建源
  File dest = new File("dest.txt");
  //2、选择流
  OutputStream os =null;
  try {
  os = new FileOutputStream(dest,true);
  //3、操作(写出)
  String msg ="IO is so easy\r\n";
  byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码)
  os.write(datas,0,datas.length);
  os.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源
  try {
  if (null != os) {
  os.close();
  } 
  } catch (Exception e) {
  }
  }

文件的拷贝:

/**
  * 文件的拷贝 
  * 思考: 利用递归 制作文件夹的拷贝   :先打开的后关闭
  * @param srcPath
  * @param destPath
  */
  public static void copy(String srcPath,String destPath) {
  //1、创建源
  File src = new File(srcPath); //源头
  File dest = new File(destPath);//目的地
  //2、选择流
  InputStream  is =null;
  OutputStream os =null;
  try {
  is =new FileInputStream(src);
  os = new FileOutputStream(dest); 
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=is.read(flush))!=-1) {
  os.write(flush,0,len); //分段写出
  } 
  os.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源 分别关闭 先打开的后关闭
  try {
  if (null != os) {
  os.close();
  } 
  } catch (IOException e) {
  e.printStackTrace();
  }

  try {
  if(null!=is) {
  is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
  }
  public static void copy2(String srcPath,String destPath) {
  //1、创建源
  File src = new File(srcPath); //源头
  File dest = new File(destPath);//目的地
  //2、选择流 
  try(InputStream  is=new FileInputStream(src);
  OutputStream os = new FileOutputStream(dest);  ) { 
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=is.read(flush))!=-1) {
  os.write(flush,0,len); //分段写出
  } 
  os.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }
  }
 }

3.2 FileReader&FileWriter

FileReader :通过字符的方式读取文件,仅适合字符文件

FileWriter :通过字节的方式写出或追加数据到文件中,仅适合字符文件

//文件字符输入流
 //1、创建源
  File src = new File("abc.txt");
  //2、选择流
  Reader  reader =null;
  try {
  reader =new FileReader(src);
  //3、操作 (分段读取)
  char[] flush = new char[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=reader.read(flush))!=-1) { //将reader引用中的数据读到flush数组中,并返回flush的长度
  //字符数组-->字符串
  String str = new String(flush,0,len);
  System.out.println(str);
  } 

  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=reader) {
  reader.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 ​
 //文件字符输出流
 //1、创建源
  File dest = new File("dest.txt");
  //2、选择流
  Writer writer =null;
  try {
  writer = new FileWriter(dest);
  //3、操作(写出)
  //写法一
 //      String msg ="IO is so easy\r\n尚学堂欢迎你";
 //      char[] datas =msg.toCharArray(); // 字符串-->字符数组
 //      writer.write(datas,0,datas.length);
  //写法二
  /*String msg ="IO is so easy\r\n尚学堂欢迎你";
  writer.write(msg); 
  writer.write("add"); 
  writer.flush();*/

  //写法三
  writer.append("IO is so easy\r\n").append("尚学堂欢迎你");
  writer.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源
  try {
  if (null != writer) {
  writer.close();
  } 
  } catch (Exception e) {
  }
  }

3.3 ByteArrayInputStream&ByteArrayOutputStream

字节数组流 特点:不用关闭流

注意:

<u>字节数组输入流:</u>1、创建源 : 字节数组 不要太大 2、选择流 3、操作 4、释放资源: 可以不用处理

字节数组输出流:1 创建源 : 内部维护 2、选择流 : 不关联源 3、操作(写出内容) 4、释放资源 :可以不用

 //字节数组输入流
 //1、创建源
  byte[] src = "talk is cheap show me the code".getBytes();//字符串转为字节数组
  //2、选择流
  InputStream  is =null;
  try {
  is =new ByteArrayInputStream(src);
  //3、操作 (分段读取)
  byte[] flush = new byte[5]; //缓冲容器
  int len = -1; //接收长度
  while((len=is.read(flush))!=-1) {
  //字节数组-->字符串 (解码)
  String str = new String(flush,0,len);
  System.out.println(str);
  } 

  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=is) {
  is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 ​
 //字节数组输出流
 //1、创建源
  byte[] dest =null;
  //2、选择流 (新增方法)
  ByteArrayOutputStream baos =null;
  try {
  baos = new ByteArrayOutputStream();
  //3、操作(写出)
  String msg ="show me the code";
  byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码)
  baos.write(datas,0,datas.length);
  baos.flush();
  //获取数据
  dest = baos.toByteArray(); //将流转化为数组
  System.out.println(dest.length +"-->"+new String(dest,0,baos.size()));
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源
  try {
  if (null != baos) {
  baos.close();
  } 
  } catch (Exception e) {
  }
  }

3.4 缓冲流(字节缓冲和字符缓冲)

3.4.1 (字节缓冲流)BufferedInputStream&BufferedOutputStream

用缓冲流对原来的流进行封装

//字节文件输入流  加入缓冲流
 File src = new File("abc.txt");
  //2、选择流
  InputStream  is =null;
  try {
  is =new BufferedInputStream(new FileInputStream(src));
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=is.read(flush))!=-1) {
  //字节数组-->字符串 (解码)
  String str = new String(flush,0,len);
  System.out.println(str);
  } 

  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=is) {
  is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  } 
  }
  }

 //字节数组输出流  加入缓冲流
 //1、创建源
  File dest = new File("dest.txt");
  //2、选择流
  OutputStream os =null;
  try {
  os =new BufferedOutputStream( new FileOutputStream(dest));
  //3、操作(写出)
  String msg ="IO is so easy\r\n";
  byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码)
  os.write(datas,0,datas.length);
  os.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源
  try {
  if (null != os) {
  os.close();
  } 
  } catch (Exception e) {
  }
  }
3.4.2 (字符缓冲流)BufferedReader&BufferedWriter
 //文件字符输入流   --加入缓冲流
 //1、创建源
  File src = new File("abc.txt");
  //2、选择流
  BufferedReader  reader =null;
  try {
  reader =new BufferedReader(new FileReader(src));
  //3、操作 (分段读取)
  String line =null;
  while((line=reader.readLine())!=null) {
  //字符数组-->字符串
  System.out.println(line);
  } 

  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }finally {
  //4、释放资源
  try {
  if(null!=reader) {
  reader.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 ​
 //文件字符输出流  --加入缓冲流
 //1、创建源
  File dest = new File("dest.txt");
  //2、选择流
  BufferedWriter writer =null;
  try {
  writer = new BufferedWriter(new FileWriter(dest));
  //3、操作(写出) 
  writer.append("IO is so easy");
  writer.newLine();
  writer.append("尚学堂欢迎你");
  writer.flush();
  }catch(FileNotFoundException e) { 
  e.printStackTrace();
  }catch (IOException e) {
  e.printStackTrace();
  }finally{
  //4、释放资源
  try {
  if (null != writer) {
  writer.close();
  } 
  } catch (Exception e) {
  }
  }

3.5 转换流 InputStreamReader&OutputStreamWriter

转换流: InputStreamReader OutputStreamWriter

  • 1、以字符流的形式操作字节流(纯文本的)

  • 2、指定字符集

     public class ConvertTest {
      public static void main(String[] args) {
      //操作System.in 和System.out
      try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      BufferedWriter writer =new BufferedWriter(new OutputStreamWriter(System.out));){
      //循环获取键盘的输入(exit退出),输出此内容
      String msg ="";
      while(!msg.equals("exit")) {
      msg = reader.readLine(); //循环读取
      writer.write(msg); //循环写出
      writer.newLine();
      writer.flush(); //强制刷新
      }
      }catch(IOException e) {
      System.out.println("操作异常");
      }

      }
     }
     ​
     //example 2
     public class ConvertTest02 {
      public static void main(String[] args) {
      try(BufferedReader reader =
      new BufferedReader(
      new InputStreamReader(
      new URL("http://www.baidu.com").openStream(),"UTF-8"));
      BufferedWriter writer =
      new BufferedWriter(
      new OutputStreamWriter(
      new FileOutputStream("baidu.html"),"UTF-8"));){
      //3、操作 (读取)
      String msg ;
      while((msg=reader.readLine())!=null) {
      //System.out.println(msg);
      writer.write(msg); //字符集不统一不够出现乱码
      writer.newLine();
      } 
      writer.flush();
      }catch(IOException e) {
      System.out.println("操作异常");
      }

      }
      public static void test2() {
      //操作网络流  下载百度的源代码
      try(InputStreamReader is =
      new InputStreamReader(new URL("http://www.baidu.com").openStream(),"UTF-8");){
      //3、操作 (读取)
      int temp ;
      while((temp=is.read())!=-1) {
      System.out.print((char)temp);
      } 

      }catch(IOException e) {
      System.out.println("操作异常");
      }
      }
      public static void test1() {
      //操作网络流  下载百度的源代码
      try(InputStream is =new URL("http://www.baidu.com").openStream();){
      //3、操作 (读取)
      int temp ;
      while((temp=is.read())!=-1) {
      System.out.print((char)temp); //字节数不够出现乱码
      } 

      }catch(IOException e) {
      System.out.println("操作异常");
      }

      }
     }
   ​

3.6 数据流 DataInputStream&DataOutputStream

数据流.png

数据流: 1、写出后读取
2、读取的顺序与写出保持一致

    public static void main(String[] args) throws IOException {
      //写出
      ByteArrayOutputStream baos =new ByteArrayOutputStream();
      DataOutputStream dos =new DataOutputStream(new BufferedOutputStream(baos));
      //操作数据类型 +数据
      dos.writeUTF("编码辛酸泪");
      dos.writeInt(18);
      dos.writeBoolean(false);
      dos.writeChar('a');
      dos.flush();
      byte[] datas =baos.toByteArray();
      System.out.println(datas.length);
      //读取
      DataInputStream dis =new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
      //顺序与写出一致
      String msg = dis.readUTF(); 
      int age = dis.readInt();
      boolean flag = dis.readBoolean();
      char ch = dis.readChar();
      System.out.println(flag);
      }
 ```

3.7 对象流

对象流.png

对象流:
1、写出后读取

2、读取的顺序与写出保持一致

3、不是所有的对象都可以序列化Serializable

* 对象流: 1、写出后读取 2、读取的顺序与写出保持一致 3、不是所有的对象都可以序列化Serializable
  * 
  * ObjectOutputStream ObjectInputStream
  * 
  * @author TW
  *
  */
 public class ObjectTest02 {
 ​
  public static void main(String[] args) throws IOException, ClassNotFoundException {
  // 写出 -->序列化
  ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("obj.ser")));
  // 操作数据类型 +数据
  oos.writeUTF("编码辛酸泪");
  oos.writeInt(18);
  oos.writeBoolean(false);
  oos.writeChar('a');
  // 对象
  oos.writeObject("谁解其中味");
  oos.writeObject(new Date());
  Employee emp = new Employee("马云", 400);
  oos.writeObject(emp);
  oos.flush();
  oos.close();
  // 读取 -->反序列化
  ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("obj.ser")));
  // 顺序与写出一致
  String msg = ois.readUTF();
  int age = ois.readInt();
  boolean flag = ois.readBoolean();
  char ch = ois.readChar();
  System.out.println(flag);
  // 对象的数据还原
  Object str = ois.readObject();
  Object date = ois.readObject();
  Object employee = ois.readObject();
 ​
  if (str instanceof String) {
  String strObj = (String) str;
  System.out.println(strObj);
  }
  if (date instanceof Date) {
  Date dateObj = (Date) date;
  System.out.println(dateObj);
  }
  if (employee instanceof Employee) {
  Employee empObj = (Employee) employee;
  System.out.println(empObj.getName() + "-->" + empObj.getSalary());
  }
  ois.close();
  }

3.8 随机读写流


 public static void main(String[] args) throws IOException {
  //分多少块
  File src = new File("p.png");
  //总长度
  long len = src.length();
  //每块大小
  int blockSize =1024;
  //块数: 多少块
  int size =(int) Math.ceil(len*1.0/blockSize); //向上取整
  System.out.println(size);

  //起始位置和实际大小
  int beginPos = 0;
  int actualSize = (int)(blockSize>len?len:blockSize); 
  for(int i=0;i<size;i++) {
  beginPos = i*blockSize;
  if(i==size-1) { //最后一块
  actualSize = (int)len;
  }else {
  actualSize = blockSize;
  len -=actualSize; //剩余量
  }
  System.out.println(i+"-->"+beginPos +"-->"+actualSize);
  split(i,beginPos,actualSize);
  }

  }
  /**
  * 指定第i块的起始位置 和实际长度
  * @param i
  * @param beginPos
  * @param actualSize
  * @throws IOException
  */
  public static void split(int i,int beginPos,int actualSize ) throws IOException {
  RandomAccessFile raf =new RandomAccessFile(new File("p.png"),"r");
  RandomAccessFile raf2 =new RandomAccessFile(new File("dest/"+i+"p.png"),"rw");
  //随机读取 
  raf.seek(beginPos);
  //读取
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=raf.read(flush))!=-1) { 
  if(actualSize>len) { //获取本次读取的所有内容  实际大小》每段规定应读取长度,按规定来,否则else
  raf2.write(flush, 0, len);
  actualSize -=len;
  }else { 
  raf2.write(flush, 0, actualSize);
  break;
  }
  } 
  raf2.close();
  raf.close();
  }
功能模块实现:文件分割:
 /**
  * 面向对象思想封装 分割

  *
  */
 public class SplitFile {
  //源头
  private File src;
  //目的地(文件夹)
  private String destDir;
  //所有分割后的文件存储路径
  private List<String> destPaths;
  //每块大小
  private int blockSize;
  //块数: 多少块
  private int size;

  public SplitFile(String srcPath,String destDir) {
  this(srcPath,destDir,1024);
  }
  public SplitFile(String srcPath,String destDir,int blockSize) {
  this.src =new File(srcPath);
  this.destDir =destDir;
  this.blockSize =blockSize;
  this.destPaths =new ArrayList<String>();

  //初始化
  init();
  }
  //初始化
  private void init() {
  //总长度
  long len = this.src.length(); 
  //块数: 多少块
  this.size =(int) Math.ceil(len*1.0/blockSize);
  //路径
  for(int i=0;i<size;i++) {
  this.destPaths.add(this.destDir +"/"+i+"-"+this.src.getName());
  }
  }
  /**
  * 分割
  * 1、计算每一块的起始位置及大小
  * 2、分割
  * @throws IOException 
  */
  public void split() throws IOException {
  //总长度
  long len = src.length(); 
  //起始位置和实际大小
  int beginPos = 0;
  int actualSize = (int)(blockSize>len?len:blockSize); 
  for(int i=0;i<size;i++) {
  beginPos = i*blockSize;
  if(i==size-1) { //最后一块
  actualSize = (int)len;
  }else {
  actualSize = blockSize;
  len -=actualSize; //剩余量
  }
  splitDetail(i,beginPos,actualSize);
  }
  } 
  /**
  * 指定第i块的起始位置 和实际长度
  * @param i
  * @param beginPos
  * @param actualSize
  * @throws IOException
  */
  private  void splitDetail(int i,int beginPos,int actualSize ) throws IOException {
  RandomAccessFile raf =new RandomAccessFile(this.src,"r");
  RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i),"rw");
  //随机读取 
  raf.seek(beginPos);
  //读取
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=raf.read(flush))!=-1) { 
  if(actualSize>len) { //获取本次读取的所有内容
  raf2.write(flush, 0, len);
  actualSize -=len;
  }else { 
  raf2.write(flush, 0, actualSize);
  break;
  }
  } 
  raf2.close();
  raf.close();
  } 
  /**
  * 文件的合并
  * @throws IOException 
  */
  public void merge(String destPath) throws IOException {
  //输出流
  OutputStream os =new BufferedOutputStream( new FileOutputStream(destPath,true)); 
  Vector<InputStream> vi=new Vector<InputStream>();
  SequenceInputStream sis =null;
  //输入流
  for(int i=0;i<destPaths.size();i++) {
  vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(i)))); 
  }
  sis =new SequenceInputStream(vi.elements());
  //拷贝
  //3、操作 (分段读取)
  byte[] flush = new byte[1024]; //缓冲容器
  int len = -1; //接收长度
  while((len=sis.read(flush))!=-1) {
  os.write(flush,0,len); //分段写出
  } 
  os.flush(); 
  sis.close();
  os.close();
  }
  public static void main(String[] args) throws IOException {
  SplitFile sf = new SplitFile("src/com/sxt/io/SplitFile.java","dest") ;
  sf.split();
  sf.merge("aaa.java");
  }
 }
 ​

四、组件使用 CommonsIO---FileUtils使用

用处:

• writing to a file

• reading from a file

• make a directory including parent directories

• copying files and directories

• deleting files and directories

• converting to and from a URL

• listing files and directories by filter and extension

• comparing file content

• file last changed date

• calculating a checksum

//1、大小
//文件大小
        long len =FileUtils.sizeOf(new File("src/com/sxt/commons/CIOTest01.java"));
        System.out.println(len);
        //目录大小
        len = FileUtils.sizeOf(new File("D:/java300/IO_study04"));
        System.out.println(len);

2//
    /**
 * 列出子孙级
 *
 */
public class CIOTest02 {

    public static void main(String[] args) {
        Collection<File> files =FileUtils.listFiles(new File("D:\\java300\\IO_study04"),
                EmptyFileFilter.NOT_EMPTY, null);
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
        System.out.println("---------------------");
         files =FileUtils.listFiles(new File("D:\\java300\\IO_study04"),
                    EmptyFileFilter.NOT_EMPTY, DirectoryFileFilter.INSTANCE);
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
        System.out.println("---------------------");
         files =FileUtils.listFiles(new File("D:\\java300\\IO_study04"),
                    new SuffixFileFilter("java"), DirectoryFileFilter.INSTANCE);//sufficient后缀
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
        System.out.println("---------------------");
         files =FileUtils.listFiles(new File("D:\\java300\\IO_study04"),
                    FileFilterUtils.or(new SuffixFileFilter("java"),
                            new SuffixFileFilter("class"),EmptyFileFilter.EMPTY), DirectoryFileFilter.INSTANCE);
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
        
        System.out.println("---------------------");
         files =FileUtils.listFiles(new File("D:\\java300\\IO_study04"),
                    FileFilterUtils.and(new SuffixFileFilter("java"),
                            EmptyFileFilter.NOT_EMPTY), DirectoryFileFilter.INSTANCE);
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
    }
    
//3/**
 * 读取内容

 *
 */
public class CIOTest03 {

    public static void main(String[] args) throws IOException {
        //读取文件
        String msg =FileUtils.readFileToString(new File("emp.txt"),"UTF-8");
        System.out.println(msg);
        byte[] datas = FileUtils.readFileToByteArray(new File("emp.txt"));
        System.out.println(datas.length);
        
        //逐行读取
         List<String> msgs= FileUtils.readLines(new File("emp.txt"),"UTF-8");
         for (String string : msgs) {
            System.out.println(string);
        }
        LineIterator it =FileUtils.lineIterator(new File("emp.txt"),"UTF-8");
        while(it.hasNext()) {
            System.out.println(it.nextLine());
        }
        
    }

}

//4/**
 * 写出内容
  *
 */
public class CIOTest04 {

    public static void main(String[] args) throws IOException {
        //写出文件
        FileUtils.write(new File("happy.sxt"), "学习是一件伟大的事业\r\n","UTF-8");
        FileUtils.writeStringToFile(new File("happy.sxt"), "学习是一件辛苦的事业\r\n","UTF-8",true);
        FileUtils.writeByteArrayToFile(new File("happy.sxt"), "学习是一件幸福的事业\r\n".getBytes("UTF-8"),true);
        
        //写出列表
        List<String> datas =new ArrayList<String>();
        datas.add("马云");
        datas.add("马化腾");
        datas.add("弼马温");
        
        FileUtils.writeLines(new File("happy.sxt"), datas,"。。。。。",true);
    }

}
    
//5/**
 * 拷贝

 *
 */
public class CIOTest05 {

    public static void main(String[] args) throws IOException {
        //复制文件
        //FileUtils.copyFile(new File("p.png"),new File("p-copy.png"));
        //复制文件到目录
        //FileUtils.copyFileToDirectory(new File("p.png"),new File("lib"));
        //复制目录到目录
        //FileUtils.copyDirectoryToDirectory(new File("lib"),new File("lib2"));
        //复制目录
        //FileUtils.copyDirectory(new File("lib"),new File("lib2"));
        //拷贝URL内容
        //String url = "https://pic2.zhimg.com/v2-7d01cab20858648cbf62333a7988e6d0_qhd.jpg";
        //FileUtils.copyURLToFile(new URL(url), new File("marvel.jpg"));
        String datas =IOUtils.toString(new URL("http://www.163.com"), "gbk");
        System.out.println(datas);
    }

}

五 文件加锁

public class FileLocking{
    public static void main(String[] args)throws Exception{
        FileOutputStream fos =new FileOutputStream("file.txt");
        FileLock fl =fos.getChannel().tryLock();
        if(fl!=null){
            System.out.println("Locked File");
            TimeUnit.MILLISECONDS.sleep(100);
            fl.release();
            System.out.println("Release Lock");
        }
        fos.close();
    }
        
}
//输出结果
Locked File
Released Lock

注意:Socket-Channel、DatagramChannel、ServerSocketChannel不需要加锁。

tryLock()和Lock的区别?

​ tryLock()是非阻塞式的,如果不能获得锁,它将直接从方法调用处返回。

​ Lock()是阻塞式的,它要阻塞进程直至锁可以获得,或调用Lock的线程中断,或调用Lock的通道关闭。

tryLock(long position, long size, boolean shared)
    
Lock(long position, long size, boolean shared) ---第三个参数指定是否是共享锁
加锁的范围

​ 无参的加锁方法对整个文件进行加锁,甚至文件变大后也会如此,但是具有固定尺寸的锁不随文件尺寸的变化而变化(即:如果获得了某一区域上的锁【从position到position+size】,

​ 当文件增大超出position+size时,在position+size之外的部分不会被锁定)

所得类型的判断(独占锁、共享锁)

​ .isShared()

六、java序列化

6.1 保存(持久化)对象及其状态到内存或者磁盘

​ 但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对 象,并在将来重新读取被保存的对象.

6.2 序列化对象以字节数组保持静态成员不保存

​ 在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装

成对象。必须注意地是,对象序列化保存的是对象的”状态”,即它的成员变量

6.3 序列化用户远程对象传输
6.4 Serializable 实现序列化

只要一个类实现了 java.io.Serializable 接口,那么它就可以被序列化。

6.5 ObjectOutputStream ObjectInputStream 对对象进行序列化及反序列化

通过 ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化。

6.6 writeObject readObject 自定义序列化策略

在类中增加 writeObject 和 readObject 方法可以实现自定义序列化策略。

6.7 序列化ID

取决于以下三点是否一致:

①类路径

②功能代码

③两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID)

6.8 Transient关键字阻止该变量被序列化到文件中

1、在变量声明前加上 Transient 关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

2、敏感数据在网络中传输

服务器端给客户端发送序列化对象数据(如密码)

只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 五、IO流 1、IO流概述 (1)用来处理设备(硬盘,控制台,内存)间的数据。(2)java中对数据的操作都是通过...
    佘大将军阅读 503评论 0 0
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,365评论 0 4
  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序运行的过程中,可能需要对一些设备进...
    征程_Journey阅读 948评论 0 1
  • 1、IO流 1.1、概述 之前学习的File类它只能操作文件或文件夹,并不能去操作文件中的数据。真正保存数据的是文...
    Villain丶Cc阅读 2,647评论 0 5
  • 一、面试准备 1.自我介绍 - 展现什么能力。 - 做事认真负责,能吃苦耐劳,踏实肯干。...是一个有毅力,不会轻...
    北国南乡阅读 349评论 0 0