I'm using jdk7's WatchService API for monitoring the folder on file system.I'm sending a new file through
email to that folder, when the file comes into that folder i m triggering the ENTRY_CRATE option. its working fine.
But the issue is its generating two events of ENTRY_CREATE instead of one event which i'm invoking.
BELOW IS THE CODE:
Path dir = Paths.get(/var/mail);
WatchService watcher = dir.getFileSystem().newWatchService();
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
System.out.println("waiting for new file");
WatchKey watckKey = watcher.take();
List<WatchEvent<?>> events = watckKey.pollEvents();
System.out.println(events.size());
for(WatchEvent<?> event : events){
if(event.kind() == StandardWatchEventKinds.ENTRY_CREATE){
String fileCreated=event.context().toString().trim();
}
}
In the above code I'm gettng the events size as 2.
Can any one please help me in finding out the reason why i'm getting two events.
I am guessing that there might be some temporary files being created in the folder at the same time. Just check what are the name/paths of the file being created.
Related
My project has this requirement where user uploads a CSV file which has to be pushed to sql server database.
I know we can use Spring batch to process large number of records. But I'm not able to find any tutorial/sample code for this requirement of mine.
All the tutorials which I came across just hardcoded the CSV file name and in-memory databases in it like below:
https://spring.io/guides/gs/batch-processing/
User Input file is available in shared drive location on schduled time with file name prefix as eg: stack_overlfow_dd-MM-yyyy HH:mm, on daily basis how can I poll the Network shared drive for every 5-10 minutes atleast for one hour daily if its matches with regex then upload to database.
How can I take the csv file first from shared location and store it in memory or somewhere and then configure spring batch to read that as input.
any help here would be appreciated. Thanks In advance
All the tutorials which I came across just hardcoded the CSV file name and in-memory databases
You can find samples in the official repo here. Here is an example where the input file name is not hardcoded but passed as a job parameter.
How can I take the csv file first from shared location and store it in memory or somewhere and then configure spring batch to read that as input.
You can proceed in two steps: download the file locally then read/process/write it to the database (See https://stackoverflow.com/a/52110781/5019386).
how can I poll the Network shared drive for every 5-10 minutes atleast for one hour daily if its matches with regex then upload to database.
Once you have defined your job, you can schedule it to run when you want using:
a scheduler like Quartz
or using Spring's task scheduling features.
or using a combination of Spring Integration and Spring Batch. Spring integration would poll the directory and then launches a Spring Batch job when appropriate. This approach is described here.
More details on job scheduling here.
You can make a service layer that can process excel file and read data from file and construct java object to save into DB. Here I have used apache POI to parse Excel data and read from excel sheet.
public class FileUploadService {
#Autowired
FileUploadDao fileUploadDao;
public String uploadFileData(String inputFilePath) {
Workbook workbook = null;
Sheet sheet = null;
try {
workbook = getWorkBook(new File(inputFilePath));
sheet = workbook.getSheetAt(0);
/*Build the header portion of the Output File*/
String headerDetails = "EmployeeId,EmployeeName,Address,Country";
String headerNames[] = headerDetails.split(",");
/*Read and process each Row*/
ArrayList < ExcelTemplateVO > employeeList = new ArrayList < > ();
Iterator < Row > rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
//Read and process each column in row
ExcelTemplateVO excelTemplateVO = new ExcelTemplateVO();
int count = 0;
while (count < headerNames.length) {
String methodName = "set" + headerNames[count];
String inputCellValue = getCellValueBasedOnCellType(row, count++);
setValueIntoObject(excelTemplateVO, ExcelTemplateVO.class, methodName, "java.lang.String", inputCellValue);
}
employeeList.add(excelTemplateVO);
}
fileUploadDao.saveFileDataInDB(employeeList);
} catch (Exception ex) {
ex.printStackTrace();
}
return "Success";
}
I believe your question have already been answered here.
The author of the question has even uploaded a repository of his working result :
https://github.com/PriyankaBolisetty/SpringBatchUploadCSVFileToDatabase/tree/master/src/main/java/springbatch_example
You can retrieve and filter files' lists in a shared drive using JCIFS API method SmbFile.listFiles(String wildcard).
I'm trying to allow users to upload photos to the server and then view them (all users can view all photos) in production (NOT development). While in development mode everything is simple - I can upload the files to the public folder and then read then from there, in production mode I don't have access to the public folder anymore (as this approach is for static accesses and not dynamic).
So, I have 2 issues:
Upload: currently I can't understand how to save the uploaded photos to a specific folder, without using an absolute path to the location where I want the photos to be saved.
Here is the code for upload (similarly to this guide - https://www.playframework.com/documentation/2.4.x/ScalaFileUpload):
def uploadPhoto = Action(parse.multipartFormData) { request =>
import play.api.mvc.MultipartFormData
import play.api.libs.Files.TemporaryFile
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
try {
val multipartForm: MultipartFormData[TemporaryFile] = request.body
val pathDev: Path = Paths.get("./public/img");
val pathProduction: Path = Paths.get("/...<[full path]>.../public/img");
val imgPath =
if (Files.exists(pathDev)) { pathDev.toString() }
else { pathProduction.toString() }
val newFile = img.get.ref.moveTo(new File(s"$imgPath/$imgName"))
// [HERE I save the path to my DB]
Ok(Json.obj("imgName" -> imgName))
} catch {
case e: Exception =>
BadRequest("unknown error")
}
}
It is unclear to me how to serve the uploaded images back to users that want to see them.
I want to dynamically change the scr in the img html tag to show the relevant image, like so: $("#img").attr("src",'assets/img/1.jpg');
But as the public folder is not available, the images are "not there" (at least until I will "stage" the project and re-run it - https://www.playframework.com/documentation/2.4.x/Assets).
I tried the following approach (https://www.playframework.com/documentation/2.4.x/ScalaStream):
I have added the following line to my conf/routes file:
GET /img/:filename controllers.MyController.getPhoto(filename)
and defined the following function in the controller:
def getPhoto(filename: String) = Action {
Ok.sendFile(new java.io.File("./img/" + filename))
}
But the browser is downloading the file instead of showing it...
These are related:
Handling dynamic created files in play 2
How to serve uploaded files in Play!2 using Scala?
Any assistance will be very appropriated.
Here's how I fix this
ISSUE 1
For upload file path, in play you can define configurations in conf/application.conf file, and you can use different file for production mode, using -Dconfig.file=/path/to/the/file.
So I defined an attribuite called myapp.image.base, in debug mode just set it to "", and in production mode (I created a file called conf/application.prod.conf) , I put an absolute path to it.
So in my code, I always use the following command for file path (it's in Java, but you should find a similar way in Scala for reading configuration)
Play.application().configuration().getString("myapp.image.base")+"img"
ISSUE 2
For serving image
You need to create a router.
First in your routes file, add something like this:
GET /user/images/:name controllers.Application.imageAt(name:String)
And write a simple file reader in action imageAt which return the file in stream. Again my sample is in Java but you should archive the same using Scala
File imageFile = new File(ReportFileHelper.getImagePath());
if (imageFile.exists()) {
//resource type such as image+png, image+jpg
String resourceType = "image+"+imageName.substring(imageName.length()-3);
return ok(new FileInputStream(imageFile)).as(resourceType);
} else {
return notFound(imageFile.getAbsoluteFile());
}
After that, the images is reachable from url /user/images/
Play reads files off the classpath (which includes the assets directory). On the JVM, the classpath is immutable—once started, files added to folders on the classpath will not actually be added to the classpath.
This works in development mode because Play reloads the classpath whenever it detects a change. That same hot-reloading is not enabled in production (for good reason).
I m tryin to make metro Media Player ,but I have a problem in file activation i.e when I open mp3 file from Windows explorer, it open my app But Doesn,t get Arguments, how can I get file or name of file in text block for which my app is launched,i saw many methods in different Websites,But I can't Solve,
here is a really good explanation on how to do this:
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh779669.aspx
you can get the file name and file size here:
protected override void OnFileActivated(FileActivatedEventArgs args)
{
// TODO: Handle file activation
// The number of files received is args.Files.Size
// The first file is args.Files[0].Name
}
If the file is uploading with the name already in the specified path, it is showing error. I want to replace with the new file. I have placed the error and the code. Please help to replace the existing image.
Error: The process cannot access the file '' because it is being used by another process.
Code:
[HttpPost]
public ActionResult MyUpload(HttpPostedFileBase file)
{
string filePath = string.Empty;
string path = "C:\\";
string filePath = string.Empty;
try
{
if (file != null && file.ContentLength > 0)
{
filePath = path + file.FileName;
file.SaveAs(filePath);
file.InputStream.Dispose();
GC.Collect();
// other operations, where can occur an exception
// (because the uploaded file can have a bad content etc.)
}
}
catch (Exception e)
{
}
}
Based upon what you posted, I would suggest the following:
[HttpPost]
public ActionResult Foo(HttpPostedFileBase file)
{
var path = #"C:\";
var filename = file.FileName;
file.SaveAs(System.IO.Path.Combine(path, filename));
// do stuff here.
return RedirectToAction("Index");
}
I had this very same issue. I had a sub-folder called "files" where I uploaded files using file.SaveAs() ('file' being of type 'HttpPostedFileBase' [using MVC]). After some local investigation and online research, it turns out that an IIS worker thread/process was locking my file. At first I thought {HttpPostedFileBase}.SaveAs() was somehow locking my file. I even tried to (first) close, and then dispose the {HttpPostedFileBase}.InputStream, and that also didn't help. In the end, it wasn't even related to the file upload process at all. After uploading the file (a PDF), I processed it using ITextSharp, but forgot to dispose of the object wrapper (so it was probably sitting in the GC). Because of that, the next file upload failed due to the locked existing file. BTW, I also tried file.InputStream.Dispose(); file.InputStream.Close(); GC.Collect();, but removed them all in the end, and it still works perfectly now. Bottom line, if an IIS Worker process is locking your file, there's probably a good reason - something somewhere in your code you are missing, and it most likely isn't the MVC framework or IIS itself gone rogue. ;) Also, as it turns out, {HttpPostedFileBase}.SaveAs() WILL overwrite files if they exist, so there's no need to delete them first.
One other tip: I read somewhere to watch out who is creating the files based on how your authorization is setup (whether or not you using an IIS process identity, or the logged-in user identity). In some cases, a file may be created by one logged in user, who then becomes the owner, and another file of the same name from a different user may become blocked; might be something to keep in mind in special cases (like intranet based web apps).
I am using the watcher service and it works great. I need to only watch for files with a certain extension, e.g. .xml. How can I implement this?
Thanks.
It appears that there is no built-in file extension filter (like there is using the old java.io.FileFilter interface). I solved this same issue by adding an "if" statement in my processing code like so:
// Watcher gives key and you get event...
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path file = dir.resolve(ev.context());
if (isCorrectFileType(file)) {
// Do you processing here.
}
And the simple check:
private boolean isCorrectFileType(Path file) {
return (file.toString().endsWith(".xml"));
}