I am uploading a file using Spring MultipartFile. I need to store the uploaded file attributes like creation date and modified date. Currently I am using following approach:
File dest = new File(uploadfile.getOriginalFilename());
dest.createNewFile();
FileOutputStream fos = new FileOutputStream(dest);
fos.write(uploadfile.getBytes());
fos.close();
Path filee = dest.toPath();
BasicFileAttributes attr = Files.readAttributes(filee, BasicFileAttributes.class);
System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());
where uploadfile is the object of spring boot MultipartFile.
Referred links :
How to convert a multipart file to File?
Get java.nio.file.Path object from java.io.File
Determine file creation date in Java
The issue is that I am getting creation date and modified date as the current date only and probably the reason is that the new file object is resetting these values. How can I get the attributes of the original uploaded file?
The file meta data (like your creationTime, lastAccessTime, lastModifiedTime) is not part of the file, but the filesystem. Thus by uploading a file you only get the file and not the additional (meta) data that is managed by the filesystem.
You could add the last modified date to the upload form with the help of the File API (access and creation are not supported), but these can be manipulated by the user and thus you cannot trust them, if that is not a problem for you here an example from: https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified
html:
<!-- inside your form -->
<input type="file" multiple id="fileInput">
javascript:
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(event) {
// files is a FileList object (similar to NodeList)
const files = event.target.files;
for (let i = 0; i < files.length; i++) {
const date = new Date(files[i].lastModified);
alert(files[i].name + ' has a last modified date of ' + date);
// TODO add the date as a hidden input to your form
}
});
Related
How can I save the output file from Run query and list results in a .PARQUET file format.
This is my current workflow.
My Logic App is working, But the file .parquet created are not valid every time I view it on Apache Parquet Viewer
Can someone help me on this matter. Thank you!
Output:
I see that you are trying to add .parquet to the csv file you are receiving but that's not how it will be converted to parquet file.
One of the workarounds that you can try is to get the csv file and then add Azure function which can convert into parquet file and then adding the azure function to logic app.
Here is the function that worked for me:
BlobServiceClient blobServiceClient = new BlobServiceClient("<YOUR CONNECTION STRING>");
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("<YOUR CONTAINER NAME>");
BlobClient blobClient = containerClient.GetBlobClient("sample.csv");
//Download the blob
Stream file = File.OpenWrite(#"C:\Users\<USER NAME>\source\repos\ParquetConsoleApp\ParquetConsoleApp\bin\Debug\netcoreapp3.1\" + blobClient.Name);
await blobClient.DownloadToAsync(file);
Console.WriteLine("Download completed!");
file.Close();
//Read the downloaded blob
Stream file1 = new FileStream(blobClient.Name, FileMode.Open);
Console.WriteLine(file1.ReadToEnd());
file1.Close();
//Convert to parquet
ChoParquetRecordConfiguration csv = new ChoParquetRecordConfiguration();
using (var r = new ChoCSVReader(#"C:\Users\<USER NAME>\source\repos\ParquetConsoleApp\ParquetConsoleApp\bin\Debug\netcoreapp3.1\" + blobClient.Name))
{
using (var w = new ChoParquetWriter(#"C:\Users\<USER NAME>\source\repos\ParquetConsoleApp\ParquetConsoleApp\bin\Debug\netcoreapp3.1\convertedParquet.parquet"))
{
w.Write(r);
w.Close();
}
}
after this step you can publish to your azure function and add the Azure function connector to your logic app
You can skip the first 2 steps (i.e.. Read and Download the blob) and get the blob directly from logic app and send it to your azure function and follow the same method as above. The generated parquet file will be in this path.
C:\Users\<USERNAME>\source\repos\ParquetConsoleApp\ParquetConsoleApp\bin\Debug\netcoreapp3.1\convertedParquet.parquet
Here convertedParquet.parquet is the name of the parquet file. Now you can read the converted parquet file in Apache Parquet reader.
Here is the output
I'm able to read blob from the richtext field now need to save it as .jgp/png into my local folder
Matcher imgMatcher = Pattern.compile( '<img(.+?)>' ).matcher(con.Photo__c);
String imageURL = imageTag.substringBetween( ' src="', '"' );
String decodedURL = imageURL.unescapeHtml4();
PageReference page = new PageReference( decodedURL );
Blob bodyBlob = page.getContent();
//something like this
File file=new File('c://myimages');
image img=new image(bodyBlob);
img.fomrat='jpg';
img.title='myphoto';
file.save(img);
so it stores as image in my local folder. is this possible using apex(salesforce)
Salesforce cannot write to your file system. You have a few options, you can save to an Attachment record or Document record and download it from there, or you can expose the file through a visualforce page that lets you download the file as an attachment if you dont want to have it stored in salesforce at all. something along the lines of:
<apex:page contentType="img/jpg" extensions="xxx">{!image}</apex:page>
This is how i achieved, once saved to salesforce folder from there i downloaded the images, hope it helps someone.
Matcher imgMatcher = Pattern.compile( '<img(.+?)>' ).matcher(con.Photo__c);
String imageURL = imageTag.substringBetween( ' src="', '"' );
String decodedURL = imageURL.unescapeHtml4();
PageReference page = new PageReference( decodedURL );
Blob bodyBlob = page.getContent();
Document doc=new Document();
doc.Body=bodyBlob;
doc.FolderId='salesforce folder Id';
doc.Name=con.name;
doc.Type='jpg';
Insert doc;
I have a JSON array of objects that is a result of a function in nodejs. I use json2xls to convert that to an excel file, and it downloads to the server (not in a public folder, and is formatted correctly in Excel).
I would like to send a response to the frontend with the json results (to display as a preview) and show a button they can click to download the xlsx file OR display the JSON results and automatically download the file.
But I can't get it, and I've tried so many things I'm going crazy.
My controller code (the part that creates the xls file):
var xls = json2xls(results,{});
var today = (new Date()).toDateString('yyyy-mm-dd');
var str = today.replace(/\s/g, '');
var fileName = "RumbleExport_"+ str +".xlsx";
var file = fs.writeFileSync(fileName,xls,'binary');
res.download('/home/ubuntu/workspace/'+file);
The frontend controller:
vm.exportData = function(day, event, division) {
console.log('Export registrations button pressed.', vm.export);
//send the search parameters to the backend to run checks
$http.post('/api/exportData', vm.export).then(function(response){
vm.results = response.data;
console.log("Results",response);
vm.exportMessage = "Found " + vm.results.length + " registrations.";
})
.catch(function(error){
vm.exportError = error.data;
});
};
The view:
//display a button to download the export file
<a target="_self" file="{{vm.results}}" download="{{vm.results}}">Download Export File</a>
Someone please put me out of my misery. All the classes I've taken and none have covered this.
I FINALLY got it! And since I searched forever trying to make something work, I'll share the answer:
On the backend:
//save the file to the public/exports folder
var file = fs.writeFileSync('./public/exports/'+fileName,xls,'binary');
//send the results to the frontend
res.json(200).json({results:results, fileName: fileName});
On the frontend, use HTML to download a link to the file:
<a href="exports/{{fileName}}" download>Save File</a>
For web browsers (such as Chrome, IE, or Firefox), when you select a file using a "Choose File" button, where does the file's data get stored?
The file name shows in the browser, but does the data of the file get stored anywhere or is just a link to the file put somewhere, such as in the browser or a temporary file?
To clarify: I want to know where the file's data get's stored BEFORE submitting. JUST after the file is selected from the client's PC an not anything else is done.
After you select a file. I believe the client (browser) just stores a reference to the file location on the user's computer. It takes a combination of js and html to post the file to the server. Via a Multi/form-data Post.
In this case, on the server, you may have to store the file to a temp location of your choosing, until you're able to process it (i.e. transform and/or store to a Datastore).
In newer browsers you can use the FormData object and xhr to post to the server which is a lot cleaner.
This FormData object is used to construct the key/value pairs which form the data payload for the xhr request.
// Create a new FormData object.
var formData = new FormData();
In this case, once the file bytes are posted to the server, you can do whatever you want with that data. Typically I'll store it as a blob in the DB.
This approach will allow you to keep it all in memory. People make the mistake of trying to store on the server file system. In some multipart form post, you might have to do it this way, however.
Here's some of my web api upload code when using XHR.
I've also called this API route using an iframe (ugh!) in order to support IE8 and older. POS browsers!
/// <summary>
/// Upload the facility logo.
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("logo")]
public HttpResponseMessage Logo()
{
int newImageId = -1;
var uploadedFiles = HttpContext.Current.Request.Files;
if (uploadedFiles.Count > 0)
{
var file = uploadedFiles[0];
if (!file.IsImage())
{
// "The uploaded file must be a .jpg, .jpeg, or .png"
return
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType,
"unsupported");
}
var facilityRepository = new FacilityRepository();
var logoBytes =
StreamCopier.StreamToByteArray(file.InputStream, file.ContentLength);
newImageId = facilityRepository.InsertLogoImage(logoBytes);
}
return Request.CreateResponse(HttpStatusCode.OK,
newImageId);
}
I'm uploading a file that is a zip in a web app and passing it as type "Part" and I need to grab the name of the file that I originally uploaded. I can't seem to figure out for the life of me how to grab the actual name of the uploaded file. I've tried the following assuming my Part is uploaded with the original file name as "ABCD". My Part object will be named "file":
file.getHeaderNames() yields "content-type" and "content-disposition"
file.getName() yields "BPzip8237267963573706108tmp" which is the temp file's name
Any ideas on how I would go about doing this?
// define variable for file name
String filename = "";
// get part
Part file = request.getPart("file");
// get filename from part header
for (String s: file.getHeader("content-disposition").split(";")) {
if (s.trim().startsWith("filename")) {
filename = s.split("=")[1].replace("\"", "");
break;
}
}