字节数组输入输出流
package com.sxt.io; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; /** * 四个步骤:字节数组输入流 * 1、创建源 : 字节数组 不要太大 * 2、选择流 * 3、操作 * 4、释放资源: 可以不用处理 * * @author * */ public class IOTest07 { public static void main(String[] args) { //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(); } } } }
字节数组输入输出流
package com.sxt.io; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * 字节数组输出流 ByteArrayOutputStream *1、创建源 : 内部维护 *2、选择流 : 不关联源 *3、操作(写出内容) *4、释放资源 :可以不用 * * 获取数据: toByteArray() * @author * */ public class IOTest08 { public static void main(String[] args) { //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) { } } } }
将图片读取到字节数组,再将字节数组写出到文件
package com.sxt.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** *1、 图片读取到字节数组 *2、 字节数组写出到文件 * @author * */ public class IOTest09 { public static void main(String[] args) { //图片转成字节数组 byte[] datas = fileToByteArray("p.png"); System.out.println(datas.length); byteArrayToFile(datas,"p-byte.png"); } /** * 1、图片读取到字节数组 * 1)、图片到程序 FileInputStream * 2)、程序到字节数组 ByteArrayOutputStream */ public static byte[] fileToByteArray(String filePath) { //1、创建源与目的地 File src = new File(filePath); byte[] dest =null; //2、选择流 InputStream is =null; ByteArrayOutputStream baos =null; try { is =new FileInputStream(src); baos = new ByteArrayOutputStream(); //3、操作 (分段读取) byte[] flush = new byte[1024*10]; //缓冲容器 int len = -1; //接收长度 while((len=is.read(flush))!=-1) { baos.write(flush,0,len); //写出到字节数组中 } baos.flush(); return baos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //4、释放资源 try { if(null!=is) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } /** * 2、字节数组写出到图片 * 1)、字节数组到程序 ByteArrayInputStream * 2)、程序到文件 FileOutputStream */ public static void byteArrayToFile(byte[] src,String filePath) { //1、创建源 File dest = new File(filePath); //2、选择流 InputStream is =null; OutputStream os =null; try { is =new ByteArrayInputStream(src); os = new FileOutputStream(dest); //3、操作 (分段读取) byte[] flush = new byte[5]; //缓冲容器 int len = -1; //接收长度 while((len=is.read(flush))!=-1) { os.write(flush,0,len); //写出到文件 } os.flush(); } catch (IOException e) { e.printStackTrace(); }finally { //4、释放资源 try { if (null != os) { os.close(); } } catch (Exception e) { } } } }
输入输出流封装
package com.sxt.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * 1、封装拷贝 * 2、封装释放 * @author * */ public class FileUtils { public static void main(String[] args) { //文件到文件 try { InputStream is = new FileInputStream("abc.txt"); OutputStream os = new FileOutputStream("abc-copy.txt"); copy(is,os); } catch (IOException e) { e.printStackTrace(); } //文件到字节数组 byte[] datas = null; try { InputStream is = new FileInputStream("p.png"); ByteArrayOutputStream os = new ByteArrayOutputStream(); copy(is,os); datas = os.toByteArray(); System.out.println(datas.length); } catch (IOException e) { e.printStackTrace(); } //字节数组到文件 try { InputStream is = new ByteArrayInputStream(datas); OutputStream os = new FileOutputStream("p-copy.png"); copy(is,os); } catch (IOException e) { e.printStackTrace(); } } /** * 对接输入输出流 * @param is * @param os */ public static void copy(InputStream is,OutputStream os) { try { //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、释放资源 分别关闭 先打开的后关闭 close(is,os); } } /** * 释放资源 * @param is * @param os */ public static void close(InputStream is ,OutputStream os) { try { if (null != os) { os.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(null!=is) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * 释放资源 * @param ios */ public static void close(Closeable... ios) { for(Closeable io:ios) { try { if(null!=io) { io.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
try ...with...resource
package com.sxt.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * try ...with...resource (jdk 1.7版本以上) * @author * */ public class FileUtils2 { public static void main(String[] args) { //文件到文件 try { InputStream is = new FileInputStream("abc.txt"); OutputStream os = new FileOutputStream("abc-copy.txt"); copy(is,os); } catch (IOException e) { e.printStackTrace(); } //文件到字节数组 byte[] datas = null; try { InputStream is = new FileInputStream("p.png"); ByteArrayOutputStream os = new ByteArrayOutputStream(); copy(is,os); datas = os.toByteArray(); System.out.println(datas.length); } catch (IOException e) { e.printStackTrace(); } //字节数组到文件 try { InputStream is = new ByteArrayInputStream(datas); OutputStream os = new FileOutputStream("p-copy.png"); copy(is,os); } catch (IOException e) { e.printStackTrace(); } } /** * 对接输入输出流 * try ...with...resource * @param is * @param os */ public static void copy(InputStream is,OutputStream os) { try(is;os) { //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(); } } }
字节流:BufferedInputStream和BufferedOutputStream:
BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8k,能够减少访问磁盘的次数,提高文件读取性能;
BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率
package com.sxt.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * 文件拷贝:文件字节输入、输出流 * * @author * */ public class Copy { public static void main(String[] args) { long t1 = System.currentTimeMillis(); copy("IO.mp4","IO-copy.mp4"); long t2 = System.currentTimeMillis(); System.out.println(t2-t1); } public static void copy(String srcPath,String destPath) { //1、创建源 File src = new File(srcPath); //源头 File dest = new File(destPath);//目的地 //2、选择流 try( InputStream is=new BufferedInputStream(new FileInputStream(src)); OutputStream os =new BufferedOutputStream( 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(); } } }
字符流:BufferedWriter和BufferedWriter
package com.sxt.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * 文件拷贝:文件字节输入、输出流 * * @author * */ public class CopyTxt { public static void main(String[] args) { copy("abc.txt","abc-copy.txt"); } public static void copy(String srcPath,String destPath) { //1、创建源 File src = new File(srcPath); //源头 File dest = new File(destPath);//目的地 //2、选择流 try( BufferedReader br=new BufferedReader(new FileReader(src)); BufferedWriter bw =new BufferedWriter( new FileWriter(dest)); ) { //3、操作 (逐行读取) String line =null; while((line=br.readLine())!=null) { bw.write(line); //逐行写出 bw.newLine(); } bw.flush(); }catch(FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }
字节流转为字符流:InputStreamReader和OutputStreamWriter
是字符流与字节流之间的桥梁,能将字节流转为字符流,并且能为字节流指定字符集,可处理一个个的字符
package com.sxt.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; /** * 转换流: InputStreamReader OutputStreamWriter * 1、以字符流的形式操作字节流(纯文本的) * 2、指定字符集 * @author TW * */ 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("操作异常"); } } }
package com.sxt.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; /** * 转换流: InputStreamReader OutputStreamWriter * 1、以字符流的形式操作字节流(纯文本的) * 2、指定字符集 * @author TW * */ 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("操作异常"); } } }
数据流:DataInputStream和DataOutputStream
package com.sxt.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; /** * 数据流: * 1、写出后读取 * 2、读取的顺序与写出保持一致 * * DataOutputStream * DataInputStream * @author TW * */ public class DataTest { 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); } }
对象流: ObjectOutputStream(需要实现Serializable接口)
package com.sxt.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Date; /** * 对象流: * 1、写出后读取 * 2、读取的顺序与写出保持一致 * 3、不是所有的对象都可以序列化Serializable * * ObjectOutputStream * ObjectInputStream * @author * */ public class ObjectTest { public static void main(String[] args) throws IOException, ClassNotFoundException { //写出 -->序列化 ByteArrayOutputStream baos =new ByteArrayOutputStream(); ObjectOutputStream oos =new ObjectOutputStream(new BufferedOutputStream(baos)); //操作数据类型 +数据 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(); byte[] datas =baos.toByteArray(); System.out.println(datas.length); //读取 -->反序列化 ObjectInputStream ois =new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas))); //顺序与写出一致 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()); } } } //javabean 封装数据 class Employee implements java.io.Serializable{ private transient String name; //该数据不需要序列化 private double salary; public Employee() { } public Employee(String name, double salary) { this.name = name; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
package com.sxt.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Date; /** * 对象流: 1、写出后读取 2、读取的顺序与写出保持一致 3、不是所有的对象都可以序列化Serializable * * ObjectOutputStream ObjectInputStream * * @author * */ 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(); } }
打印流
package com.mengge.io; import java.io.BufferedOutputStream; import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.io.PrintWriter; public class PrintStreamHandle { public static void main(String[] args) { //打印流 System.out PrintStream ps = System.out; ps.println("打印流"); ps.println(true); //自动刷新 ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")) , true); ps.println("打印流"); ps.println(true); ps.close(); //重定向输出端 System.setOut(ps); System.out.println("change"); //重定向回控制台 System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)) , true)); System.out.println("i am backing"); } public static void printStream() throws FileNotFoundException { PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream("print.txt")) , true); pw.println("打印流"); pw.println(true); pw.close(); } }
文件分割:面向过程(RandomAccessFile)
package com.sxt.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; /** * 随机读取和写入流 RandomAccessFile * @author * */ public class RandTest01 { public static void main(String[] args) throws IOException { //分多少块 File src = new File("src/com/sxt/io/Copy.java"); //总长度 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("src/com/sxt/io/Copy.java"),"r"); //随机读取 raf.seek(beginPos); //读取 //3、操作 (分段读取) byte[] flush = new byte[1024]; //缓冲容器 int len = -1; //接收长度 while((len=raf.read(flush))!=-1) { if(actualSize>len) { //获取本次读取的所有内容 System.out.println(new String(flush,0,len)); actualSize -=len; }else { System.out.println(new String(flush,0,actualSize)); break; } } raf.close(); } //分开思想: 起始、实际大小 public static void test2() throws IOException { RandomAccessFile raf =new RandomAccessFile(new File("src/com/sxt/io/Copy.java"),"r"); //起始位置 int beginPos =2+1026; //实际大小 int actualSize = 1026; //随机读取 raf.seek(beginPos); //读取 //3、操作 (分段读取) byte[] flush = new byte[1024]; //缓冲容器 int len = -1; //接收长度 while((len=raf.read(flush))!=-1) { if(actualSize>len) { //获取本次读取的所有内容 System.out.println(new String(flush,0,len)); actualSize -=len; }else { System.out.println(new String(flush,0,actualSize)); break; } } raf.close(); } //指定起始位置,读取剩余所有内容 public static void test1() throws IOException { RandomAccessFile raf =new RandomAccessFile(new File("src/com/sxt/io/Copy.java"),"r"); //随机读取 raf.seek(2); //读取 //3、操作 (分段读取) byte[] flush = new byte[1024]; //缓冲容器 int len = -1; //接收长度 while((len=raf.read(flush))!=-1) { System.out.println(new String(flush,0,len)); } raf.close(); } }
文件分割:面向对象
package com.sxt.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; /** * 随机读取和写入流 RandomAccessFile * @author * */ public class RandTest02 { 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) { //获取本次读取的所有内容 raf2.write(flush, 0, len); actualSize -=len; }else { raf2.write(flush, 0, actualSize); break; } } raf2.close(); raf.close(); } }
序列流:文件合并(SequenceInputStream)
package com.sxt.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.List; import java.util.Vector; /** * 面向对象思想封装 分割 * @author * */ 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"); } }