2012-01-06 23 views
7

Potrzebuję dodać dodatkowe informacje o zapytaniu do ścieżki pliku jako parametr zapytania , aby przeanalizować ścieżkę później podczas przetwarzania plików. Chociaż klasa System.Uri może mi w tym pomóc, ale wygląda na to, że nie daje mi tego, czego oczekiwałem w przypadku lokalnych ścieżek plików.Dlaczego System.Uri nie rozpoznaje parametru zapytania dla ścieżki pliku lokalnego?

var fileUri = new Uri("file:///c://a.txt?select=10") 
// fileUri.AbsoluteUri = "file:///c://a.txt%3Fselect=10" 
// fileUri.Query = "" 

var httpUri = new Uri("http://someAddress/a.txt?select=10") 
// httpUri.AbsoluteUri = "http://someaddress/a.txt?select=10" 
// httpUri.Query = "?select=10" 

W przypadku "ftp: //someAddress/a.txt select = 10" - ciąg kwerendy jest pusty

Rozumiem, że System.Uri prawdopodobnie rozwiązuje "się. txt? select = 10 "aby poprawić nazwę pliku" a.txt% 3Fselect = 10 ", ale DLACZEGO - jak uciec?

Dzięki z góry

+1

@Oded Ponieważ są one Uris. A Uris ma parametry. – ordag

+0

@ordag - Chodzi mi o to, że serwery FTP i system operacyjny nie wykonają _annych _ z tymi parametrami. – Oded

+2

@Oded To prawda, są one jednak ważne. A autor chce sam przetworzyć te parametry w późniejszym przetwarzaniu. – ordag

Odpowiedz

8

Jest to błąd, który Microsoft nie będzie naprawić: Bug 594562 Jak widać proponują refleksję jako obejście:

... 
Console.WriteLine("Before"); 
Uri fileUri = new Uri("file://host/path/file?query#fragment"); 
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri); 
Console.WriteLine("ToString: " + fileUri.ToString()); 
Console.WriteLine("LocalPath: " + fileUri.LocalPath); 
Console.WriteLine("Query: " + fileUri.Query); 
Console.WriteLine("Fragment: " + fileUri.Fragment); 

Type uriParserType = typeof(UriParser); 
FieldInfo fileParserInfo = uriParserType.GetField("FileUri", BindingFlags.Static | BindingFlags.NonPublic); 
UriParser fileParser = (UriParser)fileParserInfo.GetValue(null); 
FieldInfo fileFlagsInfo = uriParserType.GetField("m_Flags", BindingFlags.NonPublic | BindingFlags.Instance); 
int fileFlags = (int)fileFlagsInfo.GetValue(fileParser); 
int mayHaveQuery = 0x20; 
fileFlags |= mayHaveQuery; 
fileFlagsInfo.SetValue(fileParser, fileFlags); 

Console.WriteLine(); 
Console.WriteLine("After"); 
fileUri = new Uri("file://host/path/file?query#fragment"); 
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri); 
Console.WriteLine("ToString: " + fileUri.ToString()); 
Console.WriteLine("LocalPath: " + fileUri.LocalPath); 
Console.WriteLine("Query: " + fileUri.Query); 
Console.WriteLine("Fragment: " + fileUri.Fragment); 
... 
+0

Dzięki - wtedy jest zrozumiałe, dlaczego nie działa zgodnie z oczekiwaniami – Vitaliy

5

parametry Zapytanie nie obowiązują w przypadku prośby o pliku lokalnego.

Gdy żądasz pliku za pomocą http plik jest wykonywany i dlatego jest w stanie odczytać i przetworzyć kwerendę. Gdy żądasz pliku lokalnego, nie jest on wykonywany i nie jest w stanie korzystać z kwerendy.

Jaki jest powód dodawania paramertów do żądania pliku? Czy jest inny sposób na zrobienie tego?

+0

Powodem, dla którego używam takiej konstrukcji, jest proste i zrozumiałe zapytanie - na przykład dostęp do plików * files * folder * txt * -" files /? select = *. txt ", dostęp do dziesiątego wiersz w pliku "file.txt? line = 10" – Vitaliy

+0

Masz na myśli to, że kiedy wołam konstruktora Uri - to naprawdę próbuje uzyskać dostęp do pliku? Pomyślałem, że robi tylko url parsowania na części - Rozumiem, że prawdopodobnie protokoły * ftp * i * file * nie mają zastosowania dla parametrów zapytania - a klasa Uri zapewnia pewne rozdzielanie ścieżek. Ale jak wspomniano w @ordag - są to Uris i Uris obsługują parametry zapytań – Vitaliy

+0

I znowu - podobne konstrukcje zapytań są używane w XSLT (na przykład z funkcją fn: collection) - dozwolone jest zapisanie po XPath "count (collection ('file: ///d:/collection/?select=*.xml ')) " – Vitaliy