I have an app where user can upload file with additional info about it, such as description.
Now what i do is:
predefine the PATH where the files are stored ( so for example for server it will be at /files/ or for AWS url to aws )
user uploads file
file is saved, at location PATH/userId/uploaded file name
service that saves file returns whole path
the informations about file ( including path where it was stored ) is stored in DB.
So smth like this:
#Service
public class DiskSaveFileService implements SaveFileService {
#Value("${file.path}")
private String path;
#Override
public String saveFile(String fileName, byte[] bytes) {
Path targetLocation = Paths.get(path + "/" + fileName);
try {
Files.createDirectories(targetLocation.getParent());
Files.write(targetLocation, bytes);
} catch (IOException e) {
throw new SaveFileException("Saving file failed", e);
}
return targetLocation.toString();
}
#Override
public boolean safeDeleteFile(String fileName) throws SaveFileException {
Path targetLocation = Paths.get(path + "/" + fileName);
try {
Files.delete(targetLocation);
} catch (IOException e) {
return false;
}
return true;
}
}
And service:
UserEntity user = userUtilService.getLoggedUser();
String fileName = file.getOriginalFilename();
String path = user.getId() + "/" + fileName;
try{
String location = saveFileService.saveFile(path, uploadedFile.getBytes());
FileEntity fileEntity = new FileEntity();
fileEntity.setPath(location);
....
fileRepository.save(fileEntity);
} catch (UsernameNotFoundException | SaveFileException | IOException e) {
deleteFile(path);
throw new RecipeServiceException("Error creating recipe!", e);
}
However if user wanted to upload two separate files, that happens to have same name, this would overwritte them, as both files would be saved in the same path.
What is the best way to determine where exactly to store path? I first wanted to save the file as
PATH/userId/id of entity/name of the file
However in that case i would need to save info about file to database, then save the file ( so i will have generated ID of row ), and then update entity of location. So i would have extra database hit.
What are some best ways to decide the path then? Methods that would actually makes sense.
Related
I have a camera that I am grabbing values pixel-wise and I'd like to write them to a text file. The newest updates for Android 12 requires me to use storage access framework, but the problem is that it isn't dynamic and I need to keep choosing files directory. So, this approach it succesfully creates my files but when writting to it, I need to specifically select the dir it'll save to, which isn't feasible to me, as the temperature is grabbed for every frame and every pixel. My temperature values are in the temperature1 array, I'd like to know how can I add consistently add the values of temperature1 to a text file?
EDIT: I tried doing the following to create a text file using getExternalFilesDir():
private String filename = "myFile.txt";
private String filepath = "myFileDir";
public void onClick(final View view) {
switch (view.getId()){
case R.id.camera_button:
synchronized (mSync) {
if (isTemp) {
tempTureing();
fileContent = "Hello, I am a saved text inside a text file!";
if(!fileContent.equals("")){
File myExternalFile = new File(getExternalFilesDir(filepath), filename);
FileOutputStream fos = null;
try{
fos = new FileOutputStream(myExternalFile);
fos.write(fileContent.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
Log.e("TAG", "file: "+myExternalFile);
}
isTemp = false;
//Log.e(TAG, "isCorrect:" + mUVCCamera.isCorrect());
} else {
stopTemp();
isTemp = true;
}
}
break;
I can actually go all the way to the path /storage/emulated/0/Android/data/com.MyApp.app/files/myFileDir/ but strangely there is no such file as myFile.txt inside this directory, how come??
Working Solution:
public void WriteToFile(String fileName, String content){
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
File newDir = new File(path + "/" + fileName);
try{
if (!newDir.exists()) {
newDir.mkdir();
}
FileOutputStream writer = new FileOutputStream(new File(path, filename));
writer.write(content.getBytes());
writer.close();
Log.e("TAG", "Wrote to file: "+fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
I've a Java program that is copying a file from Unix to hdfs. It is running fine however I am looking for impersonating a different account when it runs and copies file.
Input: Apart form input file and target hdfs directory path, another input should be properties file containing account, keytab directory, domain
Please kindly let me know the best way to move forward.
I am currently exploring using a shell to first issue a kinit command and then run the jar
I am also reading about Jaas and how this can be done in Java itself - from - https://henning.kropponline.de/2016/02/14/a-secure-hdfs-client-example/
Need inputs and any reference of available options.
My Java program that copies file is as below:
public class FileCopy implements Runnable {
#Option(names = {"-i","--input"}, required=true, description="file name to copy to hadoop")
String input;
#Option(names = {"-o","--output"}, required=true, description="hdfs directory path to be copied into")
String output;
public void run() {
Properties hadoop_properties = new Properties();
HdfsFileDeploy hdfsFileDeploy = new HdfsFileDeploy();
try {
hadoop_properties.load(FileCopy.class.getClassLoader().getResourceAsStream("hadoop.properties"));
} catch (IOException e) {
e.printStackTrace();
}
FileSystem fs = hdfsFileDeploy.configureFilesystem(hadoop_properties.getProperty("coreSitePath"),hadoop_properties.getProperty("hdfsSitePath"));
String status = hdfsFileDeploy.writeToHDFS(fs,input,output);
if (status == "SUCCESS") {
System.out.println("completed copying");
} else {
System.out.println("copying error");
}
hdfsFileDeploy.closeFileSystem(fs);
}
public static void main(String[] args) throws IOException {
CommandLine.run(new FileCopy(), args);
}
}
public class HdfsFileDeploy {
public FileSystem configureFilesystem(String coreSitePath, String hdfsSitePath) {
FileSystem fileSystem = null;
try {
Configuration conf = new Configuration();
Path hdfsCoreSitePath = new Path(coreSitePath);
Path hdfsHDFSSitePath = new Path(hdfsSitePath);
conf.addResource(hdfsCoreSitePath);
conf.addResource(hdfsHDFSSitePath);
fileSystem = FileSystem.get(conf);
System.out.println(fileSystem);
return fileSystem;
} catch (Exception ex) {
ex.printStackTrace();
return fileSystem;
}
}
public void closeFileSystem(FileSystem fileSystem) {
try {
fileSystem.close();
} catch (Exception ex) {
System.out.println("Unable to close Hadoop filesystem : " + ex);
}
}
//
public String writeToHDFS(FileSystem fileSystem, String sourcePath, String destinationPath) {
String failure = "FAILURE";
String success = "SUCCESS";
Boolean doNotDelSrc = false;
Boolean overwrite = true;
try {
Path inputPath = new Path(sourcePath);
Path outputPath = new Path(destinationPath);
if(!fileSystem.exists(outputPath)) {
System.out.println("Output path " + outputPath + " does not exist. Creating outputPath directory now..");
if (fileSystem.mkdirs(outputPath)) {
System.out.println("Output path " + outputPath + " created...");
}
}
System.out.println("about to copy from " + inputPath + " to " + outputPath);
fileSystem.copyFromLocalFile(doNotDelSrc, overwrite, inputPath, outputPath);
return success;
} catch (IOException ex) {
System.out.println("Some exception occurred while writing file to hdfs");
ex.printStackTrace();
return failure;
}
}
}
Input1: input file
Input2: target hdfs directory
Reference Input: file (say yaml) containing account, domain, keytab path.
jar should impersonate and copy the input file to target hdfs directory.
I am uploading image files from application, now I want to save them in WEB-INF, but eclipse is saving it in .metadata folder .metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps.
Please let me know who can I get the path to WEB-INF3
#RequestMapping(value = "/admin/productInventory/addProduct", method = RequestMethod.POST)
public String addProduct(#ModelAttribute("product") Product product,HttpServletRequest request) {//httservlet- aswe need to use that toget thesessionpath
productDao.addProduct(product);
/////add image
MultipartFile productImage= product.getProductImage();
String rootDirectory= request.getSession().getServletContext().getRealPath("/"); //C:\Users\Avinash Kharche\ECommerce_Spring_Neon\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\emusicStore\
path =Paths.get(rootDirectory + "\\WEB-INF\\resources\\images\\" + product.getProductId()+".png");
//path =Paths.get("C:\\Users\\Avinash Kharche\\ECommerce_Spring_Neon\\emusicStore\\src\\main\\webapp\\WEB-INF\\resources\\images\\" + product.getProductId()+".png");
if(productImage!=null && !productImage.isEmpty()){
try{
productImage.transferTo(new File(path.toString()));
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException("Product image saving failed",e);
}
}
/////
return "redirect:/admin/productInventory";
}
I dont want to use commented path
(//path =Paths.get("C:\Users\Avinash Kharche\ECommerce_Spring_Neon\emusicStore\src\main\webapp\WEB-INF\resources\images\" + product.getProductId()+".png");)
Please let me know any solution. Thanks
Here is the solution:
#RequestMapping(value = "/admin/productInventory/addProduct", method = RequestMethod.POST)
public String addProductPost(#ModelAttribute("product") Product product, HttpServletRequest request) {
productDao.addProduct(product);
MultipartFile productImage = product.getProductImage();
String rootDirectory = request.getSession().getServletContext().getRealPath("/");
path = Paths.get(rootDirectory + "/WEB-INF/resources/images/" + product.getProductId() + ".png");
if (productImage != null && !productImage.isEmpty()) {
try {
productImage.transferTo(new File(path.toString()));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Product image saving failed", e);
}
}
return "redirect:/admin/productInventory";
}
Change path from:
path =Paths.get(rootDirectory + "\\WEB-INF\\resources\\images\\" + product.getProductId()+".png");
To
path = Paths.get(rootDirectory + "/WEB-INF/resources/images/" + product.getProductId() + ".png");
Make sure you do the same for edit and delete functions. I had the same problem. With your version, it worked on windows but on Mac, I had to change the path as shown above
I am having some difficulties retrieving data from files. To start with, here is my main method for file creation, which will be triggered (later) when a player logs in to the server.
// SettingsManager.java
private File file;
private FileConfiguration config;
// ...
public void createFile(String fileName) {
file = new File(UnderCovern.getPlugin().getDataFolder(), fileName + ".yml");
if ( !file.exists()) {
try {
file.createNewFile();
} catch (Exception e) {
UtilLogger.exception(e, "[SettingsManager] Could not create new file.");
}
}
config = YamlConfiguration.loadConfiguration(file);
}
The file is being created normally for each user - in another class -, with their name as the filename as seen here.
SettingsManager.get().createFile(player.getName());
However, I do not know exactly how I can retrieve the correct .yml file for a user, and retrieve data from it. This code block throws me a NullPointerException.
public Rank getRank() {
if (SettingsManager.get().getConfig().get(player.getName()) != null)
return (Rank) SettingsManager.get().getConfig().get(player.getName() + ".Rank");
return null;
}
Please also note that I am using the Bukkit framework.
Your method:
public Rank getRank() {
if (SettingsManager.get().getConfig().get(player.getName()) != null)
return (Rank) SettingsManager.get().getConfig().get(player.getName() + ".Rank");
return null;
}
Returns null if if (SettingsManager.get().getConfig().get(player.getName()) != null) is equal to null. So, the file probably isn't created, or you try to get a not-existing file. Can I maybe see the .getConfig() method?
I have a Java Class UpdateStats in WEB-INF/Classes directory of a dynamic web application.This class has a function writeLog() which writes some logs to a text file.I want this text file to be in webcontent directory.Thus everytime the function is called updates stats are written in that text file.
The problem is how to give the path of that text file in webcontent directory from within that function,which resides in WEB-INF/Classes directory.
You can get your webapp root directory from ServletContext:
String path = getServletContext().getRealPath("WEB-INF/../");
File file = new File(path);
String fullPathToYourWebappRoot = file.getCanonicalPath();
Hope this helps.
You can do something like below in your servlet,
When you do getServletContext().getRealPath() and put some string argument the file will see at your webcontent location.
If you want something into WEB-INF, you can give fileName like "WEB-INF/my_updates.txt".
File update_log = null;
final String fileName = "my_updates.txt";
#Override
public void init() throws ServletException {
super.init();
String file_path = getServletContext().getRealPath(fileName);
update_log = new File(file_path);
if (!update_log.exists()) {
try {
update_log.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Error while creating file : " + fileName);
}
}
}
public synchronized void update_to_file(String userName,String query) {
if (update_log != null && update_log.exists()) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(update_log, true);
fos.write((getCurrentFormattedTime()+" "+userName+" "+query+"\n").getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
To write a file you need to know absolute path of your web content directory on server as file class require absolute path.
File f = new File("/usr/local/tomcat/webapps/abc/yourlogfile.txt");
FileOutputStream out = new FileOutputStream(f);
out.writeLog("Data");
Assumption : abc is your project name
WebContent is not any directory when you deploy application. All files under web content goes directly under project name.