Mam dokument XML, który jest bardzo duży (około 120M) i nie chcę go załadować do pamięci naraz. Moim celem jest sprawdzenie, czy ten plik używa prawidłowego kodowania UTF-8.dekodowanie strumienia plików przy użyciu UTF-8
Wszelkie pomysły na szybką kontrolę bez czytania całego pliku do pamięci w postaci byte[]
?
Używam VSTS 2008 i C#.
Podczas ładowania dokumentu XML, który zawiera niepoprawne sekwencje bajtów, istnieje wyjątek, ale podczas odczytywania całej zawartości do tablicy bajtów, a następnie sprawdzania z UTF-8, nie ma wyjątków, żadnych pomysłów?
Oto zrzut ekranu pokazujący zawartość mojego pliku XML, czy można pobrać kopię pliku z here
EDIT 1:
class Program
{
public static byte[] RawReadingTest(string fileName)
{
byte[] buff = null;
try
{
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(fileName).Length;
buff = br.ReadBytes((int)numBytes);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return buff;
}
static void XMLTest()
{
try
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load("c:\\abc.xml");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void Main()
{
try
{
XMLTest();
Encoding ae = Encoding.GetEncoding("utf-8");
string filename = "c:\\abc.xml";
ae.GetString(RawReadingTest(filename));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return;
}
}
EDIT 2: Podczas korzystania z new UTF8Encoding(true, true)
pojawi się wyjątek, ale podczas korzystania z new UTF8Encoding(false, true)
, nie ma rzucony cepel. Jestem zdezorientowany, ponieważ powinien to być drugi parametr, który kontroluje, czy wyjątek jest zgłaszany (jeśli występują niepoprawne sekwencje bajtów), dlaczego pierwszy parametr ma znaczenie?
public static void TestTextReader2()
{
try
{
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader(
"c:\\a.xml",
new UTF8Encoding(true, true)
))
{
int bufferSize = 10 * 1024 * 1024; //could be anything
char[] buffer = new char[bufferSize];
// Read from the file until the end of the file is reached.
int actualsize = sr.Read(buffer, 0, bufferSize);
while (actualsize > 0)
{
actualsize = sr.Read(buffer, 0, bufferSize);
}
}
}
catch (Exception e)
{
// Let the user know what went wrong.
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
}
Nie jest prawie żadna sekwencja bajtów, nawet losowe wartości bajtów, poprawne UTF8? Czy są jakieś sekwencje wartości bajtów, które nie są poprawne w UTF8? – ChrisW
Nie wszystkie z nich, są pewne wyjątki, proszę zapoznać się tutaj, http://pl.wikipedia.org/wiki/UTF-8#Numer_zastosowania – George2
@ChrisW: Absolutnie nie; UTF-8 ma określone reguły kodowania. –