I have a JavaFX project with 2 modules..
[Project structure][1]
public class SkiResortModel {
private static final String FILE_NAME_RESORTS = "/SKI_RESORTS.csv";
//Code for reading file is:
private BufferedReader getReader() {
InputStream inputStreamResorts = getClass().getResourceAsStream(SkiResortModel.FILE_NAME_RESORTS);
assert inputStreamResorts != null;
InputStreamReader readerResorts = new InputStreamReader(inputStreamResorts, StandardCharsets.UTF_8);
return new BufferedReader(readerResorts);
}
private List<SkiResortModel> readFromFile() {
try (BufferedReader reader = getReader()) {
return reader.lines()
.skip(1)
.map(line -> new SkiResortModel(line.split(DELIMITER, 0)))
.collect(Collectors.toList());
} catch (IOException e) {
throw new IllegalStateException("failed");
}
}
//Code for writing file is:
private BufferedWriter getWriter(String filename) {
try {
String file = Objects.requireNonNull(getClass().getResource(filename)).getFile();
return new BufferedWriter(new FileWriter(file, StandardCharsets.UTF_8));
} catch (IOException e) {
throw new IllegalStateException("wrong file " + filename);
}
}
public void save() {
try (BufferedWriter writer = getWriter(FILE_NAME_RESORTS)) {
writer.write(
"ENTITY_ID;NAME;REGION;COMMUNES_IN_RESORT;MASL_MIN;MASL_MAX;SKI_RUNS_KM;DRAG_LIFTS;CHAIR_LIFTS;CABLE_CARS;OPEN_LIFTS;SNOW_DEPTH_CM;VISITORS_TODAY;CAR_FREE;FUNPARK_AVAILABLE;IMAGE_URL");
writer.newLine();
int id = 100;
for (SkiResortModel s : allSkiResorts) {
writer.write(s.infoAsLine(";", id));
writer.newLine();
id++;
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
We have created a small application which displays the data in a table and allows for some modification. The data should then be written back into the original csv file.
The data is stored in the resources folder (screenshot). When the save function is called the data should then be written back into the original csv-file. However Intellij creates a new csv file under skiresorts-model/target.
I tried to indicate the path by copying the path from the context menue (Right click on file => Copy path / reference. I tried all the options to copy the path but then the program is unable to find the file. Strange is also that after I used copy path/reference
the program is unable to run even with the original path. The only thing that helps then is to check out another branch and return to the branch. Is this a bug in Intellij?
The save function is called from another class after the modifications have been done.
Any help is greatly appreciated.
[1]: https://i.stack.imgur.com/NwtB2.png
Related
I am currently working on a web application. I created a button called "export", in the front end. A user click should trigger the download of a CSV file, which I generated in the back end. The CSV file is filled with values from a database table.
Do I need to generate a link to pass it to the front end button (maybe with JSON?)?
How should I proceed?
Additional information: The application is programmed with Java. The framework I use is Spring-Boot.
Code for generating CSV file
public class readDb {
public static List<Success> getDataFromDb (List<Success> success){
System.out.println("getDataFromDb");
erfolg.forEach(System.out::println);
return erfolg;
}
public static void successExport (List<Success> success) throws IOException {
String csvFile = "\\\\fs-vcs-02\\userhome\\username\\Desktop\\test.csv";
FileWriter writer = new FileWriter(csvFile);
CSVUtils.writeLine(writer, Arrays.asList("id", "endDate", "dataFromB", "dataToB", "dataToE", "report", "amountOfM", "rate", "amountOfA", "statistics", "resultP", "resultN", "resultO", "chancel", "assignmentVolume));
for (Erfolg d : erfolg) {
List<String> list = new ArrayList<>();
list.add(d.getId().toString());
list.add(d.getEndDate().toString());
list.add(d.getDataFromB().toString());
list.add(d.getDataToB().toString());
list.add(d.getDataToE().toString());
list.add(d.getReport().toString());
list.add(d.getAmountOfM().toString());
list.add(d.getRate().toString());
list.add(d.getAmountOfA().toString());
list.add(d.getStatistics().toString());
list.add(d.getResultP().toString());
list.add(d.getResultN().toString());
list.add(d.getResultO().toString());
list.add(d.getChancel().toString());
list.add(d.getAssignmentVolume().toString());
CSVUtils.writeLine(writer, list);
}
writer.flush();
writer.close();
}
}
Code for file export
public static void export() {
File f = null;
boolean bool = false;
try {
f = new File("\\\\fs-vcs-02\\userhome\\agoenkur\\Desktop\\test.csv");
bool = f.createNewFile();
System.out.println("File created: "+bool);
f.delete();
System.out.println("delete() method is invoked");
bool = f.createNewFile();
System.out.println("File created: "+bool);
} catch(Exception e) {
e.printStackTrace();
}
}
}
I am currently working on a small project to improve my programming skills, so not every “feature” might seem practical. Part of the application is a way to write notes and save them to a JList. While this notes-object is created, the content of the note (title and text) is saved to a .properties file. I picked the property-object because I needed some kind of key to allocate the content (text and title) to.
The Part for saving notes and creating the .properties file is working fine. But after closing and opening the application I want to populate the JList with the data in the .properties file. My problem now is that I want that the notes load in the same order as they were created in the first place. So if I create note a,b,c and close the application, I want that they load in this same order and I have a,b,c in my list again.
So I thought I’ll put the index of each file into the filename. This way the order in the notes directory on my hard disk is the same as in my JList. But this only works fine until you start deleting notes which messes up the order on the hard disk because of the id.
Can anyone give me a tip on how to solve this problem? I need a way to load the files in the same order they were created.
Here is the Code for adding notes:
private class AddNoteAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// Initialize variables
Properties data = new Properties();
FileOutputStream oStream = null;
// Create instance of note with the given text
String text = fldText.getText();
String title = fldTitle.getText();
Note note = new Note(text, title);
// Create new file in notes directory to save properties data
File file = new File(Config.NOTES_DIR, note.getId() + title + ".properties");
// Save data from userinput to properties file (date and id are being set when a new note object is created)
data.setProperty("title", title);
data.setProperty("text", text);
data.setProperty("created", note.getDate());
data.setProperty("id", String.valueOf(note.getId()));
// Write data from properties to file on the drive
try {
oStream = new FileOutputStream(file);
data.store(oStream, Config.APP_NAME + " Notes Data");
} catch (IOException e1) {
e1.printStackTrace();
}finally {
if(!(oStream == null)){
try {
oStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
// Add note to model
noteListModel.addNote(note);
// Clear Textfields after adding Note
fldText.setText("");
fldTitle.requestFocusInWindow();
fldTitle.setText("");
}
}
Here is the code for loading the notes:
public class LoadNotes {
// Initialize Variables
private NoteListModel noteModel;
private File folder = new File(Config.NOTES_DIR);
private File[] files = folder.listFiles();
private Properties data = new Properties();
private FileInputStream iStream = null;
// Load ListModel when creating instance of this class
public LoadNotes(NoteListModel noteModel){
this.noteModel = noteModel;
}
// Load text-files data from notes directory into properties and create new note
public void load(){
for (File file : files){
if(file.isFile()){
try {
iStream = new FileInputStream(file);
data.load(iStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(!(iStream == null)){
try {
iStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Read data from file to property
String title = data.getProperty("title");
String text = data.getProperty("text");
int id = Integer.parseInt((data.getProperty("id")));
// Create new note instance and save to model
Note note = new Note(text,title);
noteModel.addNote(note);
}
}
}
I am trying to make an application that will create Google Authenticator secret keys, as well as authenticate the OTP. I am writing all of my passwords to individual files titled with the name that goes along with them.
First and foremost, I am using this library.
https://github.com/aerogear/aerogear-otp-java
This is my code:
public void createUserFile(String name) throws IOException
{
File file = new File("users\\" + name + ".txt");
file.createNewFile();
}
public void generateUserKey(String name)
{
try
{
File file = new File("users\\" + name + ".txt");
FileWriter fw = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fw);
String s = Base32.random();
out.write(s);
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
If I change the value of s to something like "Hello" I am fine. However, it will not write that random string. That is what I need help with. I have tinkered and searched hours for answers, and I have found nothing.
I don't believe you need createUserFile, and it isn't clear you necessarily know where the "users/" folder (a relative path) is. I suggest you use System.getProperty(String) to get user.home (the User home directory).
I would also suggest you use a try-with-resources Statement and a PrintStream. Something like
public void generateUserKey(String name) {
File file = new File(System.getProperty("user.home"), //
String.format("%s.txt", name));
try (PrintStream ps = new PrintStream(file)) {
ps.print(Base32.random());
} catch (IOException e) {
e.printStackTrace();
}
}
I'm using JDK 7. I've got a class with a method that creates a html-file using PrintStream. Another method in the same class is supposed to use the created file and do stuff with it. The problem is that once i use new File("path/to/file.html), the file lenght is reduced to 0. My code:
public class CreatePDFServiceImpl {
private final PrintStream printStream;
public CreatePDFServiceImpl() throws IOException {
printStream = new PrintStream("/mnt/test.html", "UTF-8");
}
public void createHtmlFile() throws IncorporationException {
try {
StringBuilder html = new StringBuilder();
HtmlFragments htmlFragments = new HtmlFragments();
html.append(htmlFragments.getHtmlTop())
.append(htmlFragments.getHeading())
.append(htmlFragments.buildBody())
.append(htmlFragments.buildFooter());
printStream.print(html.toString());
} finally {
if(printStream != null) {
printStream.close();
}
}
}
This next method is supposed to use the html file created in "createHtmlFile()":
public void convertHtmlToPdf() {
PrintStream out = null;
try {
File file = new File("/mnt/test.html");
/** this code added just for debug **/
if (file.createNewFile()){
System.out.println("File is created!");
} else {
System.out.println("File already exists. size: " + file.length());
}
/* PDF generation commented out. */
//out = new PrintStream("/mnt/testfs.pdf", "UTF-8");
//defaultFileWriter.writeFile(file, out, iTextRenderer);
} catch (IOException e) {
throw new IncorporationException("Could not save pdf file", e);
} finally {
if(out != null) {
out.close();
}
}
My junit integration test class:
#Category(IntegrationTest.class)
public class CreatePDFServiceIntegrationTest {
private static CreatePDFServiceImpl createPDFService;
#BeforeClass
public static void init() throws IOException {
createPDFService = new CreatePDFServiceImpl();
}
#Test
public void testCreateHtmlFile() throws IncorporationException {
createPDFService.createHtmlFile();
File createdFile = new File("/mnt/test.html");
System.out.println("createdFile.length() = " + createdFile.length());
Assert.assertTrue(createdFile.length() > 1);
}
#Test
public void testCreatePDF() throws Exception {
File fileThatShouldExist = new File("/mnt/testfs.pdf");
createPDFService.convertHtml2Pdf();
Assert.assertTrue(fileThatShouldExist.exists());
}
}
The first test passes, output:
"createdFile.length() = 3440".
I checked the file system, there is the file. size 3,44kb.
Second test fails, output from CreatePDFServiceImpl:
"File already exists. size: 0"
Looking in the file system, the file now is actually 0 bytes.
I'm stumped. The new File("path") should only create a reference to that file and not empty it?
I doubt there's an error in File.createNewFile(). I don't yet fully grasp in which order you run your code, but are you aware that this sets the file size to zero?
out = new PrintStream("/mnt/testfs.pdf", "UTF-8");
From the PrintStream(File file) Javadoc:
file - The file to use as the destination of this print stream. If the
file exists, then it will be truncated to zero size; otherwise, a new
file will be created. The output will be written to the file and is
buffered.
I think that's the culprit - but in your code that line is commented out. Am I right you have run your tests with that line commented in?
I was wondering whether there is a way to take a given .jar file, selected with a JFileChooser, extract it and put it into a new directory. Then, take all the files from another directory, add it to the directory with the extracted .jar file, and then take all that and package it back up again.
I'm doing this because I want a really easy way to install mods for that game, minecraft, where you can just select your minecraft.jar, and make sure the files for the mod are in a folder, and wait a bit, as indicated by a JProgressBar.
This is all I have so far
import java.io.*;
import java.util.jar.*;
import javax.swing.*;
public class Main extends JFrame {
public Main() {
super("Auto-mod installer");
setSize(300, 60);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JProgressBar bar = new JProgressBar(0, 100);
add(bar);
setVisible(true);
}
public static void main(String[] args) {
Main m = new Main();
}
private void extract(File f) {
//Hrm...
}
private void addModFiles() {
//Uh...
}
private void repackage(File f) {
//What?
}
}
As you can see, I have no idea what I'm doing. I do know what the imports needed are, but that's about it. Help would be appreciated, ranting about anything I did wrong would get me mad. Thanks!
EDIT: If you know a way to get the same results, and it's not the way that I was looking for, please let me know how to do so. As long as I get the results I was looking for, it would be great. Thanks again!
The idea is relatively simple. You have a few gotchas (like what to do if files already exist and that kind of thing), but otherwise...
I'd start by having a look at JarFile
(I'm in the middle of another example, but when I get time, I'll post some stuff)
UPDATE with Example
public class JarTest {
protected static final String OUTPUT_PATH = "..."; // The place you want to extact the jar to
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new JarTest();
}
public JarTest() {
try {
unjar();
// Copy new contents in...
jar();
} catch (IOException exp) {
exp.printStackTrace();
}
}
// This just recursivly lists through all the files to be included in the new jar
// We don't care about the directories, as we will create them from the file
// references in the Jar ourselves
protected List<File> getFiles(File path) {
List<File> lstFiles = new ArrayList<File>(25);
// If you want the directories, add the "path" to the list now...
File[] files = path.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isDirectory()) {
lstFiles.addAll(getFiles(file));
} else {
lstFiles.add(file);
}
}
}
return lstFiles;
}
// Re-Jar the contents
// You should always attempt to jar back to a new file, as you may not want to effect the original ;)
public void jar() throws IOException {
JarOutputStream jos = null;
try {
String outputPath = OUTPUT_PATH;
// Create a new JarOutputStream to the file you want to create
jos = new JarOutputStream(new FileOutputStream("...")); // Add your file reference
List<File> fileList = getFiles(new File(OUTPUT_PATH));
System.out.println("Jaring " + fileList.size() + " files");
// Okay, I cheat. I make a list of all the paths already added to the Jar only create
// them when I need to. You could use "file.isDirectory", but that would mean you would need
// to ensure that the files were sorted to allow all the directories to be first
// or make sure that the directory reference is added to the start of each recursion list
List<String> lstPaths = new ArrayList<String>(25);
for (File file : fileList) {
// Replace the Windows file seperator
// We only want the path to this element
String path = file.getParent().replace("\\", "/");
// Get the name of the file
String name = file.getName();
// Remove the output path from the start of the path
path = path.substring(outputPath.length());
// Remove the leading slash if it exists
if (path.startsWith("/")) {
path = path.substring(1);
}
// Add the path path reference to the Jar
// A JarEntry is considered to be a directory if it ends with "/"
if (path.length() > 0) {
// At the trailing path seperator
path += "/";
// Check to see if we've already added it out not
if (!lstPaths.contains(path)) {
// At the path entry...we need need this to make it easier to
// extract the files at a later state. There is a way to cheat,
// but I'll let you figure it out
JarEntry entry = new JarEntry(path);
jos.putNextEntry(entry);
jos.closeEntry();
// Make sure we don't try to add the same path entry again
lstPaths.add(path);
}
}
System.out.println("Adding " + path + name);
// Create the actual entry for this file
JarEntry entry = new JarEntry(path + name);
jos.putNextEntry(entry);
// Write the entry to the file
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] byteBuffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = fis.read(byteBuffer)) != -1) {
jos.write(byteBuffer, 0, bytesRead);
}
jos.flush();
} finally {
try {
fis.close();
} catch (Exception e) {
}
}
jos.closeEntry();
}
jos.flush();
} finally {
try {
jos.close();
} catch (Exception e) {
}
}
}
public void unjar() throws IOException {
JarFile jarFile = null;
try {
String outputPath = OUTPUT_PATH;
File outputPathFile = new File(outputPath);
// Make the output directories.
// I'll leave it up to you to decide how best to deal with existing content ;)
outputPathFile.mkdirs();
// Create a new JarFile reference
jarFile = new JarFile(new File("C:/hold/Java_Harmony.jar"));
// Get a list of all the entries
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
// Get the next entry
JarEntry entry = entries.nextElement();
// Make a file reference
File path = new File(outputPath + File.separator + entry.getName());
if (entry.isDirectory()) {
// Make the directory structure if we can
if (!path.exists() && !path.mkdirs()) {
throw new IOException("Failed to create output path " + path);
}
} else {
System.out.println("Extracting " + path);
// Extract the file from the Jar and write it to disk
InputStream is = null;
OutputStream os = null;
try {
is = jarFile.getInputStream(entry);
os = new FileOutputStream(path);
byte[] byteBuffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = is.read(byteBuffer)) != -1) {
os.write(byteBuffer, 0, bytesRead);
}
os.flush();
} finally {
try {
os.close();
} catch (Exception e) {
}
try {
is.close();
} catch (Exception e) {
}
}
}
}
} finally {
try {
jarFile.close();
} catch (Exception e) {
}
}
}
}
You can use this very simple library to pack/unpack jar file
JarManager
Very simple
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import fr.stevecohen.jarmanager.JarPacker;
import fr.stevecohen.jarmanager.JarUnpacker;
public class MyClass {
public void addFileToJar(String jarPath, String otherFilePath) {
try {
JarUnpacker jarUnpacker = new JarUnpacker();
File myJar = new File("./myfile.jar");
File otherFile = new File(otherFilePath);
Path unpackDir = Files.createTempDirectory(myJar.getName()); //create a temp directory to extract your jar
System.out.println("Unpacking in " + unpackDir.toString());
jarUnpacker.unpack(jarPath, unpackDir.toString()); //extraxt all files contained in the jar in temp directory
Files.copy(otherFile.toPath(), new File(unpackDir.toFile(), otherFile.getName()).toPath()); //copy your file
JarPacker jarRepacker = new JarPacker();
File newJar = new File("./maNewFile.jar");
System.out.println("Packing jar in " + newJar.getAbsolutePath());
jarRepacker.pack(unpackDir.toString(), newJar.getAbsolutePath()); //repack the jar with the new files inside
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can also use maven dependency
<dependency>
<groupId>fr.stevecohen.jarmanager</groupId>
<artifactId>JarManager</artifactId>
<version>0.5.0</version>
</dependency>
You also need my repository
<repository>
<id>repo-reapersoon</id>
<name>ReaperSoon's repo</name>
<url>http://repo-maven.stevecohen.fr</url>
</repository>
Check the last version with the link bellow to use the last dependency
Please use my public issue tracker if you find some bugs