Regular Expression for validating Windows-based file paths including UNC paths - regex

I wanted to validate a file name along with its full path. I tried certain Regular Expressions as below but none of them worked correctly.
^(?:[\w]\:|\\)(\\[a-z_\-\s0-9\.]+)+\.(txt|gif|pdf|doc|docx|xls|xlsx)$
and
^(([a-zA-Z]\:)|(\\))(\\{1}|((\\{1})[^\\]([^/:*?<>""|]*))+)$
etc...
My requirement is as mentioned below:
Lets say if the file name is "c:\Demo.txt" then it should check every possibilites like no double slash should be included(c:\\Demo\\demo.text) no extra colon like(c::\Demo\demo.text). Should accept UNC files like(\\staging\servers) and others validation as well. Please help. I am really stuck here.

Why are you not using the File class ?
Always use it !
File f = null;
string sPathToTest = "C:\Test.txt";
try{
f = new File(sPathToTest );
}catch(Exception e){
Console.WriteLine(string.Format("The file \"{0}\" is not a valid path, Error : {1}.", sPathToTest , e.Message);
}
MSDN : http://msdn.microsoft.com/en-gb/library/system.io.file%28v=vs.80%29.aspx
Maybe you're just looking for File.Exists ( http://msdn.microsoft.com/en-gb/library/system.io.file.exists%28v=vs.80%29.aspx )
Also take a look to the Path class ( http://msdn.microsoft.com/en-us/library/system.io.path.aspx )
The GetAbsolutePath could be one way to get what you want! ( http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx )
string sPathToTest = "C:\Test.txt";
string sAbsolutePath = "";
try{
sAbsolutePath = Path.GetAbsolutePath(sPathToTest);
if(!string.IsNullOrEmpty(sAbsolutePath)){
Console.WriteLine("Path valid");
}else{
Console.WriteLine("Bad path");
}
}catch(Exception e){
Console.WriteLine(string.Format("The file \"{0}\" is not a valid path, Error : {1}.", sPathToTest , e.Message);
}

If you are interested only in the filename part (and not the whole path because you get the file via upload) then you could try something like this:
string uploadedName = #"XX:\dem<<-***\demo.txt";
int pos = uploadedName.LastIndexOf("\\");
if(pos > -1)
uploadedName = uploadedName.Substring(pos+1);
var c = Path.GetInvalidFileNameChars();
if(uploadedName.IndexOfAny(c) != -1)
Console.WriteLine("Invalid name");
else
Console.WriteLine("Acceptable name");
This will avoid the use of Exceptions as method to drive the logic of your code.

Related

How to modify the filename of the S3 object uploaded using the Kafka Connect S3 Connector?

I've been using the S3 connector for a couple of weeks now, and I want to change the way the connector names each file. I am using the HourlyBasedPartition, so the path to each file is already enough for me to find each file, and I want the filenames to be something generic for all the files, like just 'Data.json.gzip' (with the respective path from the partitioner).
For example, I want to go from this:
<prefix>/<topic>/<HourlyBasedPartition>/<topic>+<kafkaPartition>+<startOffset>.<format>
To this:
<prefix>/<topic>/<HourlyBasedPartition>/Data.<format>
The objective of this is to only make one call to S3 to download the files later, instead of having to look for the filename first and then download it.
Searching through the files from the folder called 'kafka-connect-s3', I found this file:
https://github.com/confluentinc/kafka-connect-storage-cloud/blob/master/kafka-connect-s3/src/main/java/io/confluent/connect/s3/TopicPartitionWriter.java which at the end has some of the following functions:
private RecordWriter getWriter(SinkRecord record, String encodedPartition)
throws ConnectException {
if (writers.containsKey(encodedPartition)) {
return writers.get(encodedPartition);
}
String commitFilename = getCommitFilename(encodedPartition);
log.debug(
"Creating new writer encodedPartition='{}' filename='{}'",
encodedPartition,
commitFilename
);
RecordWriter writer = writerProvider.getRecordWriter(connectorConfig, commitFilename);
writers.put(encodedPartition, writer);
return writer;
}
private String getCommitFilename(String encodedPartition) {
String commitFile;
if (commitFiles.containsKey(encodedPartition)) {
commitFile = commitFiles.get(encodedPartition);
} else {
long startOffset = startOffsets.get(encodedPartition);
String prefix = getDirectoryPrefix(encodedPartition);
commitFile = fileKeyToCommit(prefix, startOffset);
commitFiles.put(encodedPartition, commitFile);
}
return commitFile;
}
private String fileKey(String topicsPrefix, String keyPrefix, String name) {
String suffix = keyPrefix + dirDelim + name;
return StringUtils.isNotBlank(topicsPrefix)
? topicsPrefix + dirDelim + suffix
: suffix;
}
private String fileKeyToCommit(String dirPrefix, long startOffset) {
String name = tp.topic()
+ fileDelim
+ tp.partition()
+ fileDelim
+ String.format(zeroPadOffsetFormat, startOffset)
+ extension;
return fileKey(topicsDir, dirPrefix, name);
}
I don't know if this can be customised to what I want to do but seems to be somehow near/related to my intentions. Hope it helps.
(Submitted an issue to Github as well: https://github.com/confluentinc/kafka-connect-storage-cloud/issues/369)

Read json with rapidjson pointer

Trying to integrate rapidjson into my app. Used to read a (validated with an online tool) simple config file like:
{
"filecontent": "appsettings",
"fileversion": 1,
"appsettings": {
"general": {
"sync": "false",
"sound": "true"
},
...
This is my code:
QString path = keypath( key ); //.prepend("/");
rapidjson::Value* hello = rapidjson::Pointer( "/appsettings/general/sound" ) //path.toStdString().c_str()
.Get(rapidJsonDoc_);
if ( hello ) {
QVariant retStr( hello->GetString() );
qDebug()<<"--> " <<path<<" --> " << retStr;
ret = QVariant::fromValue( retStr );
}else{
qDebug()<<"Value not found!";
}
return ret;
If I prepend the pointer string with /, as I understand the examples, it says value not found.
If I remove the slash, if (hello) is true, but does not return an expected value.
rapidJsonDoc_ is of type rapidjson::Document.
Please help me with the correct syntax. I am looking at the source code of rapidjson and can't understand a thing, it is so full of templates and complex signatures...
update:
according to this post modifying a Qt QJsonDocument is not possible like I want.

Drag & Drop Filename Visual (Managed) C++

I have a RichTextBox that I would like to allow a user to drag and drop a file from disk into. All that should appear in the textbox is the filename(s). This code currently adds "System.String[]" to the textbox instead of the filename. When I change the DataFormats::FileDrop to DataFormats::Text as this MSDN would seem to suggest, I get a NULL dereference error.
The RichTextBox name is rtbFile. In my constructor, I have:
this->rtbFile->AllowDrop = true;
I set up the events like this (within InitializeComponents):
this->rtbFile->DragEnter += gcnew System::Windows::Forms::DragEventHandler(this, &VanicheMain::rtbFile_DragEnter);
this->rtbFile->DragDrop += gcnew System::Windows::Forms::DragEventHandler(this, &VanicheMain::rtbFile_DragDrop);
The functions are defined as follows:
void rtbFile_DragEnter(System::Object ^sender, System::Windows::Forms::DragEventArgs ^ e) {
if (e->Data->GetDataPresent(DataFormats::FileDrop))
e->Effect = DragDropEffects::Copy;
else
e->Effect = DragDropEffects::None;
}
System::Void rtbFile_DragDrop(System::Object ^sender, System::Windows::Forms::DragEventArgs ^e){
int i = rtbFile->SelectionStart;;
String ^s = rtbFile->Text->Substring(i);
rtbFile->Text = rtbFile->Text->Substring(0, i);
String ^str = String::Concat(rtbFile->Text, e->Data->GetData(DataFormats::FileDrop)->ToString());
rtbFile->Text = String::Concat(str, s);
}
Dragging files always produces an array of strings. Each array element is the path to one of the files that are dragged. You'll need to write the extra code to cast the return value of GetData() to an array and iterate it, reading the content of each file. Similar to this:
array<String^>^ paths = safe_cast<array<String^>^>(e->Data->GetData(DataFormats::FileDrop));
for each (String^ path in paths) {
String^ ext = System::IO::Path::GetExtension(path)->ToLower();
if (ext == ".txt") rtbFile->AppendText(System::IO::File::ReadAllText(path));
}

Regex for get the path of file

I have code to display a name of file to a jtable. Here is the code :
StringBuilder nameOfComparedFile = new StringBuilder(); //
if (idLexerSelection != getIDLexer()) {
nameOfComparedFile.append(file.getCanonicalPath()); //
System.out.println(file.getCanonicalPath() + " )");
}
And then, in jtable is displayed like this : D:/Data/File.java
I dont wanna change getCanonicalPath, because on jtable that i Created will be using for next process. My question is : how to get just the name of file using regex
To get just the name:
file.getName()
If you absolutely must use regex:
String filename = file.getCanonicalPath().replaceAll(".*[\\\\/](.*)", "$1");

Populating a database with file names from directories

I have an application which behaves as a slideshow for all pictures in a folder. It is written in Borland's C++ Builder (9). It currently uses some borrowed code to throw the filenames into a listbox and save the listbox items as a text file.
I want to update this so that the filenames are stored in a proper database so that I can include extra fields and do proper SQL things with it.
So basically I would be able to work it out if I saw some 'sample' code doing the same thing.
So if anyone knows of any code that does this I would be greatful. It needs to be able to do it on certain file types... not just all the files.
You basically neeed to write a recursive function with a TDataSet parameter.
(I could not compile my code, so you get it "as is")
void AddFiles(AnsiString path, TDataSet *DataSet)
{
TSearchRec sr;
int f;
f = FindFirst(path+"\\*.*", faAnyFile, sr);
while( !f )
{
if(sr.Attr & faDirectory)
{
if(sr.Name != "." && sr.Name != "..")
{
path.sprintf("%s%s%s", path, "\\", sr.Name);
AddFiles(path, DataSet);
}
}
else
{
DataSet->Append();
DataSet->FieldByName("Name")->Value = sr.Name;
/* other fields ... */
DataSet->Post();
}
f = FindNext(sr);
}
FindClose(sr);
}