在Java中将文件块转换为页面

在Java中将文件块转换为页面,java,json,spring,file,spring-mvc,Java,Json,Spring,File,Spring Mvc,我有一个代码,我读取一个大块的大文件并将其转换成JSON发送给Spring MVC控制器,我的方法类似于这样,我传递我想从哪里开始的偏移量和以noBytes表示的chunkSize,结果被传递成JSON并发送给我的控制器 public String readByteBlock(File file, int offset, int noBytes) throws IOException { InputStream in = new FileInputStream(file);

我有一个代码,我读取一个大块的大文件并将其转换成JSON发送给Spring MVC控制器,我的方法类似于这样,我传递我想从哪里开始的偏移量和以noBytes表示的chunkSize,结果被传递成JSON并发送给我的控制器

  public String readByteBlock(File file, int offset, int noBytes) throws IOException {
    InputStream in = new FileInputStream(file);
    byte[] result = new byte[noBytes];
    in.skip(offset);
    in.read(result, 0, noBytes);
    return FileSaver.byteArrayToString(result, noBytes);
}
@RequestMapping("/page/{id}")
@ResponseBody   
    File file = new File("C:/teste.txt");
    FileSaver fs = new FileSaver();
    int byteblock = 100;        
    int offset = 0;
    if(id.equals("next")){      
        offset = (int) req.getSession().getAttribute("prevEndPos"); 
        String s = fs.readByteBlock(file, offset, byteblock);       
        req.getSession().setAttribute("prevStartPos", offset);     
        req.getSession().setAttribute("prevEndPos", (offset + byteblock) );       
        return s;
    }
    if(id.equals("prev")){
        offset = (int) req.getSession().getAttribute("prevStartPos") - byteblock ; 
        if(offset < 0 ){
            String s = fs.readByteBlock(file, 0, byteblock);
              return s;
        }
        String s = fs.readByteBlock(file, offset, byteblock);         
        req.getSession().setAttribute("prevStartPos", (offset - byteblock) );      
        return s;
    }
    String s = fs.readByteBlock(file, 0, byteblock);
    req.getSession().setAttribute("prevStartPos", offset);
    req.getSession().setAttribute("prevEndPos", (offset + byteblock));
    return s;
我在控制器中执行下一个和上一个分页时遇到问题

  public String readByteBlock(File file, int offset, int noBytes) throws IOException {
    InputStream in = new FileInputStream(file);
    byte[] result = new byte[noBytes];
    in.skip(offset);
    in.read(result, 0, noBytes);
    return FileSaver.byteArrayToString(result, noBytes);
}
@RequestMapping("/page/{id}")
@ResponseBody   
    File file = new File("C:/teste.txt");
    FileSaver fs = new FileSaver();
    int byteblock = 100;        
    int offset = 0;
    if(id.equals("next")){      
        offset = (int) req.getSession().getAttribute("prevEndPos"); 
        String s = fs.readByteBlock(file, offset, byteblock);       
        req.getSession().setAttribute("prevStartPos", offset);     
        req.getSession().setAttribute("prevEndPos", (offset + byteblock) );       
        return s;
    }
    if(id.equals("prev")){
        offset = (int) req.getSession().getAttribute("prevStartPos") - byteblock ; 
        if(offset < 0 ){
            String s = fs.readByteBlock(file, 0, byteblock);
              return s;
        }
        String s = fs.readByteBlock(file, offset, byteblock);         
        req.getSession().setAttribute("prevStartPos", (offset - byteblock) );      
        return s;
    }
    String s = fs.readByteBlock(file, 0, byteblock);
    req.getSession().setAttribute("prevStartPos", offset);
    req.getSession().setAttribute("prevEndPos", (offset + byteblock));
    return s;
@RequestMapping(“/page/{id}”)
@应答器
File File=新文件(“C:/teste.txt”);
FileSaver fs=newfilesaver();
int字节块=100;
整数偏移=0;
如果(id.equals(“next”){
偏移量=(int)req.getSession().getAttribute(“prevEndPos”);
字符串s=fs.readByteBlock(文件、偏移量、byteblock);
req.getSession().setAttribute(“prevStartPos”,偏移量);
req.getSession().setAttribute(“prevEndPos”,(offset+byteblock));
返回s;
}
如果(id.equals(“prev”)){
偏移量=(int)req.getSession().getAttribute(“prevStartPos”)-byteblock;
如果(偏移量<0){
字符串s=fs.readByteBlock(文件,0,byteblock);
返回s;
}
字符串s=fs.readByteBlock(文件、偏移量、byteblock);
req.getSession().setAttribute(“prevStartPos”,(偏移量-字节块));
返回s;
}
字符串s=fs.readByteBlock(文件,0,byteblock);
req.getSession().setAttribute(“prevStartPos”,偏移量);
req.getSession().setAttribute(“prevEndPos”,(offset+byteblock));
返回s;

因此,文件的每个块都将被放入我的应用程序中的html表中,我将当前块startByte和endByte保存到会话中,但是当用户按下我页面上的“上一步”按钮时,我如何知道上一个块的开始和结束位置?既然会话将保留当前页面而不是上一个页面,而不是向会话添加两个int属性,为什么不添加两个包含适当值的int数组呢?还可以添加一个“page”属性,这样您就可以执行以下操作

if(id.equals("prev") {
    List<Integer> offsetStarts = req.getSession.getAttribute("offsetStarts);
    List<Integer> offsetEnds = req.getSession.getAttribute("offsetEnds);
    int lastPage = req.getSession.getAttribute("page");
    int desiredPage = lastPage -1;
    int offsetStart = offsetStarts.get(desiredPage);
    int offsetEnd = offsetEnd.get(desiredPage);
    // get the chunk as desired, and return it
    req.getSession().setAttribute("page", desiredPage);
}
// if it's a new chunk, append offsets to the arrays
if(id.equals(“prev”){
List offsetStarts=req.getSession.getAttribute(“offsetStarts”);
List offsetEnds=req.getSession.getAttribute(“offsetEnds”);
int lastPage=req.getSession.getAttribute(“页面”);
int desiredPage=最后一页-1;
int offsetStart=offsetStarts.get(desiredPage);
int offsetEnd=offsetEnd.get(desiredPage);
//根据需要获取块,并返回它
req.getSession().setAttribute(“页面”,desiredPage);
}
//如果它是一个新块,则将偏移量附加到数组中

首先介绍一下分页。 简单分页只有两个属性:

  • 页面大小
  • 页码
  • 后端将发回数据和以下元数据:

  • 总页数
  • 当前页码
  • 当前页面大小
  • 然后,客户端负责请求所需的数据块,通过发送页码和页面大小,后端将计算偏移量和结束。唯一需要注意的是,如果用户增加页面大小,那么总页数(客户端在上一次调用中接收到的页数)将增加不再有效,但在这种情况下,服务器只返回没有数据和新元数据。 许多框架都使用这种方法,比如后端的Spring数据和前端的ExtJS

    因为您使用的是Spring,所以只需创建一个DTO类来保存数据和元数据:

    Class PageResult {
        String data;
        int totalPageCount;
        int currentPage;
        int pageSize;       
    }
    
    在使用字符串传输数据时,请注意,可能需要在前端调用JSON.parse(),JSON将被字符串转义,这看起来很愚蠢;如果使用Jacksons ObjectMapper读取数据,我建议使用ObjectMapper.readTree()返回JsonNode,并将其放入DTO类中

    在前端,您可以使用建议的页面大小和页码输入框进行下拉。如果您想要“下一页”和“上一页”,只需发送带有当前页面+/-1和页面大小的请求,后端将计算开始、结束和总页面数