how to solve "stream closed error" in java? - java

I'm trying to merge multiple pdf files in java using pdfbox jar using this code. when it's trying to merge the second pdf in to first...it's getting Stream closed error. can anyone pls help me with this?
public static string PDFMergingForForeignModule String(folder_name) {
//Creating a File object for directory
String path = "E:\Code";
File directoryPath = new File(path);
File[] files = directoryPath.list();
String mergedFileName = "Merged_"+folder_name+".pdf";
path = path + "\\"+ mergedFileName;
mergePDFFiles(files, path);
File mergedFile = new File(mergedFileName);
}
public void mergePDFFiles(File[] files, String filepath) throws COSVisitorException{
try {
PDFMergerUtility pdfmerger = new PDFMergerUtility();
for (File file : files) {
PDDocument document = PDDocument.load(file);
pdfmerger.setDestinationFileName(filepath);
pdfmerger.addSource(file);
pdfmerger.mergeDocuments();
document.close();
}
} catch (IOException e) {
logger.error("Error to merge files. Error: " + e.getMessage());
}
}

Related

Saving a csv log file in internal storage

Description: I'm trying to log the data I have coming from firestore into a csv file, and I have the following methods to do it.
public interface ExportPojo {
String generateExportValues();
String generateExportHeaders();}
public static File generateCSV(Context context, Collection<? extends ExportPojo> values, Class<? extends ExportPojo> type) {
StringBuilder csv = new StringBuilder();
String header;
try {
header = type.newInstance().generateExportHeaders();
} catch (Exception e) {
e.printStackTrace();
return null;
}
csv.append(header).append("\n");
for (ExportPojo entry : values) {
csv.append(entry.generateExportValues());
csv.append("\n");
}
return writeStringToFile(context, csv.toString(), ".csv");
}
public static File writeStringToFile(Context context, String data, String format) {
File dir = new File(context.getFilesDir(), "/manage/");
// create this directory if not already created
dir.mkdir();
// create the file in which we will write the contents
String timestamp =
new SimpleDateFormat("E MMM yyyy H-m-s", Locale.getDefault()).format(new Date());
final File file = new File(dir, timestamp + format);
try {
FileOutputStream os = new FileOutputStream(file);
os.write(data.getBytes());
os.close();
return file;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Problem: The client would like the user to navigate the file directory, find the csv file, and open it. But after running the methods, I can't find the exported file. I've logged csv.tostring() and it looks like the data is okay. What am I doing wrong?
context.getFilesDir() give you the path for files directory that lies inside the app folder present in /data of Android which a normal user cannot access. To make the file accessible to user, you need to save it in a public directory.
You can do it like this: (the code is in kotlin but you can easily convert it in JAVA)
val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
val dir = File(path.absolutePath)
if(!dir.exists())
dir.mkdirs()
val file = File("$path/Text.txt")
if (!file.exists()) {
file.createNewFile();
}
var content = "" //todo: write your csv content here
val fw = FileWriter(file.absoluteFile)
val bw = BufferedWriter(fw)
bw.write(content)
bw.close()
file.renameTo(File("$path/${name}.csv"))
File("$path/Text.txt").delete()
You can also try writing the content directly to .csv instead of .txt but it failed for me.

problem when upload file in play framework

I tried uploading a file, and placed the file in the "public / images" directory and it worked, but the file I uploaded was zero in size and certainly couldn't be opened
public Result upload() throws IOException {
Http.MultipartFormData<File> requestBody = request().body().asMultipartFormData();
Http.MultipartFormData.FilePart<File> profile_pic = requestBody.getFile("profile_pic");
String dirPath = "public/images/";
if(profile_pic != null) {
String name = profile_pic.getFilename();
File file = profile_pic.getFile();
System.out.println(file);
File theDir = new File(dirPath);
if (!theDir.exists()) {
boolean result = false;
try {
theDir.mkdirs();
result = true;
} catch (SecurityException se) {
// handle it
}
if (result) {
System.out.println("DIR created");
}
}
try {
File filex = new File(dirPath + name.toLowerCase());
filex.createNewFile();
file.renameTo(filex);
}catch (Exception e) {
// TODO: handle exception
}
return ok("File uploaded ");
}else {
return badRequest("Eroor");
}
}
this is my file after upload
I think creating a new file and renaming your old file to that name may cause trouble. I would recommend using the move method, see docs here.
Does your System.out.println(file); print what looks like a normal png file?

Exception : Stream is closed during downloading multiple attachments

I have requirement where a user can upload a file and later if other user see that he can download a file. New requirement suggest that now a user can upload multiple attachments and any user who see it can download multiple attachment as well.
So i took a list in which attachments are added and direct it to download controller, i changed the earlier line and kept a for-loop but during download only first attachment is downloaded and later it gives exception stream is closed.Below is the code of controller.Please let me know how can i over come this?
#ApiOperation(value = "Download content")
#RequestMapping(value = "/api/content/{id}/download/", method = RequestMethod.GET)
public ResponseEntity<String> downloadContent(HttpServletResponse response, #PathVariable("id") final Long id)
throws IOException, APIException {
Content content = null;
try {
content = this.contentService.get(this.contentUtils.getContentObject(id));
} catch (ServiceException e) {
throw new APIException("Access denied");
}
if (null == content) {
throw new APIException("Invalid content id");
}
List<Document> documentList = this.contentService.getDocumentByContent(content);
if (documentList != null && !documentList.isEmpty()) {
//Document document = documentList.get(0); //If multiple files supported?, then need to be handled here
for (Document document : documentList) {
File file = new File(document.getLocalFilePath());
if (file.exists()) {
response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
try (InputStream inputStream = new FileInputStream(file); ServletOutputStream sos = response.getOutputStream();) {
IOUtils.copy(inputStream, sos);
} catch (final IOException e) {
LOGGER.error("File not found during content download" + id, e);
throw new APIException("Error during content download:" + id);
}
} else {
try {
s3FileUtil.download(document.getS3Url(), document.getLocalFilePath());
} catch (S3UtilException e) {
throw new APIException("Document not found");
}
}
}
} else {
//404
return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<String>(HttpStatus.OK);
}
practically you cannot download all the files at once. Because, once you open a stream and write the file content to the stream, you have to close the stream.
When you add the files in for loop, you have to append the file content instead of file, which is not an expected behavior.
When you want to download multiple files at once, you have to zip
the files and download.
check this link: download multiple files

Deploying GWT application on Apache Tomcat

On a server side I have a class that I use for convertion SVG file to PDF.
public class PdfHandler {
private File savedFile;
private File svgTempFile;
public PdfHandler(String fileName) {
this.savedFile = new File(File.separator + "documents" + File.separator + fileName);
}
public void convertToPdf(String inputFileName) {
this.svgTempFile = new File(inputFileName);
System.out.println(inputFileName);
if (this.svgTempFile.exists()){
System.out.println("Svg File exists");
}
else {
System.out.println("Svg File not exists");
}
try {
Transcoder transcoder = new PDFTranscoder();
System.out.println("Transcoder created");
FileInputStream fis = new FileInputStream(this.svgTempFile);
System.out.println("Input stream created");
FileOutputStream fos = new FileOutputStream(this.savedFile);
System.out.println("Output stream created");
TranscoderInput transcoderInput = new TranscoderInput(fis);
System.out.println("Transcoder input created");
TranscoderOutput transcoderOutput = new TranscoderOutput(fos);
System.out.println("Transcoder output created");
transcoder.transcode(transcoderInput, transcoderOutput);
System.out.println("Conversion finished");
fis.close();
fos.close();
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Exception");
} finally {
this.svgTempFile.delete();
System.out.println("File deleted");
}
System.out.println("End of method");
}
}
And I have a method that called by RPC.
public String generatePdf(PayDoc filledDoc) {
//String svgFileName = this.generateSvg(filledDoc);
//String pdfFileName = this.generateFileName("pdf");
PdfHandler pdfHandler = new PdfHandler("myPdf.pdf");
pdfHandler.convertToPdf(File.separator + "documents" + File.separator + "mySvg.svg");
return null;//pdfFileName;
}
In eclipse all works fine, but not on Tomcat. RPC fails when I call it on Tomcat
This is Tomcat console output:
\documents\mySvg.svg
Svg File exists
Transcoder created
Input stream created
Output stream created
Transcoder input created
Transcoder output created
File deleted
After that in "documents" folder I have "mySvg.svg"(still not deleted) and "myPdf.pdf"(it is empty).
Looks like you're not including the required library in your deployed application.
ElementTraversal is part of xml-apis-X.XX.X.jar and has to be bundled with your application.
As there are loads of build tools and I don't know which one you're using, I can't suggest changes.

How to create a file in a directory in java?

If I want to create a file in C:/a/b/test.txt, can I do something like:
File f = new File("C:/a/b/test.txt");
Also, I want to use FileOutputStream to create the file. So how would I do it? For some reason the file doesn't get created in the right directory.
The best way to do it is:
String path = "C:" + File.separator + "hello" + File.separator + "hi.txt";
// Use relative path for Unix systems
File f = new File(path);
f.getParentFile().mkdirs();
f.createNewFile();
You need to ensure that the parent directories exist before writing. You can do this by File#mkdirs().
File f = new File("C:/a/b/test.txt");
f.getParentFile().mkdirs();
// ...
With Java 7, you can use Path, Paths, and Files:
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreateFile {
public static void main(String[] args) throws IOException {
Path path = Paths.get("/tmp/foo/bar.txt");
Files.createDirectories(path.getParent());
try {
Files.createFile(path);
} catch (FileAlreadyExistsException e) {
System.err.println("already exists: " + e.getMessage());
}
}
}
Use:
File f = new File("C:\\a\\b\\test.txt");
f.mkdirs();
f.createNewFile();
Notice I changed the forward slashes to double back slashes for paths in Windows File System. This will create an empty file on the given path.
String path = "C:"+File.separator+"hello";
String fname= path+File.separator+"abc.txt";
File f = new File(path);
File f1 = new File(fname);
f.mkdirs() ;
try {
f1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This should create a new file inside a directory
A better and simpler way to do that :
File f = new File("C:/a/b/test.txt");
if(!f.exists()){
f.createNewFile();
}
Source
Surprisingly, many of the answers don't give complete working code. Here it is:
public static void createFile(String fullPath) throws IOException {
File file = new File(fullPath);
file.getParentFile().mkdirs();
file.createNewFile();
}
public static void main(String [] args) throws Exception {
String path = "C:/donkey/bray.txt";
createFile(path);
}
Create New File in Specified Path
import java.io.File;
import java.io.IOException;
public class CreateNewFile {
public static void main(String[] args) {
try {
File file = new File("d:/sampleFile.txt");
if(file.createNewFile())
System.out.println("File creation successfull");
else
System.out.println("Error while creating File, file already exists in specified path");
}
catch(IOException io) {
io.printStackTrace();
}
}
}
Program Output:
File creation successfull
To create a file and write some string there:
BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get("Path to your file"));
bufferedWriter.write("Some string"); // to write some data
// bufferedWriter.write(""); // for empty file
bufferedWriter.close();
This works for Mac and PC.
For using the FileOutputStream try this :
public class Main01{
public static void main(String[] args) throws FileNotFoundException{
FileOutputStream f = new FileOutputStream("file.txt");
PrintStream p = new PrintStream(f);
p.println("George.........");
p.println("Alain..........");
p.println("Gerard.........");
p.close();
f.close();
}
}
When you write to the file via file output stream, the file will be created automatically. but make sure all necessary directories ( folders) are created.
String absolutePath = ...
try{
File file = new File(absolutePath);
file.mkdirs() ;
//all parent folders are created
//now the file will be created when you start writing to it via FileOutputStream.
}catch (Exception e){
System.out.println("Error : "+ e.getmessage());
}

Categories