Large file upload using FileInputStream and FileOutputStream - java

HttpExchange exchange;
OutputStream responseBody = null;
try{
File fileVal = new File(file);
InputStream inVal = new FileInputStream(fileVal);
exchange.sendResponseHeaders(HTTP_OK, fileVal.length());
responseBody = exchange.getResponseBody();
int read;
byte[] buffer = new byte[4096];
while ((readVal = inVal.read(buffer)) != -1){
responseBody.write(buffer, 0, readVal);
}
} catch (FileNotFoundException e){
//uh-oh, the file doesn't exist
} catch (IOException e){
//uh-oh, there was a problem reading the file or sending the response
} finally {
if (responseBody != null){
responseBody.close();
}
}
I am tring to upload large video file as chunks .while doing the operation I am getting the following error.
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.File(org.springframework.web.multipart.commons.CommonsMultipartFile)
any anyone guide me to solve this.

File fileVal = new File(file);
Here file is org.springframework.web.multipart.commons.CommonsMultipartFile type and you are trying to create File object by passing CommonsMultipartFile object in constructor and File class does not have constructor of CommonsMultipartFile type.
Check here for File Class Constructor
You Need to get Bytes from file object and create a java.io.File object.
Convert MultiPartFile into File

The error message descripes the failure perfectly. There is no constructor for the class File that accept a parameter of the type org.springframework.web.multipart.commons.CommonsMultipartFile.
Try using the path to the file you want to open. For example:
String path = "/path/to/your/file.txt";
File fileVal = new File(path);
Alternatively you can use the getInputStream() method from CommonsMultipartFile.
InputStream inVal = file.getInputStream();

Related

set multiple content types in java servlet

I have .pdf,.jpg,.docx files and I want to open them when button clicked. Is there any method to set multiple content types in servlet. My servlet codes like this.
String Docpath=request.getParameter("document");
String docname=request.getParameter("docName");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition","inline;filename="+docname);
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try{
ServletOutputStream outs=response.getOutputStream();
File file=new File("T:\\Temp\\"+docname);
File original=new File(Docpath);
File destination=new File("T:\\Temp\\");
FileUtils.copyFileToDirectory(original,destination);
InputStream input=new FileInputStream(file);
bis=new BufferedInputStream(input);
bos=new BufferedOutputStream(outs);
byte[]buf=new byte[2048];
int bytesRead;
while((bytesRead=bis.read(buf))>0) {
bos.write(buf,0,bytesRead);
}
} catch(IOException e) {
e.printStackTrace();
} finally {
bis.close();
bos.close();
}
There is the working codes
File file=new File("T:\\Temp\\"+docname);
Path filePath=Paths.get("T:\\Temp\\"+docname);
response.setContentType(Files.probeContentType(filePath));
You can not set multiple content types. What you need to do is to determine the content type of the file you load from disk:
File file=new File("T:\\Temp\\"+docname);
After you find out what the content type is you set it:
response.setContentType(contentTypeOfTheFileIJustLoaded);
There are a few options how you can find out the content type of a file. Have a look at the following Stackoverflow question:
Getting A File's Mime Type In Java

Return Zip File from ZipOutputStream in Java

I have a function which creates a Zip file from a list of files. Is it possible to return the Zip file without it being saved on the disk? I need the file as I have to use the zip file as a parameter for another function. I am not sure of the ByteStream would be an option for me.
public File compressFileList(List<File> fileList,String fileName) {
FileOutputStream fileOutputStream=null;
ZipOutputStream zipOutputStream=null;
FileInputStream fileInputStream=null;
String compressedFileName=fileName +".zip";
if(fileList.isEmpty())
return null;
try
{
fileOutputStream = new FileOutputStream(compressedFileName);
zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
for (File file: fileList) {
fileInputStream = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
fileInputStream.close();
}
zipOutputStream.close();
return compressedFile; //This is what I am missing
}
catch (FileNotFoundException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
EDIT : adding the use case
The idea is to create a zip file and use the CreateClassifierOptions method of VisualRecognition Service of Watson.
classifierOptions = new CreateClassifierOptions.Builder()
.classifierName("Santa")
.addClass("Santa", new File("C:\\app\\GitRepo\\images\\beagle.zip"))
.negativeExamples(new File("C:\\app\\GitRepo\\images\\nosport.zip"))
.build();
The builder accepts the zip file as the parameter.
Understanding
Based on the explanation from Alexandre Dupriez, I think it is better to store the file at some place on the hard disk.
You should be able to use a ByteArrayOutputStream instead of a FileOutputStream:
zipOutputStream = new ZipOutputStream(new ByteArrayOutputStream());
The difficulty here is to provide a File to the method consuming the zip file. The java.io.File does not provide an abstraction which allows you to manipulate in-memory files.
The java.io.File abstraction and java.io.FileInputStream implementation
To simplify, if we had to boil down what the File abstraction is, we would see it as a URI. And therefore, to be able to build an in-memory File, or at least mimic it, we would need to provide an URI which would then be used by the consumer of the File to read its content.
If we look at the FileInputStream which the consumer is likely to use, we can see that it always ends up with a native call which gives us to possibility whatsoever to abstract a FileSystem for in-memory files:
// class java.io.FileInputStream
/**
* Opens the specified file for reading.
* #param name the name of the file
*/
private native void open0(String name) throws FileNotFoundException;
It would be easier if there was a possibility to adapt the consumer to accept an InputStream, but from your problem statement I guess this is not possible.
API call
Your requirement is to provide a File to the Watson Visual API.
Could you please provide the API method you need to call?
public void compressFileList(List<File> fileList, OutputStream outputStream)
throws IOException {
try (ZipOutputStream zipOutputStream =
new ZipOutputStream(new BufferedOutputStream(outputStream));
for (File file: fileList) {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
} catch (FileNotFoundException e) { // Maybe skip not found files.
Logger.log(Level.INFO, "File not found {}", file.getPath());
}
}
}
}
Usage:
if (fileList.isEmpty()) {
...
return;
}
try {
compressFileList(fileList, servletRequest.getOutputStream())) {
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}

FileNotFoundException when attempting to read json asset

I'm working on an app that needs to send an automatic email on button click. the problem I am currently have is that I need to read a json file and when I pass the path of the json stored in assets into into a new FileReader() I get a file not found Exception. here is how I am getting the path. (wondering if Uri.parse().toString is redundant):
private static final String CLIENT_SECRET_PATH =
Uri.parse("file:///android_asset/raw/sample/***.json").toString()
and here is the method I am passing it into:
sClientSecrets = GoogleClientSecrets
.load(jsonFactory, new FileReader(CLIENT_SECRET_PATH));
the json file that I am attemping to access is in my apps asset folder under the app root in android project directory (/app/assets/)
I am not sure what I am doing wrong here but I'm sure it is something simple. please help point me in the right direction.
You should not access the assets using direct file path.
The files are packed and the location will change on each device.
You need to use a helper function to get the assets path
getAssets().open()
See this post for more information.
Keep your file directly inside assets directory rather then raw-sample.
And then file path will be like this
private static final String CLIENT_SECRET_PATH =
Uri.parse("file:///android_asset/***.json").toString()
hope your problem will be solved..
You can use this function to get JSON string from assets and pass that string to the FileReader.
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getActivity().getAssets().open("yourfilename.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
#Rohit i was able to use the method you provided as a starting point. the only issue with it was that the gmail api that i am using requires a Reader as its parameter, not a string. here is what i did. and i am no longer getting filenotfoundexception. thank you very much.
public InputStreamReader getJsonStreamReader(String file){
InputStreamReader reader = null;
try {
InputStream in = getAssets().open(file);
reader = new InputStreamReader(in);
}catch(IOException ioe){
Log.e("launch", "error : " + ioe);
}
return reader;
}

java how to check if file exists and open it?

how to check if file exists and open it?
if(file is found)
{
FileInputStream file = new FileInputStream("file");
}
File.isFile will tell you that a file exists and is not a directory.
Note, that the file could be deleted between your check and your attempt to open it, and that method does not check that the current user has read permissions.
File f = new File("file");
if (f.isFile() && f.canRead()) {
try {
// Open the stream.
FileInputStream in = new FileInputStream(f);
// To read chars from it, use new InputStreamReader
// and specify the encoding.
try {
// Do something with in.
} finally {
in.close();
}
} catch (IOException ex) {
// Appropriate error handling here.
}
}
You need to create a File object first, then use its exists() method to check. That file object can then be passed into the FileInputStream constructor.
File file = new File("file");
if (file.exists()) {
FileInputStream fileInputStream = new FileInputStream(file);
}
You can find the exists method in the documentation:
File file = new File(yourPath);
if(file.exists())
FileInputStream file = new FileInputStream(file);

Create a file object from a resource path to an image in a jar file

I need to create a File object out of a file path to an image that is contained in a jar file after creating a jar file. If tried using:
URL url = getClass().getResource("/resources/images/image.jpg");
File imageFile = new File(url.toURI());
but it doesn't work. Does anyone know of another way to do it?
To create a file on Android from a resource or raw file I do this:
try{
InputStream inputStream = getResources().openRawResource(R.raw.some_file);
File tempFile = File.createTempFile("pre", "suf");
copyFile(inputStream, new FileOutputStream(tempFile));
// Now some_file is tempFile .. do what you like
} catch (IOException e) {
throw new RuntimeException("Can't create temp file ", e);
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
Don't forget to close your streams etc
This should work.
String imgName = "/resources/images/image.jpg";
InputStream in = getClass().getResourceAsStream(imgName);
ImageIcon img = new ImageIcon(ImageIO.read(in));
Usually, you can't directly get a java.io.File object, since there is no physical file for an entry within a compressed archive. Either you live with a stream (which is best most in the cases, since every good API can work with streams) or you can create a temporary file:
URL imageResource = getClass().getResource("image.gif");
File imageFile = File.createTempFile(
FilenameUtils.getBaseName(imageResource.getFile()),
FilenameUtils.getExtension(imageResource.getFile()));
IOUtils.copy(imageResource.openStream(),
FileUtils.openOutputStream(imageFile));
You cannot create a File object to a reference inside an archive. If you absolutely need a File object, you will need to extract the file to a temporary location first. On the other hand, most good API's will also take an input stream instead, which you can get for a file in an archive.

Categories