`

文件上传原理学习

    博客分类:
  • java
 
阅读更多

 

 

  个人理解:

   http协议上传文件与传输数据就是以下面的格式进行传输,普通数据按照格式解析即可,如果是文件则将文件内容按照格式进行解析,然后将文件内容保存到服务器端相应的文件中即可。

       /* -----------------------------7d91463b90688
			Content-Disposition: form-data; name="pic"; filename="111.txt"
			Content-Type: text/plain
			
			文件内容开始
			111 
			222
			333 文件中的内容,
			文件内容结束

            -----------------------------7d91463b90688--
			Content-Disposition: form-data; name="name"
			
			wang
			-----------------------------7d91463b90688
			Content-Disposition: form-data; name="age"

			10
         */

 

 

 

 

package test;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class Welcome extends HttpServlet{
	
    protected String encoding = "UTF-8";
    protected String decoding = null;
    
    /**
     * 个人理解文件上传就是将文件的内容以流的形式传到服务器,然后在服务器端创建一个文件将文件内容写入文件中即可 
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        /*****
         * -----------------------------7d91463b90688
			Content-Disposition: form-data; name="pic"; filename="111.txt"
			Content-Type: text/plain
			
			文件内容开始
			111 
			222
			333 文件中的内容,
			文件内容结束

            -----------------------------7d91463b90688--
			Content-Disposition: form-data; name="name"
			
			wang
			-----------------------------7d91463b90688
			Content-Disposition: form-data; name="age"

			10
         */
        request.setCharacterEncoding("UTF-8");//设定输入的格式
        response.setCharacterEncoding("UTF-8");//设定输入的格式
        ServletInputStream sis = request.getInputStream();//得到输入流
        int len = request.getContentLength();//得到内容的长度
        
        int index = 0;
        String tmp = null;//临时保存一行数据的变量
        boolean isFirst = true;//第一次访问的时候
        String firstLine = null;//保存第一行数据作为结束的标志
        System.out.println("the content lenth is: "+len);
        //iindex 能把读 ServetInputStream 位数据 的计数的长度存档
        int[] iindex = new int[1];//记录每一次读取的字节的数
        byte[] bytes = new byte[4096];//缓冲数组的大小
        //文件名
        String filename = null;
        //循环读取请求头中的内容
        while((tmp = readLine(bytes, iindex, sis, encoding)) != null)
        {
            if(isFirst)//判断是否是第一行
            {
                firstLine = tmp;//将第一行数据保存下来
                isFirst = false;//将标识改为false
            }
            //判断是否到达客户上传的文件的文件名的那一行数据
            index = tmp.indexOf("filename=");
            if(index != -1)
            {   
                //  Content-Disposition: form-data; name="f1"; filename="110425030337-0.jpg"
                String tailString = tmp.substring(index+10);//将文件名截取下来 110425030337-0.jpg"
                System.out.println("指针到文件名开始标志-->:index="+index+"tailString="+tailString);
                if(tailString != null)
                {//截取下来的文件的名字的最后还包含一个引号,得到引号的下标
                    int ii = tailString.indexOf("\"");
                    //再次截取字符串得到文件名
                    filename = tailString.substring(0,ii);
                }
                System.out.println("得到文件名的时候:tmp="+tmp);
                break;//下一行就是上传的文件的数据所以就跳出循环
            }
            
        }
        
        filename = getName(filename);
        
        if(filename == null)//如果文件名为空那么将随意给一个名字避免出现bug
        {
            filename = "file.out1";
        }
        
        //文件写出的地址
        String filepath = "d:/"+filename;
        //初始化输出流对象
        FileOutputStream fos = new FileOutputStream(filepath);
        
        String endFlag = firstLine.substring(0, firstLine.length() -2)+"--"+firstLine.substring(firstLine.length() -2);
        System.out.println("firstLine元数据"+firstLine);
        System.out.println("前一段截取:"+firstLine.substring(0, firstLine.length() -2));
        System.out.println("后一段截取:"+firstLine.substring(firstLine.length() -2));
        System.out.println("结束的标识符:"+endFlag);
        //因为下一行是上传的文件的数据类型  所以就读取一下将指针移动到下一行 下一行就是客户上传的数据的所有的内容
        String contentType = readLine(bytes, iindex, sis, encoding);
        System.out.println("Content-Type is : "+contentType);
        if(contentType != null)
        {
            if(contentType.indexOf("Content-Type") == -1)
            {
                System.out.println(contentType);
            }
            else
            {//经接着是换行\r\n所以将指针向下移动一行
                System.out.println("the head of file: "+readLine(bytes, iindex, sis, encoding));
            }
        }
        
        //从现在开始读取的数据就是客户端上传的文件的数据
        boolean tt = false;
        int mark = 0;
        byte[] backups = new byte[4096];
        while((tmp = readLine(bytes, iindex, sis, encoding)) != null)
        {
        	//结束是以这样的形式结束的 -----------------------------3907944211862--
            if(endFlag.equals(tmp))
            {
                if(mark >2)
                {
                    //现在指针已经读取到最后的一行数据所以不能在往下读取了
                    System.out.println("文件到了最后:"+mark);
                    //将上一行的数据写入指定的文件为什么要减2因为最后一行的数据有一个\r\n占用2个字节   二进制的数据回车换行是0D 0A
                    fos.write(backups, 0, mark-2);
                    fos.flush();
                }
                break;//文件写出完毕
            }
            else//下一次写出上一次的数据
            {
                if(tt)
                {
                    fos.write(backups, 0, mark);
                    fos.flush();
                }
                mark = iindex[0];
                for(int i=0;i<iindex[0];i++)
                {
                    backups[i] = bytes[i];
                }
                tt = true;
            }
        }
        
        fos.close();
        sis.close();
        
    }
    /***
     * 因为每种浏览器的上传的文件的名字不一样
     * 所以还需要判断是否是文件的全路径如果是那么将文件的名字截取下来
     * 返回
     * @param name
     * @return
     */
    protected String getName(String name)
    {
        String rtn = null;
        System.out.println("传入的全部的名称:"+name);
        if(name != null)
        {
            int index = name.lastIndexOf("/");
            if(index != -1)
            {
                rtn = name.substring(index +1);
            }
            else
            {
                index = name.lastIndexOf("\\");
                if(index != -1)
                {
                    rtn = name.substring(index +1);
                }
                else
                {
                    rtn = name;
                }
            }
        }
        return rtn;
    }
    
    //读取来自客户端请求的数据每次读取一行将其返回
    protected String readLine(byte[] bytes, int[] index, ServletInputStream sis, String enconding)
    {
        try {
            index[0] = sis.readLine(bytes, 0, bytes.length);
            if(index[0] < 0)
                return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        try{
            if(encoding == null)
            {
                return new String(bytes, 0, index[0]);
            }
            else
            {
                return new String(bytes, 0, index[0], encoding);
            }
        }catch(Exception e)
        {
            return null;
        }
    }
}


 

分享到:
评论

相关推荐

    Struts2.0文件上传原理

    以下是对Struts2.0文件上传原理的详细解释: 1. **HTTP协议与表单提交** 在HTML表单中,如果需要上传文件,`&lt;form&gt;`标签必须包含`enctype="multipart/form-data"`属性。这是因为普通POST请求无法处理二进制数据,...

    通过Servlet文件上传理解Struts2文件上传原理(附源码)

    在本文中,我们将深入探讨如何使用Servlet来理解Struts2中的文件上传原理。Servlet是Java Web应用程序中的一个组件,用于处理HTTP请求和响应。而Struts2是一个基于MVC(模型-视图-控制器)设计模式的开源Web应用框架...

    多文件上传--多文件上传组件

    首先,我们来详细了解一下多文件上传的原理。在Web环境中,HTML5引入了`&lt;input type="file" multiple&gt;`标签,使得浏览器支持用户同时选择多个文件进行上传。而在服务器端,开发者通常会使用各种编程语言(如Java、...

    JSP文件上传 支持进度条显示.rar

    在IT领域,文件上传是Web应用中常见的功能之一,尤其在管理系统中,用户可能需要上传各种数据文件。...通过研究这个项目,可以深入理解文件上传的原理,以及如何在实际应用中处理大文件和多文件上传。

    文件上传小例子,学习中的练习

    这个"文件上传小例子"是你在学习过程中的一次实践,它可能涉及了基本的文件处理和网络传输原理。下面我们将深入探讨相关的知识点。 首先,文件上传涉及到前端和后端两个部分。前端通常是用户与应用交互的地方,它...

    silverlight 文件上传,文件上传进度,大文件上传,中文注释

    首先,让我们深入了解Silverlight文件上传的基本原理。在Silverlight中,文件上传通常是通过`HttpWebRequest`对象实现的,它允许客户端向服务器发送HTTP请求。用户可以选择文件后, Silverlight应用将读取文件内容并...

    6种经典的asp上传文件源码+带进度条

    1. 文件上传原理: ASP文件上传主要是通过HTML表单中的`&lt;input type="file"&gt;`元素来实现的。用户选择文件后,表单提交到服务器,服务器端的ASP代码解析请求并处理文件。由于HTTP协议本身的限制,文件上传不支持进度...

    MVC文件上传源码

    1. **文件上传原理**: 文件上传是Web应用中的常见需求,通常涉及HTTP协议的POST请求。在MVC中,通过`HttpPostedFileBase`或`IFormFile`接口处理上传的文件。用户选择要上传的文件后,浏览器将文件内容封装到HTTP...

    okhttp多文件上传

    二、多文件上传原理 多文件上传通常涉及表单数据的Multipart编码。在HTTP请求中,MIME类型为`multipart/form-data`的表单数据允许我们将多个部分(如文本字段和文件)组合在一起发送。每个部分都有自己的头信息,...

    C#webapi文件上传下载源码

    总的来说,"C# WebAPI文件上传下载源码"是一个包含关键功能实现的代码示例,对于学习如何在C# WebAPI项目中处理文件操作非常有帮助。通过研究这些源码,开发者可以深入理解WebAPI的工作原理,以及如何在实际项目中...

    javaweb文件上传与下载模块源代码

    通过学习这个源代码模块,开发者不仅可以了解文件上传和下载的基本原理,还能学习到如何在实际项目中应用这些技术,从而提升Web应用的交互性和功能性。对于初学者,这是一个很好的实践平台,有助于加深对Java Web...

    java文件上传进度条学习资料分享c

    首先,我们要理解文件上传的基本原理。在HTTP协议中,文件上传通常是通过POST请求实现的。在Java Web应用中,我们通常使用Servlet或者Spring MVC框架来处理这些请求。用户选择要上传的文件后,浏览器会将文件内容...

    springMVC多文件上传demo

    2. **多文件上传原理** 在HTML中,`&lt;input type="file" multiple&gt;`元素允许用户选择多个文件进行上传。当表单提交时,这些文件会被封装在MultipartRequest中,然后由服务器端的Spring MVC控制器处理。 3. **...

    struts2 文件上传,也可以多文件上传

    首先,我们要了解Struts2文件上传的基本原理。Struts2使用Apache的Commons FileUpload库来处理文件上传。这个库将HTTP请求中的multipart/form-data解析为一个个单独的文件和字段,使得我们可以方便地访问上传的文件...

    SpringMVC单文件上传、多文件上传、文件列表显示、文件下载

    首先,我们需要理解SpringMVC处理文件上传的基本原理。在SpringMVC中,文件上传通常涉及到`CommonsMultipartResolver`解析器,它是Spring提供的一个用于处理multipart请求的解析器。multipart请求是HTTP协议中用于...

    Android 文件上传Demo

    在Android平台上,文件...以上内容是关于Android文件上传的基本原理和步骤,实际应用中可能还需要根据业务需求进行定制化开发,如添加身份验证、权限控制等。如果你对附件中的代码有任何疑问,可以进一步研究和学习。

    Jsp文件上传下载

    在Java Web开发中,JSP(JavaServer Pages)是一种用于创建动态网页的技术,它允许开发者在HTML代码中嵌入Java代码来实现服务器...同时,理解文件上传下载的底层原理,对于提升你的Java Web开发技能也是非常有帮助的。

    文件上传,jsp限定后缀名的文件上传功能

    通过分析和学习这个示例,你可以更深入地理解文件上传以及后缀名限制的具体实现步骤,包括HTML表单的设计、Servlet的编写以及与JSP的配合。 总的来说,JSP限定后缀名的文件上传功能涉及到客户端与服务器之间的数据...

    兼容多个浏览器的单文件上传

    首先,我们来看文件上传的基本原理。在HTML中,`&lt;input type="file"&gt;`标签用于让用户选择本地文件,当用户选择文件后,可以通过JavaScript获取到选中的文件信息。在HTML5中,通过File API可以实现文件的读取、操作和...

Global site tag (gtag.js) - Google Analytics