Odczyt pliku "niszczy" jego zawartość

0

Witam,

piszę aplikację i mam taki problem, że po wczytaniu pliku, którego zawartość poprzez funkcję print w pythone prezentuje się w ten sposób - czyli tak, jak powinno to wyglądać:
https://preview.ibb.co/ehVXwJ/1.jpg

w C# wygląda następująco:
https://image.ibb.co/gCnUbJ/1.jpg

Kod dotyczący odczytu w c# wygląda tak:

OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = false;
ofd.ShowDialog();
content = System.IO.File.ReadAllText(ofd.FileName);

A pythonie:

with open(filename_in, 'rb') as f:
content = f.read()
print(content)

Proszę o pomoc!

0

W Pythonie powinieneś odczytywać plik tekstowy nie jako "rb", tylko "r".

W C# sam nie wiem... próbowałeś według MSDN? https://msdn.microsoft.com/pl-pl/library/system.windows.forms.openfiledialog(v=vs.110).aspx
Tylko, że zamiast czystego streamu z dialogu użyj na nim stream reader:

            using (StreamReader sr = new StreamReader(myStream)) 
            {
                Console.WriteLine(sr.ReadToEnd());
            }

Czy ten plik na pewno jest tekstowy?

2

@Effy_: zobacz jakiego kodowania używa python przy zapisie do pliku (sys.getdefaultencoding() - lub sprawdź w programie w którym stworzyłeś plik) i przekaż podobną wartość w C# (np. Encoding.UTF8). Bez podawania kodowania to jest kwestia szczęścia czy Twój plik zostanie odczytany tak jak chcesz.

Kolejna rzecz do sprawdzenia to czy w pliku jest fizycznie bajt 0xff czy tekst \xff - jeśli bajt, to prawdopodobnie powinieneś czytać używając ReadAllBytes i wypisywać je kolejno używając np.: mojBajt.ToString("X2").

0

   byte[] array = File.ReadAllBytes(ofd.FileName);
            for(int i=0; i<array.Length-1; i++)
            {
                content = content + array[i].ToString("X2"); 
            }

Teraz już wyświetla 'prawie' poprawnie, ale robi to bardzo powolnie. Jak to zoptymalizować? Wolałabym, żeby ten plik był w takiej formie, żeby mógłby potem podmienić część pliku, wyszukując taki ciąg "\x01\x01\x00\x0c;\r".

Generalnie mój program powinien wyszukiwać ciąg i podmieniać go na inny. Jednak jest taki problem, że zamiast wybranego ciągu podmienia mi prawie cały plik.

a = "\x01\x01\x00\x0c;\r";
b = "\x00\x01\x00\x0c;\r";
.....
if (content.Contains(a))
            {
             
                newContent = content.Replace(a, b);
              
                isChanged = true;
               
                using (TextWriter tw = new StreamWriter(ofd.FileName + "NEW"))
                {
                    tw.WriteLine(newContent);
                    tw.Close();
                }
                MessageBox.Show("Nowy plik został zapisany w "+ofd.FileName+"NEW");
}
1

Możesz wrzucić zawartość tego pliku?

1

Mi się coś wydaje, że to nie jest plik tekstowy tylko binarny. Dlatego masz takie problemy. Użyj MemoryStream i odczytaj ten plik do tego. Następnie baw się w memoryStream. Tu masz prosty przykład na to: https://codereview.stackexchange.com/questions/136419/replace-eol-in-stream

0

To plik binarny. Tutaj zamieszczam link do niego: http://www.rapidshare.com.cn/IisKAvP

Juhas, dzięki, spróbuję.

0
 byte[] buffer;
             FileStream fs;
             using (fs = File.OpenRead(ofd.FileName))
             {
                 int length = (int)fs.Length;


                 using (BinaryReader br = new BinaryReader(fs))
                 {
                     buffer = br.ReadBytes(length);
                 }
             }
            content = System.Text.Encoding.Default.GetString(buffer);

Zrobiłam to i w ten sposób, jednak cały plik jest nadal zniekształcany - już nie chodzi o wypisanie na konsoli, czy gdziekolwiek. Nie zmieniając jego zawartości metodą Replace(), odczytując go za pomocą programu w pythonie, plik ma zupełnie inną zawartość, mimo, że jest to ten sam plik.

https://ibb.co/njAsWJ

MemoryStream ms = new MemoryStream();
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                byte[] barr = encoding.GetBytes(newContent);


                ms.Write(barr, 0, barr.Length);

                using (FileStream fs1 = new FileStream(ofd.FileName+"NEW", FileMode.OpenOrCreate))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs1))
                    {
                        bw.Write(ms.ToArray());
                    }
                }

Zmieniłam też zapis. Lecz bez zmian, dalej zepsuty plik.

0

Najwolniejsza część w Twoim kodzie to content = content + ..., spróbuj użyć StringBuilder. np.:

var sb = new StringBuilder();
sb.Append(foo.ToString("X2"));
...
string content = sb.ToString();

druga opcja jest taka, żeby wypisywać bezpośrednio do konsoli i nie robić żadnych stringów po drodze (powinno być nawet szybsze).

Jeśli dalej jest za wolne to foo.ToString("X2") możesz ręcznie przekonwertować na hex tak żeby nie tworzyć po drodze stringa (nie optymalizuj nic póki nie trzeba)

Jeśli dalej jest za wolne lub plik jest duży to zamień ReadAllBytes na MemoryStream (wydaje mi się, że StringBuilder powinien wystarczyć)

0

Czy możesz wydzielić małe próbki tych plików i zamieścić tutaj? Ja cały czas nie jestem pewien co ten plik właściwie zawiera.

1

Nie rozumiem gdzie jest problem. Wczytując plik za pomocą:

File.ReadAllBytes(name);

wczytujesz je dokładnie tak jak w pythonie (dane są takie same) różnią się jedynie sposobem wyświetlania danych (łatwo w c# możesz również wyświetlić je tak jak w pythonie ((byte).ToString("X2"))..

1 użytkowników online, w tym zalogowanych: 0, gości: 1