I have more attachments to download instead of downloading one by one.
I need to download them by zipping these files as batched 2 or 3 files in each zip based on conditions written in the code.
The code is written to download 2 zip files but it downloaded only one zip through response.
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class downloadSert extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=Attachments.ZIP");
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "0");
String[] cjFiles = { "C:\\Users\\MW\\Desktop\\Treasury process title and status\\1.txt", "C:\\Users\\MW\\Desktop\\Treasury process title and status\\2.txt", "C:\\Users\\MW\\Desktop\\Treasury process title and status\\3.txt", "C:\\Users\\MW\\Desktop\\Treasury process title and status\\4.txt", "C:\\Users\\MW\\Desktop\\Treasury process title and status\\5.txt" };
int len = cjFiles.length;
int attachmentTotalForEachZip = 0;
int zipBatches = 0;
if (len <= 10) {
attachmentTotalForEachZip = 2;
zipBatches = len / 2;
} else {
attachmentTotalForEachZip = 4;
zipBatches = len / 4;
}
int total = 0;
FileInputStream in = null;
ZipOutputStream zos = null;
List<ZipOutputStream> zips = new ArrayList<ZipOutputStream>();
for (int i = 0; i < cjFiles.length; i++) {
if (total == 0) {
zos = new ZipOutputStream(response.getOutputStream());
}
total = total + 1;
in = new FileInputStream(cjFiles[i]);
File f = new File(cjFiles[i]);
zos.putNextEntry(new ZipEntry((i + 1) + " - " + f.getName().substring(f.getName().indexOf("-") + 1, f.getName().length())));
int length;
byte[] buffer = new byte[1024];
while ((length = in.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
in.close();
zos.closeEntry();
//download zip
if (total == attachmentTotalForEachZip) {
zips.add(zos);
total = 0;
zipBatches = zipBatches - 1;
}
// handle zip file amount (pdf total in each zip )
if (zipBatches == 1) {
attachmentTotalForEachZip = attachmentTotalForEachZip + (len % attachmentTotalForEachZip);
zipBatches = 0;
}
}
for (ZipOutputStream z : zips) {
z.finish();
z.close();
}
}
}
if there is any way to download all zip file.
Related
I am creating a Web App in which, I have to upload files by splitting them using parallel processing and multi threading and while downloading I have to combine them back to a single file using multi threading and parallel processing.
I want to combine split files into a single. But its not working as I expected to work.
The number of threads created is equal to the number of parts the file have been split.
And the threads should run parallelly and should run only once. But the threads are called several times. Help me fix the code.
UploadServlet.java
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import org.apache.commons.io.IOUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
import jakarta.servlet.http.HttpServletRequest;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class UploadServlet extends HttpServlet
{
private static final long serialVersionUID = 100L;
public static String fileName;
public static long size;
public static int noOfParts;
public static String type;
public static byte[] b;
private static final String INSERT_USERS_SQL = "INSERT INTO uploadlist" +
" (filename, filesize, noofparts) VALUES " +
"(?, ?, ?);";
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part file = request.getPart("file");
fileName=file.getSubmittedFileName();
type=file.getContentType();
PrintWriter writer=response.getWriter();
file.write(fileName);
String n = request.getParameter("parts");
size = file.getSize();
Integer temp1 = Integer.parseInt(n);
noOfParts = temp1.intValue();
set();
writer.println("File Uploaded Successfully");
file.delete();
}
public static void set()
{
Split.split(fileName,size,noOfParts);
try {
Connection c = DataBaseConnection.getConnection();
PreparedStatement preparedStatement = c.prepareStatement(INSERT_USERS_SQL);
preparedStatement.setString(1, fileName);
preparedStatement.setLong(2, size);
preparedStatement.setInt(3, noOfParts);
System.out.println(preparedStatement);
preparedStatement.executeUpdate();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
From UploadServlet Split.split() is called to split the files into number of parts.
Split.java
import java.io.*;
import java.util.Arrays;
public class Split implements Runnable
{
int i;
long size;
int noOfParts;
String fileName;
Split()
{
fileName="";
}
Split(String fileName, int i, long size, int noOfParts)
{
this.fileName=fileName;
this.i=i;
this.size=size;
this.noOfParts=noOfParts;
}
public void run()
{
try
{
System.out.println(i);
RandomAccessFile in = new RandomAccessFile("D:\\temp\\"+fileName,"r");
int bytesPerSplit = (int)(size/noOfParts);
int remainingBytes = (int)(size % noOfParts);
byte[] b;
if(i!=noOfParts-1)
{
b = new byte[bytesPerSplit];
}
else
{
b = new byte[bytesPerSplit+remainingBytes];
}
in.seek((long)i*bytesPerSplit);
in.read(b);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\Upload\\"+fileName+i+".bin"));
for(byte temp : b)
out.write(temp);
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void split(String fileName, long size, int noOfParts)
{
for(int i=0; i<noOfParts; i++)
{
Split obj = new Split(fileName,i,size,noOfParts);
Thread t = new Thread(obj);
t.start();
}
}
}
In this program, I split the files according to number of parts. And I want to combine them back using Parallel Processing and Multi Threading.
DownloadServlet.java\
import jakarta.servlet.http.HttpServlet;
import org.postgresql.Driver;
import java.sql.Statement;
import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.util.Arrays;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String name = new String(request.getParameter("fileName"));
int noOfParts = Integer.parseInt(request.getParameter("parts"));
int size = Integer.parseInt(request.getParameter("size"));
File downloadFile = new File("D:\\Download\\"+name);
Combine.combine(name,noOfParts,size);
int length = (int)downloadFile.length();
String completeFile=name;
ServletContext context=getServletContext();
String mimeType = context.getMimeType(completeFile);
if (mimeType == null)
{
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setContentLength((int)length);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", completeFile);
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
DataInputStream in = new DataInputStream(new FileInputStream(downloadFile));
byte[] buffer = new byte[(int)length];
while ((in != null) && ((length = in.read(buffer)) != -1))
{
outStream.write(buffer,0,length);
}
if ((length = in.read(buffer))== -1) {
outStream.write(buffer, 0, length);
}
Arrays.fill(buffer, (byte)0);
in.close();
outStream.flush();
outStream.close();
}
}
From DownloadServlet, Combine.combine() is called to combine the split parts into a single file.
Combine.java
import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.*;
import java.util.Scanner;
import java.util.Arrays;
public class Combine implements Runnable
{
String name;
int size;
int noOfParts;
int i;
public static String root = "D:\\Upload\\";
Combine(String name,int noOfParts,int size, int i)
{
this.name = name;
this.noOfParts=noOfParts;
this.size=size;
this.i=i;
}
public void run()
{
try
{
System.out.println(i);
RandomAccessFile out = new RandomAccessFile("D:\\Download\\"+name,"rw");
int bytesPerSplit = size/noOfParts;
int remainingBytes = size%noOfParts;
String temp=name+i+".bin";
RandomAccessFile file = new RandomAccessFile(root+temp,"r");
long l=file.length();
byte[] b = new byte[(int)l];
file.read(b);
out.seek(i*bytesPerSplit);
out.write(b);
file.close();
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void combine(String name, int noOfParts, int size)
{
for(int i=0; i<noOfParts; i++)
{
Combine obj = new Combine(name,noOfParts,size,i);
Thread t = new Thread(obj,"Thread"+i);
t.start();
}
}
}
I have attached the image in which the numbers represent the part of the file being read and combined using threads.
The output shows that the threads keeping on executing again and again.
I don't know where is the error or any logical mistake in my program.
Help me solve this problem.
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.Calendar;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class SSEServlet
*/
#WebServlet("/SSE")
public class SSE extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
PrintWriter printwriter = response.getWriter();
File file= new File("/home/user/Documents/new.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
long length = randomAccessFile.length();
String temp;
int foundLine = 0;
while (length > 0 && foundLine < 10) {
randomAccessFile.seek(length--);
if (randomAccessFile.read() == 10) {
foundLine++;
}
}
while(true)
while((temp = randomAccessFile.readLine()) != null)
{
printwriter.println(temp);
response.flushBuffer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
In my code I am trying to get the last 10 lines and also the one that is written to file dynamically after tht 10 lines but while running my pgm am only getting the last 10 lines and not the ones written after that....in short am not able to watch the file dynamically is there any solution for this
I want to implement video Player in Angular using Spring Boot Rest API. I can play the video but I can't make video seeking. Every time the video starts over and over again when I use Chrome or Edge.
I tried this endpoint:
#RequestMapping(value = "/play_video/{video_id}", method = RequestMethod.GET)
#ResponseBody public ResponseEntity<byte[]> getPreview1(#PathVariable("video_id") String video_id, HttpServletResponse response) {
ResponseEntity<byte[]> result = null;
try {
String file = "/opt/videos/" + video_id + ".mp4";
Path path = Paths.get(file);
byte[] image = Files.readAllBytes(path);
response.setStatus(HttpStatus.OK.value());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(image.length);
result = new ResponseEntity<byte[]>(image, headers, HttpStatus.OK);
} catch (java.nio.file.NoSuchFileException e) {
response.setStatus(HttpStatus.NOT_FOUND.value());
} catch (Exception e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
return result;
}
I found this post which gives some ides: How to Implement HTTP byte-range requests in Spring MVC
But currently it's not working. Video is again playing from the start when I try to shift the position.
I use this player: https://github.com/smnbbrv/ngx-plyr
I have configured it this way:
<div class="media">
<div
class="class-video mr-3 mb-1"
plyr
[plyrPlaysInline]="true"
[plyrSources]="gymClass.video"
(plyrInit)="player = $event"
(plyrPlay)="played($event)">
</div>
<div class="media-body">
{{ gymClass.description }}
</div>
</div>
Do you know how I can fix this issue?
First solution: Using FileSystemResource
FileSystemResource internally handles byte-range header support, reading and writing the appropriate headers.
Two problems with this approach.
It uses FileInputStream internally for reading files. This is fine for small files, but not for large files served through byte-range requests. FileInputStream will read the file from the beginning and discard the not needed content until it reches the requested start offset. This can cause slowdowns with larger files.
It sets "application/json" as the "Content-Type" response header. So, I provide my own "Content-Type" header. See this thread
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class Stream3 {
#GetMapping(value = "/play_video/{video_id}")
#ResponseBody
public ResponseEntity<FileSystemResource> stream(#PathVariable("video_id") String video_id) {
String filePathString = "/opt/videos/" + video_id + ".mp4";
final HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "video/mp4");
return new ResponseEntity<>(new FileSystemResource(filePathString), responseHeaders, HttpStatus.OK);
}
}
Second solution: Using HttpServletResponse and RandomAccessFile
With RandomAccessFile you can implement support for byte-range requests. The advantage over FileInputStream, is that you don't need to read the file from the beginning every time there is a new range request, making this method usable also for larger files. RandomAccessFile has a method called seek(long) which calls the C method fseek(), which directly moves the pointer for the file to the requested offset.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class Stream {
#GetMapping(value = "/play_video/{video_id}")
#ResponseBody
public void stream(
#PathVariable("video_id") String video_id,
#RequestHeader(value = "Range", required = false) String rangeHeader,
HttpServletResponse response) {
try {
OutputStream os = response.getOutputStream();
long rangeStart = 0;
long rangeEnd;
String filePathString = "/opt/videos/" + video_id + ".mp4";
Path filePath = Paths.get(filePathString);
Long fileSize = Files.size(filePath);
byte[] buffer = new byte[1024];
RandomAccessFile file = new RandomAccessFile(filePathString, "r");
try (file) {
if (rangeHeader == null) {
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Content-Length", fileSize.toString());
response.setStatus(HttpStatus.OK.value());
long pos = rangeStart;
file.seek(pos);
while (pos < fileSize - 1) {
file.read(buffer);
os.write(buffer);
pos += buffer.length;
}
os.flush();
return;
}
String[] ranges = rangeHeader.split("-");
rangeStart = Long.parseLong(ranges[0].substring(6));
if (ranges.length > 1) {
rangeEnd = Long.parseLong(ranges[1]);
} else {
rangeEnd = fileSize - 1;
}
if (fileSize < rangeEnd) {
rangeEnd = fileSize - 1;
}
String contentLength = String.valueOf((rangeEnd - rangeStart) + 1);
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Content-Length", contentLength);
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Range", "bytes" + " " + rangeStart + "-" + rangeEnd + "/" + fileSize);
response.setStatus(HttpStatus.PARTIAL_CONTENT.value());
long pos = rangeStart;
file.seek(pos);
while (pos < rangeEnd) {
file.read(buffer);
os.write(buffer);
pos += buffer.length;
}
os.flush();
}
} catch (FileNotFoundException e) {
response.setStatus(HttpStatus.NOT_FOUND.value());
} catch (IOException e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
}
}
Third solution: Also using RandomAccessFile, but StreamingResponseBody instead of HttpServletResponse
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
#Controller
public class Stream2 {
#GetMapping(value = "/play_video/{video_id}")
#ResponseBody
public ResponseEntity<StreamingResponseBody> stream(
#PathVariable("video_id") String video_id,
#RequestHeader(value = "Range", required = false) String rangeHeader) {
try {
StreamingResponseBody responseStream;
String filePathString = "/opt/videos/" + video_id + ".mp4";
Path filePath = Paths.get(filePathString);
Long fileSize = Files.size(filePath);
byte[] buffer = new byte[1024];
final HttpHeaders responseHeaders = new HttpHeaders();
if (rangeHeader == null) {
responseHeaders.add("Content-Type", "video/mp4");
responseHeaders.add("Content-Length", fileSize.toString());
responseStream = os -> {
RandomAccessFile file = new RandomAccessFile(filePathString, "r");
try (file) {
long pos = 0;
file.seek(pos);
while (pos < fileSize - 1) {
file.read(buffer);
os.write(buffer);
pos += buffer.length;
}
os.flush();
} catch (Exception e) {}
};
return new ResponseEntity<>(responseStream, responseHeaders, HttpStatus.OK);
}
String[] ranges = rangeHeader.split("-");
Long rangeStart = Long.parseLong(ranges[0].substring(6));
Long rangeEnd;
if (ranges.length > 1) {
rangeEnd = Long.parseLong(ranges[1]);
} else {
rangeEnd = fileSize - 1;
}
if (fileSize < rangeEnd) {
rangeEnd = fileSize - 1;
}
String contentLength = String.valueOf((rangeEnd - rangeStart) + 1);
responseHeaders.add("Content-Type", "video/mp4");
responseHeaders.add("Content-Length", contentLength);
responseHeaders.add("Accept-Ranges", "bytes");
responseHeaders.add("Content-Range", "bytes" + " " + rangeStart + "-" + rangeEnd + "/" + fileSize);
final Long _rangeEnd = rangeEnd;
responseStream = os -> {
RandomAccessFile file = new RandomAccessFile(filePathString, "r");
try (file) {
long pos = rangeStart;
file.seek(pos);
while (pos < _rangeEnd) {
file.read(buffer);
os.write(buffer);
pos += buffer.length;
}
os.flush();
} catch (Exception e) {}
};
return new ResponseEntity<>(responseStream, responseHeaders, HttpStatus.PARTIAL_CONTENT);
} catch (FileNotFoundException e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
} catch (IOException e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
In your component.ts:
You can change the currently displaying video with playVideoFile()
export class AppComponent implements OnInit {
videoSources: Plyr.Source[];
ngOnInit(): void {
const fileName = 'sample';
this.playVideoFile(fileName);
}
playVideoFile(fileName: string) {
this.videoSources = [
{
src: `http://localhost:8080/play_video/${fileName}`,
},
];
}
}
And the html:
<div
#plyr
plyr
[plyrPlaysInline]="false"
[plyrSources]="videoSources"
></div>
If you are using the <video /> element in Chrome, seeking only works if the endpoint implements partial content requests by honouring requests with a Range header and respond with a 206 Partial Content response.
My program uses Tasks from JavaFX to download and unzip files and to show the progress on the screen, by using the updateProgress(workDone, max) method and the progressProperty().bind(observable) method.
It works for Download :
package com.franckyi.lan.installer;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import javafx.concurrent.Task;
public class DownloadTask extends Task<Void> {
private String file;
private String url;
public DownloadTask(String dir, String fileurl) {
file = dir;
url = fileurl;
}
#Override
protected Void call() throws Exception {
URLConnection connection = new URL(url).openConnection();
long fileLength = connection.getContentLengthLong();
try (InputStream is = connection.getInputStream();
OutputStream os = Files.newOutputStream(Paths.get(file))) {
long nread = 0L;
byte[] buf = new byte[1024];
int n;
while ((n = is.read(buf)) > 0) {
os.write(buf, 0, n);
nread += n;
updateProgress(nread, fileLength);
}
}
return null;
}
#Override
protected void succeeded(){
System.out.println("Download succeeded");
}
}
But it doesn't work well for Unzip : The file is correctly unzipped but I get a wrong ProgressBar (empty at the end).
package com.franckyi.lan.installer;
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.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javafx.concurrent.Task;
public class UnZipTask extends Task<Void>{
private File zipfile;
private File folder;
public UnZipTask(File zipfile, File folder){
this.zipfile = zipfile;
this.folder = folder;
}
#Override
protected Void call() throws Exception {
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(new FileInputStream(zipfile.getCanonicalFile())));
ZipEntry ze = null;
try {
while ((ze = zis.getNextEntry()) != null) {
File f = new File(folder.getCanonicalPath(), ze.getName());
if (ze.isDirectory()) {
f.mkdirs();
continue;
}
f.getParentFile().mkdirs();
OutputStream fos = new BufferedOutputStream(new FileOutputStream(f));
try {
try {
final byte[] buf = new byte[1024];
int bytesRead;
long nread = 0L;
long length = zipfile.length();
while (-1 != (bytesRead = zis.read(buf))){
fos.write(buf, 0, bytesRead);
nread += bytesRead;
System.out.println(nread + "/" + length);
updateProgress(nread, length);
}
} finally {
fos.close();
}
} catch (final IOException ioe) {
f.delete();
throw ioe;
}
}
} finally {
zis.close();
}
return null;
}
#Override
protected void succeeded(){
System.out.println("Unzip succeeded");
}
}
This is what I get in the console :
Download succeeded
1024/91804
2048/91804
2815/91804
362/91804
326/91804
290/91804
386/91804
257/91804
250/91804
588/91804
1101/91804
1613/91804
2128/91804
2646/91804
3159/91804
3672/91804
4185/91804
4701/91804
5214/91804
5731/91804
6243/91804
6755/91804
7272/91804
7793/91804
8326/91804
8862/91804
9379/91804
9897/91804
10411/91804
10927/91804
11442/91804
11956/91804
12437/91804
447/91804
437/91804
978/91804
1525/91804
2040/91804
454/91804
1056/91804
1568/91804
2089/91804
2672/91804
3198/91804
3728/91804
4282/91804
4826/91804
5377/91804
5891/91804
6413/91804
6941/91804
7480/91804
8027/91804
8565/91804
9088/91804
9609/91804
9794/91804
507/91804
1019/91804
1531/91804
2043/91804
2239/91804
134/91804
548/91804
1292/91804
2316/91804
2584/91804
507/91804
837/91804
135/91804
486/91804
1001/91804
1514/91804
2027/91804
2545/91804
3057/91804
3571/91804
4086/91804
4599/91804
5113/91804
5627/91804
6144/91804
6655/91804
7166/91804
7679/91804
8196/91804
8710/91804
9229/91804
9745/91804
10259/91804
10773/91804
11288/91804
11802/91804
12321/91804
12834/91804
13348/91804
13864/91804
14378/91804
14893/91804
15407/91804
15918/91804
16431/91804
16944/91804
17458/91804
17971/91804
18484/91804
18997/91804
19508/91804
20021/91804
20535/91804
21047/91804
21560/91804
22072/91804
22584/91804
23096/91804
23609/91804
24122/91804
24638/91804
25149/91804
25664/91804
26176/91804
26689/91804
27203/91804
27715/91804
28227/91804
28739/91804
29251/91804
29764/91804
30277/91804
30789/91804
31301/91804
31813/91804
32325/91804
32838/91804
33306/91804
33819/91804
34333/91804
34846/91804
35357/91804
35869/91804
36381/91804
36894/91804
37407/91804
37922/91804
38435/91804
38948/91804
39460/91804
39972/91804
40488/91804
41002/91804
41514/91804
42028/91804
42540/91804
43052/91804
43566/91804
44079/91804
44594/91804
45105/91804
45619/91804
46132/91804
46644/91804
47156/91804
47668/91804
48180/91804
48692/91804
49204/91804
49716/91804
50228/91804
50741/91804
51252/91804
51765/91804
52277/91804
52790/91804
53305/91804
53821/91804
54335/91804
54852/91804
55365/91804
55881/91804
56396/91804
56442/91804
545/91804
1287/91804
2311/91804
2584/91804
507/91804
845/91804
4/91804
Unzip succeeded
Can someone help me ?
It is because you use length of compressed zipFile as the maximum, and the count of bytes raeded from each uncompressed zipEntry as the postion - the size of compressed file is in most cases different from the uncompressed one, also you can have multiple files in the zip package - so the progres will jump from 0 to some value (the size of actual zipEntry not the compressed zipFile length) for each one in this case. To have the actual position in a zip file, get the reference to FileChannel from the FileInputStream, using this method: FileInputStream#getChannel();
then when it comes to update the progres do:
updateProgress(channel.position(), length);
This will update the progress bar according to the actual position that was readed in the zipFile (not the size of uncompressed content).
It could be something like:
package com.franckyi.lan.installer;
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.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javafx.concurrent.Task;
public class UnZipTask extends Task<Void>{
private File zipfile;
private File folder;
public UnZipTask(File zipfile, File folder){
this.zipfile = zipfile;
this.folder = folder;
}
#Override
protected Void call() throws Exception {
FileInputStream is = new FileInputStream(zipfile.getCanonicalFile());
FileChannel channel = is.getChannel();
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze = null;
try {
while ((ze = zis.getNextEntry()) != null) {
File f = new File(folder.getCanonicalPath(), ze.getName());
if (ze.isDirectory()) {
f.mkdirs();
continue;
}
f.getParentFile().mkdirs();
OutputStream fos = new BufferedOutputStream(new FileOutputStream(f));
try {
try {
final byte[] buf = new byte[1024];
int bytesRead;
long nread = 0L;
long length = zipfile.length();
while (-1 != (bytesRead = zis.read(buf))){
fos.write(buf, 0, bytesRead);
nread += bytesRead;
System.out.println(nread + "/" + length);
updateProgress(channel.position(), length);
}
} finally {
fos.close();
}
} catch (final IOException ioe) {
f.delete();
throw ioe;
}
}
} finally {
zis.close();
}
return null;
}
#Override
protected void succeeded(){
System.out.println("Unzip succeeded");
}
}
I have a dynamic web project in eclipse. When I'm executing just WordFreq.java it works. If I want to execute same code in MyServlet.java > doGet method, I get this error: HTTP Status 500 - text.txt (The system cannot find the file specified).
I copied my file (text.txt) everywhere :
The project root folder
The WebContent folder
The src folder
Any subdirectory in my project.
and still get this error.
Note: my workspace is in D:/.... and my Apache server is on C:/...
I tried to change to full path but still doesn't work.
WordFreq.java
package cpd;
import java.io.*;
import java.util.Scanner;
public class WordFreq {
public static void main(String[] args) throws IOException {
File file1 = new File("text.txt");
BufferedReader in = new BufferedReader(new FileReader(file1));
String content = new Scanner(file1).useDelimiter("\\Z").next();
CezarBun cezar = new CezarBun();
System.out.println(cezar.criptare(content, 3));
System.out.println("Frecventa literelor");
System.out.println();
int nextChar;
char ch;
double[] count = new double[26];
while ((nextChar = in.read()) != -1) {
ch = ((char) nextChar);
if (ch >= 'a' && ch <= 'z') {
count[ch - 'a']++;
}
}
for (int i = 0; i < 26; i++) {
System.out.printf("%c %d", i + 'a', (int) count[i]);
System.out.println("Frecventa: " + count[i] / file1.length() * 100 + "%");
}
in.close();
try {
/*create a buffered reader that connects to the console, we use it so we can
read lines*/
BufferedReader in2 = new BufferedReader(new InputStreamReader(System.in));
//read a line from the console
String lineFromInput = in2.readLine();
//create an print writer for writing to a file
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
//output to the file a line
out.println(lineFromInput);
//close the stream
out.close();
} catch (IOException e1) {
System.out.println("Error during reading/writing");
}
}
}
MyServlet.java
package cpd;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Scanner;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
#WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("A pornit servlet-ul" + "<br />");
//inceput wordfreq
File file1 = new File("text.txt");
BufferedReader in = new BufferedReader(new FileReader(file1));
String content = new Scanner(file1).useDelimiter("\\Z").next();
CezarBun cezar = new CezarBun();
System.out.println(cezar.criptare(content, 3));
System.out.println("Frecventa literelor");
System.out.println();
int nextChar;
char ch;
double[] count = new double[26];
while ((nextChar = in.read()) != -1) {
ch = ((char) nextChar);
if (ch >= 'a' && ch <= 'z') {
count[ch - 'a']++;
}
}
for (int i = 0; i < 26; i++) {
System.out.printf("%c %d", i + 'a', (int) count[i]);
System.out.println(" Frecventa: " + count[i] / file1.length() * 100 + "%");
}
in.close();
try {
//create a buffered reader that connects to the console, we use it so we can read lines
BufferedReader in2 = new BufferedReader(new InputStreamReader(System.in));
//read a line from the console
String lineFromInput = in2.readLine();
//create an print writer for writing to a file
PrintStream out2 = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out2);
//output to the file a line
out2.println(lineFromInput);
//close the file (VERY IMPORTANT!)
out2.close();
} catch (IOException e1) {
System.out.println("Error during reading/writing");
}
//sfarsit wordfreq
// freq = new WordFreqBun();
//freq.wf();
out.print("<br />");
out.print("<a href='http://localhost:8080/CpdApplication/'>Inapoi la meniu</a>");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
You can access your file as a resource using the ServletContext.getResourceAsStream(), the file can be located anywhere in your web application. It is recommended to keep it under the /WEB-INF directory if you don't want browers being able to access it.
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream("/file.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(is));
ServletContext.getResource() : Returns a URL to the resource that is mapped to the given path.
ServletContext.getResourceAsStream() :
Returns the resource located at the named path as an InputStream object.