I am writing a C++/CLI program using Visual Studio 2008 with .NET version 3.5.
This program receives data from a COM port. If the string received is not in certain format, the program will output an error message with the line to a log file.
One of the requirement is that the computer operator may come in and check the log file.
Here is my program (sort of):
FileStream ^ fs = File::Create("erorr-log.txt");
StreamWriter ^ sw = gcnew StreamWriter(fs);
// while receiving data from COM port
// if data is not in expected format
sw->WriteLine("Error in received data");
sw->WriteLine(received_string_data_from_port);
sw->Flush();
sw->Close();
After the execution of Flush, if I check the file size of log file, it remains the same. I cannot open it in Notepad neither.
After the execution of Close, the file size changes and can be open in Notepad.
Question: Why the content is not available after Flush? Shouldn't Flush immediately 'update' the file? As in the last line in Log () in How to: Open and Append to a Log File?
FileStream ^ fs = File::Create("erorr-log.txt");
File::Create() is a convenience method, it picks a lot of defaults to construct the FileStream. Defaults that you don't like, it uses FileShare::None. That's a very safe choice, nobody will see a partially written file. But prevents anybody from accessing the file until it is closed.
The simple workaround here is to not use it at all. But use the StreamWriter(String) constructor instead. Which also picks defaults, but it uses FileShare::Read. Which you like. A more reasonable safe choice for that class since it writes text streams and automatically flushes, unlike a FileStream.
Related
I am using CGI DSPSTMF command to display stmf file on web browser. I am copying a spool file to a stmf file using CPYSPLF *STMF option. Once copied i am passing IFS location to DSPSTMF command but it is going to download automatically and when i open the download file i am getting all Junk data any idea why?
Also, i noticed it is using CONTTYPES file in CGILIB and on my server it is empty. What should be the values in it and what should i do show correct data instead of junk. I tried to use different methods to copy the file to IFS like used cpytostmf instead of cpysplf but on IFS file looks correct not the download version.
What CCSID is the resulting stream file tagged with?
use WRKLNK and option 8=Display attributes
If 65535, that tells the system the data is binary and it won't try to translate the EBCDIC to ASCII.
The correct fix is to properly configure your IBM i so that the stream file is tagged with it's correct CCSID.
Do a WRKSYSVAL QCCSID ... if your system is still set to 65535, that's the start of your problem. But this isn't programming related, you can try posting to Server Fault but you might get better responses on the Midrange mailing list
I am developing an application in .NET Compact Framework 3.5, for Windows CE 6. I need to automate some data synchronization between the mobile application and a PC. So what I do is that, in the .NETCF application, I have a while loop that checks every few seconds, using System.IO.File.Exists(fullFilePath), whether the file I am expecting has been copied from the PC to the mobile device, through an ActiveSync connection.
Once the mobile app finds the file, it will open and read it using a StreamReader.
My problem is that, some times, File.Exists(fullFilePath) would return true, yet the subsequent use of StreamReader may fail with a FileNotFoundException.
Ruling out the possibility of the file getting deleted between the call to File.Exists() and the instantiation of the StreamReader, would anybody know how the exception may occur? Is it because file copy through ActiveSync is not atomic, such that the file is not actually ready for reading even though File.Exists() returns true?
A file copy is most certainly not going to be atomic. When you start the copy, the file is created, but has no data in it. As the file data gets written, the file "exists", but is not yet fully complete. You'd want to know not only that it exists, but that it's not currently in use (meaning the writer is done). Trying to open it exclusively would verify that.
I am trying to watch files in a directory to determine when files are opened/accessed. I thought FileSystemWatcher would do the trick using the event Changed.
Problem is that some applications do not create a lock on the file they open/access or change either the date modified or date accessed (even after fsutil behavior set disablelastaccess 0). Notepad for example. Apparently is makes a copy of the file in memory and plays with it there until you save it. Nor does it update the Date Accessed.
How can I monitor a directory of files and be notified when a file is simply opened/accessed by any program (e.g. Notepad)? Files may be opened from another computer, not necessarily on the computer running the "watcher".
I found lots of similar questions but did not see one focusing on file "access".
This is quite normal. Updating an existing file is quite dangerous since it can cause irretrievable data loss. A disk error (like disk full) while writing is very bad news. The common algorithm used:
rename the original file
write a new file using the original name
no error: delete the renamed file
error: delete the new file, rename original file back
Clearly this doesn't cause a Changed event to be raised, no file was changed.
Sorry, I didn't read the question well enough. There is no notification whatsoever for an app just opening a file for reading. FSW can only detect changes to the file system. There is no ready alternative either, this requires a custom file system filter driver that snoops on driver requests. Like the kind that SysInternals' ProcMon utility uses. I'm not aware of such a driver ready for use in a C# program, you can't write them in C# either. This just isn't a common requirement.
I want to upload a file to a ftp server programmatically (C++). If the connection is lost while uploading a file, I wouldn't want to upload the file from scratch, but to upload only the part that I haven't sent.
Does the APPE command fulfill my demand? What list of FTP commands should I use exactly? And how?
I am googling details about APPE FTP command, what actually it does but most site just state only append. Then I try out the command to make sure it behave as expected.
I designing FTP auto sender that is used to send a log file from a machine to a server for reporting. I only want to send the last line of the log file.
When using a APPE command, it actually append the whole file content and append to the existing one in the server. This will cause the line entry duplicated.
The answer:
To do the resume of file if the last transfer is failed, there is no such command for that, but we need to use a sequence of command to achieve it.
The key point here is seek your local file to the last uploaded byte if you are using APPE command or using command REST. REST will start transfer on that particular byte start position. I end-up with this solution to perform after connection established:
Use APPE (I got the idea from FileZilla log):
Use SIZE to check for file exist and use it as resume marker.
Open local file system and seek on the marker.
Use APPE to upload and FTP server will append it automatically.
Use STOR with REST (I got the idea from edtFTPnet):
Use SIZE to check for file exist and use it as resume marker.
Send REST with the result you get from SIZE to tell FTP server to start write on the position.
Open local file system and seek on the marker.
Use STOR as normal upload.
Note that not all FTP server support for both way. I see FileZilla switch this two way depending on the server. My observation shows that using REST is the standard way. Download can also use REST to start download on the given byte position.
Remember that using resume support for ASCII transfer type will produce unexpected result since Unix and Windows have different line break byte count.
Try to manipulate FileZilla to see the behave in the log.
You can also check this useful open source FTP for .NET library on how they do it.
edtFTPnet
Check the RFC and specifically the APPEND command:
This
command causes the server-DTP to
accept the data transferred via the
data connection and to store the data
in a file at the server site. If the
file specified in the pathname exists
at the server site, then the data
shall be appended to that file;
otherwise the file specified in the
pathname shall be created at the
server site.
Note that you cannot simply APPEND the same file again. You should send the bytes remaining. That is, continue at the same position when the connection was lost.
I'm working with a GPS module that is transferring data to my mac over a serial RS232-to-USB interface. I've written a objC program that takes the raw data and converts it into meaningful information.
Using a program called goSerial, I'm able to log all incoming data into a text file. I have been able to make my program read the text file and process data line by line.
I would like this procedure to happen in real time i.e. as soon as the data is received, it gets logged into the text file and my program reads it. The first part of this happens automatically that is the text file is being constantly appended (when not open). Is it possible to monitor a text file for appended data and only read new lines? Also, will doing this affect the ability of new incoming data to be saved?
Thanks!!!
(Also, if anyone knows how I may send serial data directly to Xcode, please let me know!)
I'm not sure how the serial-to-USB affects things but traditionally, unix accesses serial devices using the Device-File Mechanism which treats the input from the device as a file to be read. You would use NSFileHandle to read the file from Cocoa/Foundation. You probably want to checkout the IORegistryExplorer app to see how your device shows up.
You can use a kqueue (perhaps with a wrapper such as UKKQueue) to watch the file for changes.
You should be able to create a unix domain socket, which you can then have your goSerial application open (as it looks like a normal file on the fs)
And then read from the other end, linewise in your application. This is probably the easiest way, or alternately have a look at the source of tail in GNU's coreutils, specifically it's -f function (although thinking more you'll probably want to look at how the FreeBSD implementation works, as I believe that the GNU version uses some linux specific callback)