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.
Related
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());
}
}
I have a Path variable like this:
Path output;
This path is initialized in the main-method.
I want to check if there exists a File in this path
and if thats the case- write a string into that file.
Else create a new File with the given path and write
the string.
//void parseOutput(String s){
//if (file in path exists)
// write(s in file from path)
else
File f = new File(String.valueOf(output));
write String in f
You can try this :
import java.io.*;
class FileDemo {
public static void main(String str[]) {
String path = "E:/myfile.txt";
File file = new File(path);
if(file.exists()) {
System.out.println("File is exist..!!!");
} else {
try {
FileWriter fileWriter = new FileWriter(path);
fileWriter.write("This is my first file..!!");
fileWriter.close();
System.out.println("File has some content..!!");
} catch(Exception exception) {
System.out.println(exception.getMessage());
}
}
}
}
If you have a Path, it doesn't really make sense to convert that to a String and use the File constructor.
For checking if a file exists, you can use Files exists.
To add to an existing file, have a look at Files.newBufferedWriter with the APPEND OpenOption set.
Full example:
Path path = Paths.get("/path/to/file.txt");
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(
path, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
PrintWriter printWriter = new PrintWriter(bufferedWriter))
{
printWriter.println("This is a line");
}
You might want to use exists() method in File class. Here's an example which you could use:
public void writeOnFile(String path, String str) throws FileNotFoundException {
PrintWriter out;
File file = new File(path);
if (file.exists()){
out = new PrintWriter(file.getPath());
out.println(str);
}
}
I am building an Android app where I want to export some values to a CSV.
I have to problem: either I get an error saying that the permission is denied or I get no errors but no CSV is created.
FileWriter writer;
File root = Environment.getExternalStorageDirectory();
File csvFile = new File(root, "xxx.csv");
writer = new FileWriter(csvFile);
String headers = String.format("%s,%s\n", "Timestamp",
"Value");
writer.write(headers);
writer.flush();
writer.close();
But i get nothing...
From Android 10 and beyond, Android enforces Storage Scope Model. You can either write your CSV file in App-Specific Location which is private to your App and doesn't require any user permission, but no one can access this location. Here is the code snippet to write the file into the App-Specific directory:
public void writeIntoFile(Context context, String fileName, String content) {
// File appSpecificExternalStorageDirectory = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
File appSpecificInternalStorageDirectory = context.getFilesDir();
File file = new File(appSpecificInternalStorageDirectory, fileName);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file, false);
fos.write(content.getBytes());
fos.close();
}
If you want to share this file with the User, then you should write this file in Shared Storage. To write a file in Shared Storage, this has to be done in 3 steps:-
Step 1: Launch System Picker to choose the destination by the user. This will return Uri of the destination directory.
private ActivityResultLauncher<Intent> launcher; // Initialise this object in Activity.onCreate()
private Uri baseDocumentTreeUri;
public void launchBaseDirectoryPicker() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
launcher.launch(intent);
}
Step 2: Launch System Picker to choose the destination by the user. This will return the Uri of the destination directory. Also, you can optionally persist the permissions and Uri for future use.
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
baseDocumentTreeUri = Objects.requireNonNull(result.getData()).getData();
final int takeFlags = (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// take persistable Uri Permission for future use
context.getContentResolver().takePersistableUriPermission(result.getData().getData(), takeFlags);
SharedPreferences preferences = context.getSharedPreferences("com.example.fileutility", Context.MODE_PRIVATE);
preferences.edit().putString("filestorageuri", result.getData().getData().toString()).apply();
} else {
Log.e("FileUtility", "Some Error Occurred : " + result);
}
}
Step 3: Write CSV content into a file.
public void writeFile(String fileName, String content) {
try {
DocumentFile directory = DocumentFile.fromTreeUri(context, baseDocumentTreeUri);
DocumentFile file = directory.createFile("text/*", fileName);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(file.getUri(), "w");
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
fos.write(content.getBytes());
fos.close();
} catch (IOException e) {
}
}
For more explanation, you can read "How to Save a file in Shared Storage in Android 10 or Higher" or Android official documentation.
I have tried in multiple ways to load the property file from the resource folder.
Every time, I'm getting a file not found exception. My code is as follows:
Properties prop = new Properties();
FileInputStream inputStream = new FileInputStream("/resource/excelfilepath.properties");
prop.load(inputStream);
String path = prop.getProperty("excelPath");
System.out.println("Excel File Path "+ path);
My project structure looks as follows,
What is the needed structure of the file path literal?
I don't think that you really want to read a ....properties file from web resources. That way the content is visible to all users that access your server - as long as you don't hide it explicitly in web.xml.
It's much more common to put it into the classpath next to your accessing class. That way you can access it with the classloader and it is not visible to the webusers anymore:
Properties prop = new Properties();
prop.load(CreateUser.class.getResourceAsStream("excelfilepath.properties"));
But as you are using Liferay, you should use its configuration as well. Just add the property UserCreationPortlet.excelPath to your portal-ext.properties and use:
String path = PrefsPropsUtil.getString("UserCreationPortlet.excelPath", defaultPath);
You need to tell to the server where your root folders are :
With Tomcat : in the catalina.properties
append the properties shared.loader with yours.
With Jboss : Edit jboss-service.xml in your conf folder
<classpath codebase="${jboss.home.url}/server/default/lib//proprietes/rootFolder" archives="*"/>
I would advice to create a classe to load your properties :
Like :
public static Properties charger(Class<?> pClass, String pFilename) {
Properties aProperties = null;
try {
InputStream aIs = null;
File aFile = new File(pFilename);
if (!aFile.isAbsolute()) {
aIs = pClass.getClassLoader().getResourceAsStream(pFilename);
if (aIs == null) {
return null;
}
} else if (!aFile.exists()) {
return null;
}
if (aIs == null)
aIs = new FileInputStream(aFile);
InputStreamReader reader = new InputStreamReader(aIs, "UTF-8");
aProperties = new Properties();
aProperties.clear();
aProperties.load(reader);
reader.close();
aIs.close();
} catch (FileNotFoundException e) {
LOG.error("Catch FileNotFoundException : ", e);
} catch (IOException e) {
LOG.error("Catch IOException : ", e);
}
return aProperties;
}
Then call your new class with the property that you wish :
protected static final Properties property = ChargeurProprietes.charger( .class,"PATH");
property.getProperty(NAME OF YOUR PROPERTY);
I have a config.properties file at the root of my blackberry project (same place as Blackberry_App_Descriptor.xml file), and I try to access the file to read and write into it.
See below my class:
public class Configuration {
private String file;
private String fileName;
public Configuration(String pathToFile) {
this.fileName = pathToFile;
try {
// Try to load the file and read it
System.out.println("---------- Start to read the file");
file = readFile(fileName);
System.out.println("---------- Property file:");
System.out.println(file);
} catch (Exception e) {
System.out.println("---------- Error reading file");
System.out.println(e.getMessage());
}
}
/**
* Read a file and return it in a String
* #param fName
* #return
*/
private String readFile(String fName) {
String properties = null;
try {
System.out.println("---------- Opening the file");
//to actually retrieve the resource prefix the name of the file with a "/"
InputStream is = this.getClass().getResourceAsStream(fName);
//we now have an input stream. Create a reader and read out
//each character in the stream.
System.out.println("---------- Input stream");
InputStreamReader isr = new InputStreamReader(is);
char c;
System.out.println("---------- Append string now");
while ((c = (char)isr.read()) != -1) {
properties += c;
}
} catch (Exception e) {
}
return properties;
}
}
I call my class constructor like this:
Configuration config = new Configuration("/config.properties");
So in my class, "file" should have all the content of the config.properties file, and the fileName should have this value "/config.properties".
But the "name" is null because the file cannot be found...
I know this is the path of the file which should be different, but I don't know what i can change... The class is in the package com.mycompany.blackberry.utils
Thank you!
I think you need to put the config.properties file into a source folder when you build the project, you can create a "resources" folder as a src folder and put the config file in it, than you can get the file in the app
Try putting the file in the same package as the class?
Class clazz = Class.forName("Configuration");
InputStream is = addFile.getResourceAsStream(fName);