I have two file names in following format:
Gontagrator_1.xml
Gontagrator_2.xml
As of now i am picking just Gontagrater_1.xml and rename it to processing and failed once done.
+ "&fileName=" + sftpFileName
+ "&preMove="+sftpFileName+".$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.processing"
+ "&move="+sftpFileName+".$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}"
+ "&moveFailed="+sftpFileName+".$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.failed"
Now Gontagrator_2 comes into picture. It is suggested to create separate routes for both.
Can we download both in one route and rename accordingly? If yes, what values i need to pass?
Update1: There are multiple files with different names but i need to use both above file names only
update 2: Whole from component is:
"{{m.protocol}}://{{m.hostname}}{{t.directory}}"
+ "?username={{m.username}}"
+ "&password={{m.password}}"
+ "&download=true"
+ "&useList=false"
+ "&stepwise=false"
+ "&disconnect=true"
+ "&passiveMode=true"
+ "&reconnectDelay=10000"
+ "&bridgeErrorHandler=true"
+ "&delay=30000"
//+ "&fileName=" + sftpFileName
+ "&include="+ sftpFileName
+ "&preMove=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.processing"
+ "&move=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}"
+ "&moveFailed=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.failed"
+ "&readLock=idempotent-changed"
+ "&idempotentRepository=#infinispan"
+ "&readLockRemoveOnCommit=true")
.onException(GenericFileOperationFailedException.class)
.onWhen(exchange -> {
Throwable cause = exchange.getException(GenericFileOperationFailedException.class).getCause();
return (cause != null && cause.toString().equalsIgnoreCase("2: No such file"));
}).handled(true)
.logExhausted(true)
.logExhaustedMessageHistory(true)
.log("Could not find file")
.end()
.log("Downloading xml file")
//.to(archiveReceivedFile(sftpFileName))
.split(body().tokenizeXML("ERequest", "ERequests")).streaming()
.inOnly(E_QUEUE)
Yes, you can download all files in one route.
You need to
Remove fileName option (such that the route will pick all file)
Use file expression language (file:onlyname) to refer to filename currently handled by Camel SFTP component
+ "&preMove=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.processing"
+ "&move=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}"
+ "&moveFailed=$simple{file:onlyname}.$simple{date:now:yyyy-MM-dd'T'hh-mm-ss}.failed"
Use include option to control file to be picked up (REGEX to match file name pattern)
+ "&include=Gontagrator_(1|2)\.xml"
I have used kquque to monitor desktop with:
flags - EV_ADD | EV_CLEAR
fflags - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE
filter - EVFILT_VNODE
However when I edit a .js file on desktop with sublime2 software, it doesnt trigger a notification :(
Please advise
Here is my js-ctypes code:
var rez_fd = ostypes.API('kqueue')();
console.info('rez_fd:', rez_fd.toString(), uneval(rez_fd));
if (ctypes.errno != 0) {
throw new Error('Failed rez_fd, errno: ' + ctypes.errno);
}
this.kq = rez_fd;
this.path = OS.Constants.Path.desktopDir;
// Open a file descriptor for the file/directory that you want to monitor.
var event_fd = ostypes.API('open')(this.path, OS.Constants.libc.O_EVTONLY);
console.info('event_fd:', event_fd.toString(), uneval(event_fd));
if (ctypes.errno != 0) {
throw new Error('Failed event_fd, errno: ' + ctypes.errno);
}
// The address in user_data will be copied into a field in the event.If you are monitoring multiple files,you could,for example,pass in different data structure for each file.For this example,the path string is used.
var user_data = ctypes.cast(ctypes.char.array()(this.path), ctypes.void.ptr);
// Set the timeout to wake us every half second.
var timeout = ostypes.TYPE.timespec();
var useSec = 0;
var useNsec = 500000000;
timeout.tv_sec = useSec; // 0 seconds
timeout.tv_nsec = useNsec; // 500 milliseconds
// Set up a list of events to monitor.
var fflags = vnode_events = ostypes.CONST.NOTE_DELETE | ostypes.CONST.NOTE_WRITE | ostypes.CONST.NOTE_EXTEND | ostypes.CONST.NOTE_ATTRIB | ostypes.CONST.NOTE_LINK | ostypes.CONST.NOTE_RENAME | ostypes.CONST.NOTE_REVOKE; // ostypes.TYPE.unsigned_int
var events_to_monitor = ostypes.TYPE.kevent.array(ostypes.CONST.NUM_EVENT_FDS)();
var filter = ostypes.CONST.EVFILT_VNODE;
var flags = ostypes.CONST.EV_ADD | ostypes.CONST.EV_CLEAR;
EV_SET(events_to_monitor.addressOfElement(0), event_fd, filter, flags, fflags, 0, user_data);
// Handle events
var event_data = ostypes.TYPE.kevent.array(ostypes.CONST.NUM_EVENT_SLOTS)(); // 1 slot
var num_files = 1; // ostypes.TYPE.int
var continue_loop = 40; // Monitor for twenty seconds. // ostypes.TYPE.int
while (--continue_loop) {
var event_count = ostypes.API('kevent')(this.kq, ctypes.cast(events_to_monitor.address(), ostypes.TYPE.kevent.ptr), ostypes.CONST.NUM_EVENT_SLOTS, ctypes.cast(event_data.address(), ostypes.TYPE.kevent.ptr), num_files, timeout.address());
console.info('event_count:', event_count.toString(), uneval(event_count));
if (ctypes.errno != 0) {
throw new Error('Failed event_count, errno: ' + ctypes.errno + ' and event_count: ' + cutils.jscGetDeepest(event_count));
}
if (cutils.jscEqual(event_data.addressOfElement(0).contents.flags, ostypes.CONST.EV_ERROR)) {
throw new Error('Failed event_count, due to event_data.flags == EV_ERROR, errno: ' + ctypes.errno + ' and event_count: ' + cutils.jscGetDeepest(event_count));
}
if (!cutils.jscEqual(event_count, '0')) {
console.log('Event ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.ident) + ' occurred. Filter ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.filter) + ', flags ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.flags) + ', filter flags ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.fflags) + ', filter data ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.data) + ', path ' + cutils.jscGetDeepest(event_data.addressOfElement(0).contents.udata /*.contents.readString()*/ ));
} else {
// No event
}
// Reset the timeout. In case of a signal interrruption, the values may change.
timeout.tv_sec = useSec; // 0 seconds
timeout.tv_nsec = useNsec; // 500 milliseconds
}
ostypes.API('close')(event_fd);
I just realized that you're not monitoring the .js file, you're monitoring its directory. That makes everything a lot less mysterious.
The short version is: If you open a file and write it, that doesn't change anything on the directory. If you atomically save a file, that does change the directory, but Sublime 2 doesn't atomically save by default.
So, to watch for any changes to any file in the directory, you need to enumerate all files in the directory and add them all to the kqueue,* as well as the directory.
Watching the directory will catch atomic saves (and new files being created); watching the files will catch overwrites. (Files being unlinked will trigger both.) If you're worried about performance… well, kqueue is designed to handle switching on 10000 file descriptors, and neither UFS nor HFS+ is a good filesystem for hundreds of thousands of directory entries in the same directory, so you're probably OK… but you may want to add some code that warns or aborts if the directory turns out to be massively huge.
If you want to understand why this is necessary, you have to think about how the two different kinds of saves work.
A write just writes to a file descriptor. That file descriptor could have one directory entry link on the filesystem—but it could just as easily have none (e.g., it was created in a temporary namespace, or you just unlinked the file after creating it), or many (e.g., you've created hard links to it). So it can't actually update "the directory entry for the file", because there is no such thing.
An atomic save, on the other hand, works by creating a new temporary file, writing to that, and then rename-ing the temporary over the original file. That rename has to update the directory, replacing the entry pointing at the old file with an entry pointing at the new file. (Of course it also sends a DELETE notification for the file itself, because the file is losing a link. And you'll also usually sends an ATTRIB, because most apps want the new file to have the same extended attributes, extra forks, etc.)
* There is an obvious race condition here: if a file is moved or deleted between the readdir and adding it to the kqueue, you'll get an error. You may want to handle that error by generating an immediate notification, or maybe you just want to ignore it—after all, from the user perspective, it's not much different from the case where someone deletes a file between the time your program starts and the time you do the readdir.
This is my Python Program that I have been having some issues with:
-- coding: cp1252 --
from time import gmtime, strftime
print("Welcome to the PiggyBank version 1.")
num_write = int(input("How much money would you like to store in your PiggyBank?"))
f = open("PiggyBanks_Records.txt", "w")
current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
convert_1 = str(current_time)
convert_2 = str(int(num_write))
add_1 = ("\n" + convert_1 + " £" + convert_2)
add_2 = ("\n" + add_1) #Tried to make it so new line is added every time the program is run
final_record = str(add_2)
print("Final file written to the PiggyBank: " + final_record)
#Write to File
f.write(final_record)
f.close()
Right now whenever the program writes to the file it over-writes. I would preferably would like to keep, like a history of the amounts added. If anyone can help so the string that needs to be written to the .txt file goes down by one line and essentially keeps going for ever. I am also open to any suggestion on how I can shorten this code.
You need to open your file with append mode :
f = open("PiggyBanks_Records.txt", "a")
Using the 'w' write option with open automatically looks for the specified file, and deletes its contents if it already exists (which you can read about here) or creates it if it doesn't. Use 'a' instead to add / append to the file.
Hi all i've got a complex SSIS package, however i'm hitting my head against a brick wall with a particular part. I've got a maintenance part that will delete files that are older than 3 months old (from today's date). The files all have the date in the filename, for example AA-CDR-20110606030000-2-001A648E6F74-026874.xml
So i've written a task that will loop over all the files in a particular folder using a Foreach loop, then i have a script that will load in the filename using a variable set using the foreach loop. Then delete the file using the script below. This works fine when running in debug mode. However when trying to execute this on the server i get a failure with a "System.FormatException: String was not recognized as a valid DateTime.". I really dont understand why, any ideas?
DateTime deleteDate = DateTime.Today.AddMonths(-3);
String file = Dts.Variables["FileName"].Value.ToString();
String fileDateString = file.Substring(42, 8);
String fileDateYear = fileDateString.Substring(0, 4);
String fileDateMonth = fileDateString.Substring(4, 2);
String fileDateDay = fileDateString.Substring(6, 2);
DateTime fileDateTime = Convert.ToDateTime(fileDateDay + "-" + fileDateMonth + "-" + fileDateYear);
if (fileDateTime < deleteDate)
{
System.IO.File.Delete(file);
}
It seems that there is a file on the production server that does not follow the pattern and the date cannot be extracted from its name.
Try to use something like this:
try
{
DateTime fileDateTime = Convert.ToDateTime(fileDateDay + "-" + fileDateMonth + "-" + fileDateYear);
if (fileDateTime < deleteDate)
{
System.IO.File.Delete(file);
}
}
catch (System.FormatException)
{
// log the Dts.Variables["FileName"] value here to see why it could not be parsed
}
I'm running a script made in Groovy from Soap UI and the script needs to generate lots of files.
Those files have also in the name two numbers from a list (all the combinations in that list are different), and there are 1303 combinations
available and the script generates just 1235 files.
A part of the code is:
filename = groovyUtils.projectPath + "\\" + "$file"+"_OK.txt";
targetFile = new File(filename);
targetFile.createNewFile();
where $file is actually that part of the file name which include those 2 combinations from that list:
file = "abc" + "-$firstNumer"+"_$secondNumber"
For those file which are not created is a message returned:"The filename, directory name or volume label syntax is incorrect".
I've tried puting another path:
filename = "D:\\rez\\" + "\\" + "$file"+"_OK.txt";
targetFile = new File(filename);
targetFile.createNewFile();
and also:
File parentFolder = new File("D:\\rez\\");
File targetFile = new File(parentFolder, "$file"+"_OK.txt");
targetFile.createNewFile();
(which I've found here: What are possible reasons for java.io.IOException: "The filename, directory name, or volume label syntax is incorrect")
but nothing worked.
I have no ideea where the problem is. Is strange that 1235 files are created ok, and the rest of them, 68 aren't created at all.
Thanks,
My guess is that some of the files have illegal characters in their paths. Exactly which characters are illegal is platform specific, e.g. on Windows they are
\ / : * ? " < > |
Why don't you log the full path of the file before targetFile.createNewFile(); is called and also log whether this method succeeded or not, e.g.
filename = groovyUtils.projectPath + "\\" + "$file"+"_OK.txt";
targetFile = new File(filename);
println "attempting to create file: $targetFile"
if (targetFile.createNewFile()) {
println "Successfully created file $targetFile"
} else {
println "Failed to create file $targetFile"
}
When the process is finished, check the logs and I suspect you'll see a common pattern in the ""Failed to create file...." messages
File.createNewFile() returns false when a file or directory with that name already exists. In all other failure cases (security, I/O) it throws an exception.
Evaluate createNewFile()'s return value or, additionally, use the File.exists() method:
File file = new File("foo")
// works the first time
createNewFile(file)
// prints an error message
createNewFile(file)
void createNewFile(File file) {
if (!file.createNewFile()) {
assert file.exists()
println file.getPath() + " already exists."
}
}