java IO框架关系 概念

1 篇文章 0 订阅
I/O结构关系图
 
 
字节与字符的概念
 
字节 byte
 
            计算机信息技术用于计量存储容量的一种计量单位,通常使用字节数组byte[]读取字节类型的文件。
            FileInputStream:文件流的具体实现类,继承InputStream(流), 如下例子,将文件通过文件流实现类,转换为流。
            FileOutputStream:文件流的具体实现类,继承OutputStream(流),例如  OutputStream os = new FileOutputStream(file);
            InputStream,OutputStream:输入/输出流。文件内容的写入通过其实现,读取通过BufferedInputStream.read()读取。
            MultiPartFile: 一个接口,用于接收文件(前台传进来的文件),并通过transferTo(File)方法转换为文件,也可以MultiPartFile.getInputStream()获取文件流,路径,文件名等信息。
 
            FileInputStream、FileOutputStream直接用于操作文件流的,进行文件与流的转换,是文件流的最直接操作类;
            InputStream、OutputStream用于流内容的读取与写入,不能进行文件级别的信息操作。
 
字符 char
 
        是指计算机中使用的文字和符号,通常使用字符数组char[]读取字符类型的文件。
        InputStreamReader : 是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符; 参数为InputStream类型,
        BufferedReader : 提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
        BufferedWriter: 字符缓冲输出流,用于写文件,刷新,关闭流等操作。
        FileWriter: 字符输出流,与bufferedWriter区别是,BufferedWriter有缓冲区8192个字符,缓冲8192个字符并查码表,FileWriter写一个查一次码表。
        字符流 = 字节流 + 码表, 一字符 = 2字节
    
        不管是字节流还是字符流,文件转换为流一定是通过fileInputStream转化并成为字节流,如果是字符流,则通过new inputStreamReader(InputStream in)转为字符流,框架里构造函数可录入多种形式的参数生成字符流,其实走的都是最底层的 public InputStreamReader(InputStream in)方法。
 
文件概念
  • 文件名
         文件在java中是一个实体,具有多种属性方法,常用包括获取文件路径(相对,绝对),获取文件名,获取父级路径。在文件实体中,文件名也作为文件路径的一部分。
         例如 C:\\Users\\Administrator\D\esktop\\CNY15_20190925_001_022298.apk 这是一个完整的文件路径,也是完整的文件;
 
  • 常用的文件操作方法
            获取父级目录:使用getParent()方法可以获取父级路径,C:\Users\Administrator\Desktop,
            创建目录:需要实例化一个File file = new File("filePath");file.mkdirs()方法,mkdirs可以创建父级目录,mkdir创建当前目录,例如C:\Users\Administrator\Desktop下创建                                    asdf 文件夹,使用mkdirs情况下,若无C:\\Users\\Administrator\\Desktop,则会创建;使用mkdir,若无C:\\Users\\Administrator\\Desktop,则目录不会创建。
            检测目录:实例化file并使用exist()方法。
            移动文件:files.move(源文件,目标文件),文件移走后源文件删除。
            删除文件:files.delete()。
 
  • 相对路径与绝对路径
            相对路径: 两个文件处于同一目录下,则这两个文件成相对关系,如d:/a/abc.html与d:/a/b/bdeg.jpg,若该html需要引入此图片,路径直接填写b/bdeg.jpg即可。
            绝对路径: 两个文件不处于同一目录下,则这两个文件成绝对关系,如需互相调用,则要填写完整路径。
 
  • 注意事项
            分隔符: windows与linux分隔符不同,windows为\\,linux为/,因为前后台路径的交互,可能会有分隔符转换的情况发生,需要注意;使用File.seperator代替分隔符,该方法会判定操作系统并进行适应。
                I/O流: 对文件进行操作时,要注意是否有文件流存在,若该文件被解析成流,需要先关闭流。
  • 文件下载

 前台下载:页面使用a标签进行连接,后台使用输出流写文件。OutputStream out = response.getOutputStream(),注意如果使用http进行文件下载,则在该线程内就不能使用 http做页面响应了 

 后台下载:使用输出流OutputStream.write()继续下载,注意一定要使用write(byte b[], int off, int len),如果不录入写入长度length,很有可能写完的文件会多出一部分内容。

 跨服务器下载: 可以使用sftp或ftp,可以参考sftp工具类ftp工具类


  
 /**
     * 使用http响应进行文件下载 
     * 例子
     * 
     */
    @SuppressWarnings("unused")
   public static String downloadFile(HttpServletRequest request, HttpServletResponse response,
            String fileName, String path) {
        if(fileName != null){
            File file = new File(path);
            if (file.exists()) {
                try{
                    // 转码之后的文件名
                    String finalFileName = "";
                    // 获取客户端浏览器信息
                    String agent = request.getHeader("User-Agent");
                    // 是否为IE浏览器
                    boolean isMSIE = (agent != null && agent.indexOf("MSIE") != -1);
                    if (isMSIE) {
                        // IE浏览器下文件名
                        finalFileName = java.net.URLEncoder.encode(fileName, "UTF8");
                    } else {
                        // 其他浏览器下文件名
                        finalFileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
                    }
                    response.setHeader("Content-Disposition", "attachment; filename=\"" + finalFileName + "\"");
                    response.resetBuffer();
                    // 利用输出输入流导出文件
                    OutputStream sos = response.getOutputStream();
                    InputStream is = new FileInputStream(file);
                    byte[] b = new byte[1024];
                    int len;
                    while ((len = is.read(b)) > 0) {
                        sos.write(b,0,len);
                    }
                    // 关闭流
                    if (is != null) {
                        is.close();
                    }
                    sos.flush();
                    response.flushBuffer();
                    // 关闭流
                    sos.close();
                    return "success";
                }catch(IllegalStateException | IOException e){
                    return "error";
                }
            }
        }
        return "field";
    }


    /*
     * 例子
     * 使用新文件内容重写旧文件(只针对字符流/文本文件)
     * out = new BufferedWriter(new FileWriter(filePath, true))表示在原文件基础上继续编写
     */
                 BufferedWriter out = null;
                 String content = null;
                 out = new BufferedWriter(new FileWriter(filePath));
                 content = FileUtils.readFileToString(file, "GBK");
                 file.delete();
                 out.write(content);
                 out.flush();
                 out.close();


    /*
     * 例子
     * 输入流转换为文件
     */
    public static void inputStreamToFile(InputStream ins, File file) throws IOException {
         OutputStream os = new FileOutputStream(file);
         int bytesRead = 0;
         byte[] buffer = new byte[128];
         while ((bytesRead = ins.read(buffer)) != -1) {
             os.write(buffer, 0 , bytesRead);
         }
         os.flush();
         os.close();
         ins.close();
    }

 

 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值