Java IO

五、  Java IO

1.  IO

1. java.io 包中几乎包含了所有操作输入、输出所需要的类
2. 一个流可以理解为一个数据的序列
3. 输入流表示从一个源读取数据,输出流表示向一个目标写数据
4. 字节流和字符流:
   1)字节流:二进制,可处理一切文件(纯文本、音频、视频等)
   2)字符流:纯文本,只能处理纯文本
5. 字节流、字符流与文件 1)字节流: 输入流:InputStream is = new FileInputStream(File file);
is.read(byte[] bt);// 从源中读取 bt.length 长度的字节并赋给数组 bt;返回读取的字节数;如果是文件结尾则返回 -1 输出流:OutputStream os = new FileOutputStream(File file, boolean append);
os.write(byte[] bt);// 将 bt 数组中 bt.length 长度的字节写入到目标中
2)字符流: 输入流:Reader reader = new FileReader(File file);
reader.read(char[] ch); // 从源中读取 ch.length 长度的字符并赋给数组 ch;返回读取的字符数;如果是文件结尾则返回 -1
输出流:Writer writer = new FileWriter(File file, boolean append);
writer.write(char[] ch);// 将 ch 数组中 ch.length 长度的字符写入到目标中
writer.append(CharSequence csq);// 追加字符序列,底层实现:writer.write(csq.toString());返回 Writer
6. 缓冲流:增加缓冲功能,避免频繁读写硬盘,提高性能 1)字节缓冲流 输入流:new BufferedInputStream(InputStream in); 输出流:new BufferedOutputStream(OutputStream out); 2)字符缓冲流 输入流:BufferedReader br = new BufferedReader(Reader in);
子类新增方法:br.readLine();// 无参数,行读取,返回 String 类型,如果是文件结尾则返回 null;不能发生多态
输出流:BufferedWriter bw = new BufferedWriter(Writer out);
子类新增方法:bw.newLine();// 无参数,相当于一个换行符,无返回类型;不能发生多态

7. 转换流:字节流转为字符流 1)编码与解码概念 编码:字符 --编码字符集--> 二进制 解码:二进制 --解码字符集--> 字符
       byte[] data = "中国".getBytes("gbk");// 编码 char-->byte
       String str = new
String(data, "gbk");// 解码 byte-->char,与编码字符集统一,否则出现乱码 2)乱码 a.编码与解码的字符集不统一 b.字节缺少,长度丢失 3)转换流 a.输出流(写入),编码 OutputStreamWriter(OutputStream out, String charsetName); b.输入流(读取),解码 InputStreamReader(InputStream in, String charsetName);
8. 使用 1)创建 src 或 dest 2)选择流 3)操作流 4)释放资源 close();

9. 控制台
  1)键盘输入
Scanner sc = new Scanner(System.in);
  2)文件输入
InputStream is = new BufferedInputStream(new FileInputStream(src)); Scanner sc = new Scanner(is);
  3)输出到控制台
System.out.println("hello, world");
4)输出到指定文件
PrintStream ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(dest))); ps.println("hello, world");
5)错误样式输出
System.err.println();
  6)重定向
     System.setIn(InputStream in);
     System.setOut(PrintStream out);
System.setOut(new PrintStream(OutputStream out, boolean autoFlush)); System.out.println("控制台-->文件");
System.setErr(PrintStream err);
   7)回到控制台:FileDescriptor.out
System.setOut(new PrintStream(FileDescriptor.out, boolean autoFlush)); System.out.println("控制台")
public class CopyDirectory {
   
    //拷贝文件夹
    public static void copyDir(File src, File dest){
        if(src.isDirectory()){
            //父类文件夹不能拷贝到子类中
            if(dest.getAbsolutePath().contains(src.getAbsolutePath())){
                return;
            }
        }
        copyFileDetail(src, dest);
    }

    //拷贝细节
    private static void copyFileDetail(File src, File dest) {
        if(src.isFile()){//文件
            copyFile(src, dest);
        }else if(src.isDirectory()){//文件夹
            dest.mkdirs();
            //获取下一级文件|目录
            for(File sub : src.listFiles()){
                copyFileDetail(sub, new File(dest, sub.getName()));
            } 
        }  
    }
    private static void copyFile(File src, File dest) {
        //2.选择流
        InputStream is = null;
        OutputStream os = null;
        try {
            is = new BufferedInputStream(new FileInputStream(src));
            os = new BufferedOutputStream(new FileOutputStream(dest));
            //3.文件拷贝 循环+读取+写出
            byte[] bt = new byte[1024];
            int len = 0;
            while(-1!=(len=is.read(bt))){
                os.write(bt, 0, len);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件查找失败");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件拷贝失败");
        } finally{
            if(null!=is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("文件关闭失败");
                }
            }
            if(null!=os){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("文件关闭失败");
                }
            }
        }
    }
}
拷贝文件夹
public class Convert {
    public static void main(String[] args) throws IOException {
        
        //编码
        BufferedWriter or = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(
                                new File("E:/test/a.txt")), "gbk"
                        )
                );
        String off = "转换流:字节流转为字符流";
        or.write(off);
        or.flush();
        
        //解码
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(
                                new File("E:/test/a.txt")), "gbk"    
                        )
                );
        String info = null;
        while(null!=(info=br.readLine())){
            System.out.println(info);    
        }

    }
}
转换流
public class SplitFile {
    //文件名
    private String fileName;
    //文件路径
    private String filePath;
    //文件大小
    private long length;
    //块数
    private int size;
    //每一块的大小
    private long blockSize;
    //每块的名称
    private List<String> blockPath;
    
    
    public SplitFile(){
        this.blockPath = new ArrayList<String>();
    }
    
    public SplitFile(String filePath){
        this(filePath, 1024);
    }
    
    public SplitFile(String filePath,long blockSize){
        this();
        this.filePath = filePath;
        this.blockSize = blockSize;
        init();
    }

    private void init() {
        File src = null;
        src=new File(filePath);
        //健壮性
        if(null==filePath || !src.exists()){
            return;
        }
        
        if(src.isDirectory()){
            return;
        }
        //文件名
        this.fileName = src.getName();
        
        //计算块数,是实际大小,每块大小
        this.length = src.length();
        //修正最后一块大小
        if(this.blockSize>length){
            this.blockSize=length;
        }
        //确定块数
        this.size = (int)Math.ceil(length*1.0/this.blockSize);
        
    }
    
    private void initPathName(String destPath){
        for(int i=0;i<this.size;i++){
            String original = this.fileName.substring(0, this.fileName.lastIndexOf("."));
            String tail = this.fileName.substring(this.fileName.lastIndexOf("."));
            this.blockPath.add(destPath+"/"+original+"_Part"+i+tail); 
        }
    }
    
    /**
     * 文件分割 
     * @param destPath 分割文件的存放 目录
     */
    public void split(String destPath){
        //确定文件路径
        initPathName(destPath);
        
        long beginPos = 0;//起始点
        long actualBlockSize = this.blockSize;//实际大小
        
        //计算所有块的大小,位置,索引
        for(int i=0; i<this.size; i++){
            if(i==size-1){//最后一块
                actualBlockSize = this.length - beginPos;
            }
            splitDetail(i, beginPos, actualBlockSize);
            beginPos += actualBlockSize;
        }
    }
    
    public void splitDetail(int index, long beginPos, long actualBlockSize){
        //文件的拷贝
        //1.创建源
        File src = new File(this.filePath);//源文件
        File dest = new File(this.blockPath.get(index));//目标文件
        //2.选择流
        RandomAccessFile raf = null;
        BufferedOutputStream bos = null;
        
        try {
            raf = new RandomAccessFile(src, "r");
            bos = new BufferedOutputStream(new FileOutputStream(dest));
            //3.从指定位置开始读取文件
            raf.seek(beginPos);
            //缓冲区
            byte[] bt = new byte[1024];
            //接收长度
            int len = 0;
            
            while(-1!=(len=raf.read(bt))){
                if(actualBlockSize-len>0){//如果每块的实际大小大于 1024 个字节数,则继续循环
                    bos.write(bt, 0, len);
                    actualBlockSize -= len;//剩余量
                }else{//写出最后一次的剩余量
                    bos.write(bt, 0, (int)actualBlockSize);
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(null!=raf && null!=bos){
                try {
                    raf.close();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                
            }
        }
                
    }
    
    /**
     * 文件合并
     */
    public void mergeFile(String destPath){
        //创建源
        File dest = new File(destPath);
        //选择流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(dest,false));
            for(int i=0;i<this.blockPath.size();i++){
                bis = new BufferedInputStream(
                        new FileInputStream(new File(this.blockPath.get(i)))
                        );    
                //缓冲区
                byte[] bt = new byte[1024];
                //接收长度
                int len = 0;
                
                while(-1!=(len=bis.read(bt))){
                    bos.write(bt,0,len);
                }
                bos.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(null!=bis && null!=bos){
                try {
                    bis.close();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
        
    /**
     * 合并02
     */
    public void mergeFile02(String destPath){
        //1.创建源
        File dest = new File(destPath);
        //选择流
        SequenceInputStream sis = null;//输入流
        BufferedOutputStream bos = null;//输出流
        //创建容器
        Vector<InputStream> vi = new Vector<InputStream>();
        try {
            bos = new BufferedOutputStream(new FileOutputStream(dest,false));
            for(int i=0;i<this.blockPath.size();i++){
                vi.add(new BufferedInputStream(
                        new FileInputStream(new File(this.blockPath.get(i)))
                        ));    
            }
            sis = new SequenceInputStream(vi.elements());
                //缓冲区
                byte[] bt = new byte[1024];
                //接收长度
                int len = 0;
                
                while(-1!=(len=sis.read(bt))){
                    bos.write(bt,0,len);
                }
                bos.flush();
    
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(null!=sis && null!=bos){
                try {
                    sis.close();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     * main
     */
    public static void main(String[] args) {
        SplitFile file = new SplitFile("E:/test/k.txt", 50);
        System.out.println(file.size);
        file.split("E:/test");
        file.mergeFile("E:/test/k02.txt");
        file.mergeFile02("E:/test/k03.txt");
    }
}
文件分割
public class CloseUtil {
    /**
     * 工具类关闭流
     * 可变参数: ... 只能在形参最后一个位置,处理方式和数组一致
     * @param io
     */
    public static void  close(Closeable ...io){
        for(Closeable temp:io){
            if(null!=temp){
                try {
                    temp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     * 泛型方法的关闭流
     * @param io
     */
    public static<T extends Closeable> void  closeAll(T ...io){
        for(Closeable temp:io){
            if(null!=temp){
                try {
                    temp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
关闭流
原文地址:https://www.cnblogs.com/IT-LFP/p/11009294.html