Problems working with files runtime in executable jar - java

I have a working code (at least in eclipse), in which I work with some files: I have a .dot file I write into some text, so I can read it to create a graph. Then I save the graph into a .png image, which I display on a frame..
My problem is: In the executable .jar file I can´t acces these files, and also - if i know it right - I can´t even change em runtime. So I tried to work with Streams. I can access the .dot file like:
$InputStream fileStream = this.getClass().getResourceAsStream("/graf.dot");$
But I have no clue how can i write into it. I found OutputStreamWriter, but it also requires a path, which I can´t acces like I accessed the InputStream..I also struggle with reading the text from the file and creating the .png file... Can you please help me? Is it even possible to work with these files at runtime?
I had the same problem accessing the background image of the frame, but I found a solution:
$URL bgPath = this.getClass().getResource("/background.jpg");
panel = new JLabel(new ImageIcon(bgPath));$
So I really hope there exists some similar solution for the files I work with..
private void createGraph() throws IOException {
/* Creating the graph into "graf.dot" file.
* The format is in DOT language.
*/
String fileName = "src/main/resources/graf.dot";
InputStream fileStream = this.getClass().getResourceAsStream("/graf.dot");
BufferedReader br = new BufferedReader(new InputStreamReader(fileStream));
/* Here I write the content into *graph_string**/
br.close();
try {
FileOutputStream outputStream = new FileOutputStream(fileName);
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
//FileWriter writer = new FileWriter(fileName);
writer.write(graph_string);
writer.close();
}catch (IOException e) {
System.out.println("Error writing into file");
}finally {
drawGraph();
}
}
private void drawGraph() throws IOException {
/*
* Reading the graph from file for visualization
*/
String fileName = "src/main/resources/graf.dot";
InputStream fileStream = this.getClass().getResourceAsStream("/graf.dot");
BufferedReader br = new BufferedReader(new InputStreamReader(fileStream));
File file = new File("src/main/resources/graf.dot");
String str="";
try {
str = FileUtils.readFileToString(file, "UTF-8");
} catch (IOException e) {
System.out.println("Errorrr reading from file.");
}
MutableGraph g = Parser.read(str);
Graphviz.fromGraph(g).render(
Format.PNG).toFile(new File("src/main/resources/graph.png"));
BufferedImage background = ImageIO.read(new File("src/main/resources/graph.png"));
panel = new JLabel(new ImageIcon(background));
...
}

Related

IntelliJ: how to copy resources, such as text files and images to the build path?

This is my first time writing a small application in javafx, using IntelliJ. The problem I'm having is that, although I've my text file and images in the same namespace as the Controller.java file, when I run the application, I still get the error that files cannot be found.
try (BufferedReader reader = new BufferedReader(new FileReader("bookList.txt")))
{
//code here...
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this is for the image
Image image = new
Image(getClass().getResourceAsStream("images/book1.jpg"));
ImageView imageView = new ImageView(image);
Here's the structure of the files
After reading some questions/answers, it seems like the issue is related to those resources not being copied to the output path.
In visual studio, all you have to do is right-click the file then chose "Copy to Output Directory: Always | If Newer"
How do I copy text files and/or images to the output path in java/IntelliJ?
Thanks for helping
If you use the path: right-click on the source file> copy> Path from content Root:
The result is:
BufferedReader reader = new BufferedReader(new
FileReader("src\\sample\\bookList.txt"))
If you use URL, the URL starts from src, in this case:
Image image = new
Image(getClass().getResourceAsStream("/sample/images/book1.jpg"));
Ideally, you should use the URL for BufferedReader:
String fileName = "/sample/bookList.txt";
InputStream is = getClass().getResourceAsStream(fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));

JAVA Apache POI wrong document write output

I'm reading a file, adding some data to paragraphs, and then writing out a document another file.
The problem I'm facing is that the output file is unreadable, I can't open it, and if a binary open it I can see that it don't have the correct format.
Every character has a ? character at the left side.
Can you give me some advice about what is happening?
Wrong output
Correct output
EDIT: Code Save function
FileOutputStream out = null;
try {
// Add true to make the data append possible in output stream.
out = new FileOutputStream(filePath, true);
doc.write(out);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
out.close();
}
Edit file:
File file = new File("muestra.doc");
FileInputStream fis = new FileInputStream(file.getAbsolutePath());
POIFSFileSystem fs = new POIFSFileSystem(fis);
HWPFDocument document = new HWPFDocument(fs);
Range range = document.getRange();
for (int i = 0; i < document.getParagraphTable().getParagraphs().size(); i++) {
Paragraph p = range.getParagraph(i);
p.insertBefore("£");
}

Getting InputStream of a .docx file using docx4j

I have an application which saves .docx files to a FTP server. To store the file on the FTP server the FTP client needs the InputStream of the file, but here comes the problems. I use docx4j to save the text I want to a temp file on the file system, after that I get the InputStream of that file and stores it on the FTP server. But when I try to open it says that it is corrupted. Here is my sample code:
public void setText(String text) throws BusinessException {
//My utility class, used for ftp processes(such as storing, deleting files
FtpProcesses ftp = new FtpProcesses(Consts.ADMIN_FTP_USERNAME, UserType.ADMIN);
String filePath = ftp.getFileFolderRelativePath(FileType.ARTICLE, String.valueOf(this.getVersionsCount()), String.valueOf(this.getId()));
File outputFile;
InputStream stream;
Text fileText;
R run;
P paragraph;
ObjectFactory factory = Context.getWmlObjectFactory();
try {
outputFile = File.createTempFile("tempFile", ".docx");
paragraph = factory.createP();
run = factory.createR();
fileText = factory.createText();
fileText.setValue(text);
run.getContent().add(fileText);
paragraph.getContent().add(run);
WordprocessingMLPackage word = WordprocessingMLPackage.createPackage();
word.getMainDocumentPart().addObject(paragraph);
word.save(outputFile);
stream = new FileInputStream(outputFile);
ftp.uploadFile(filePath, stream);
} catch (IOException | Docx4JException e) {
e.printStackTrace();
throw new BusinessException(Errors.FILE_UPLOAD_ERROR);
}
}
So as you can see I getting the InputStream directly after saving the file. Is there some other way for getting it with docx4j so that it can be saved properly on the ftp?

Creating a file dynamically through jsp

I have a block of jsp code like this. Here blockerdata, criticaldata, majordata and minordata are stringbuilder strings and their value is appended through a loop and value is assigned dynamically. Now I'm tryong to write them into an xml file like this.
<%
System.out.println(blockerdata);
System.out.println(criticaldata);
System.out.println(majordata);
System.out.println(minordata);
try
{
File file1 = new File("WebContent/criticaldata.xml");
File file2 = new File("WebContent/majordata.xml");
File file3 = new File("WebContent/minordata.xml");
File file4 = new File("WebContent/blockerdata.xml");
FileOutputStream fop1 = new FileOutputStream(file1);
FileOutputStream fop2 = new FileOutputStream(file2);
FileOutputStream fop3 = new FileOutputStream(file3);
FileOutputStream fop4 = new FileOutputStream(file4);
// if file doesnt exists, then create it
if (!file1.exists()) {
file1.createNewFile();
}
if (!file2.exists()) {
file2.createNewFile();
}
if (!file3.exists()) {
file3.createNewFile();
}
if (!file4.exists()) {
file4.createNewFile();
}
// get the content in bytes
byte[] contentInBytes1= criticaldata.toString().getBytes();
byte[] contentInBytes2= majordata.toString().getBytes();
byte[] contentInBytes3= minordata.toString().getBytes();
byte[] contentInBytes4= blockerdata.toString().getBytes();
fop1.write(contentInBytes1);
fop2.write(contentInBytes1);
fop3.write(contentInBytes1);
fop4.write(contentInBytes1);
fop1.flush();
fop2.flush();
fop3.flush();
fop4.flush();
fop1.close();
fop2.close();
fop3.close();
fop4.close();
}
catch ( IOException e)
{
}
%>
Problem is, the code doesn't seem to be working. I tried to do it using printwriter also but
the files are not being generated. Also I want to rewrite the file if it already exists. Can somebody please help me on how to do this ?

Java FileWriter overwrite

I have a piece of code that generates new data whenever there is new data available as InputStream . The same file is overwritten everytime. Sometimes the file becomes 0 kb before it gets written. A webservice reads these files at regular intervals. I need to avoid the case when the file is 0 bytes.
How do it do this? Will locks help in this case? If the browser comes in to read a file which is locked, will the browser continue to show old data from the cache until the lock is released and file is available to be read again.
try{
String outputFile = "output.html";
FileWriter fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
outputFile = "anotheroutput.html";
fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
fWriter.close();
}
catch(Exception e)
{
e.prinStackTrace();
}
Try writing to a temporary file (in the same file system) and once the file write is complete move it into place using File.renameTo(). If you underlying file system supports atomic move operations (most do) then you should get the behaviour that you require. If you are running on windows you will have to make sure you close the file after reading otherwise the file move will fail.
public class Data
{
private final File file;
protected Data(String fileName) {
this.file = new File(filename);
}
/* above is in some class somehwere
* then your code brings new info to the file
*/
//
public synchronized accessFile(String data) {
try {
// Create temporary file
String tempFilename = UUID.randomUUID().toString() + ".tmp";
File tempFile = new File(tempFilename);
//write the data ...
FileWriter fWriter = new FileWriter(tempFile);
fWriter.write(data);
fWriter.flush();
fWriter.close();
// Move the new file in place
if (!tempFile.renameTo(file)) {
// You may want to retry if move fails?
throw new IOException("Move Failed");
}
} catch(Exception e) {
// Do something sensible with the exception.
e.prinStackTrace();
}
}
}
FileWriter fWriter = new FileWriter(fileName,true);
try using above :-)
Your requirement is not very clear. Do you want to write a new name file every time or you want to append to the same file or you want to over write the same file? Anyway all three cases are easy and from the API you can manage it.
If the issue is that a web service is reading the file which is not yet complete i.e. is in writing phase. In your web service you should check if the file is read only, then only you read the file. In writing phase once writing is finished set the file to read only.
The 0Kb file happens because you are overwriting the same file again. Overwriting cleans up all the data and then start writing the new content.
public class Data
{
String fileName;
protected Data(String fileName)
{
this.fileName= fileName;
return; // return from constructor often not needed.
}
/* above is in some class somehwere
* then your code brings new info to the file
*/
//
public synchronized accessFile(String data)
{
try
{
// File name to be class member.
FileWriter fWriter = new FileWriter(fileName);
//write the data ...
fWriter.write(data);
fWriter .flush();
fWriter .close();
return;
}
catch(Exception e)
{
e.prinStackTrace();
}
this is not needed:
outputFile = "anotheroutput.html";
fWriter = new FileWriter(outputFile);
//write the data ...
fWriter .flush();
fWriter.close();
that's because work on the file is a method of class Data

Categories