Czy można buforować plik binarny w .NET i wykonywać normalne operacje na plikach w pamięci podręcznej?Buforowanie pliku binarnego w języku C#
Odpowiedz
Aby to zrobić, należy przeczytać całą zawartość obiektu FileStream
w obiekcie MemoryStream
, a następnie użyć tego obiektu do operacji we/wy. Oba typy dziedziczą po Stream
, więc użycie będzie skutecznie identyczne.
Oto przykład:
private MemoryStream cachedStream;
public void CacheFile(string fileName)
{
cachedStream = new MemoryStream(File.ReadAllBytes(fileName));
}
Więc po prostu wywołać metodę CacheFile
raz kiedy chcesz buforować dany plik, a następnie nigdzie indziej w użyciu kodu cachedStream
do czytania. (Faktyczny plik zostanie zamknięty, gdy tylko jego zawartość zostanie zapisana w pamięci podręcznej.) Jedyną rzeczą do zapamiętania jest pozbycie się cachedStream
, gdy skończysz.
+1: Myślę, że to może być to, czego chce pytający. –
Prawdopodobnie wszystko będzie dobrze - jedynym problemem będzie sytuacja, w której mówimy o pliku o wielkości GB lub dwóch. –
Ta metoda oczywiście przestaje być przydatna, gdy rozmiar pliku zbliża się do rozmiaru pamięci RAM. W tym momencie powinieneś jednak używać serwera bazy danych, więc zakładam, że to nie będzie problemem. – Noldorin
Każdy nowoczesny system operacyjny ma wbudowany system buforowania, więc w rzeczywistości za każdym razem, gdy wchodzisz w interakcję z plikiem, wchodzisz w interakcję z pamięcią podręczną w pamięci tego pliku.
Przed zastosowaniem niestandardowego buforowania należy zadać ważne pytanie: co się dzieje, gdy plik bazowy ulegnie zmianie, więc moja kopia w pamięci podręcznej zostanie unieważniona?
Możesz dalej komplikować sprawy, jeśli kopia w pamięci podręcznej może się zmieniać, a zmiany muszą być zapisane z powrotem do pliku podstawowego.
Jeśli plik jest mały, prostszym rozwiązaniem jest użycie opcji MemoryStream
, co sugeruje inna odpowiedź.
Jeśli chcesz zapisać zmiany z powrotem do pliku, możesz napisać klasę opakowania, która przekazuje wszystko dalej do MemoryStream
, ale dodatkowo ma właściwość IsDirty, która ustawia wartość true, gdy wykonywana jest operacja zapisu. Następnie możesz mieć kod zarządzania, który uruchamia się w dowolnym momencie (pod koniec jakiejś większej transakcji?), Sprawdza, czy dla (IsDirty == true)
i zapisuje nową wersję na dysku. Jest to nazywane buforowaniem "leniwym zapisem", ponieważ modyfikacje są dokonywane w pamięci i nie są zapisywane do pewnego czasu później.
Jeśli naprawdę chcesz komplikować sprawy lub masz bardzo duży plik, możesz zaimplementować własne stronicowanie, w którym wybierasz rozmiar bufora (może 1 MB?) I zachować niewielką liczbę stron o stałej liczbie stron, które zostały ustalone. rozmiar. Tym razem będziesz mieć brudną flagę dla każdej strony. Wdrożysz metody Stream, aby ukryć szczegóły od wywołującego i w razie potrzeby pobrać (lub odrzucić) bufory strony.
Wreszcie, jeśli chcesz łatwiejsze życie, spróbuj:
http://www.microsoft.com/Sqlserver/2005/en/us/compact.aspx
To pozwala wykorzystywać ten sam silnik SQL jak SQL Server, ale na pliku, ze wszystko dzieje się w procesie, a nie za pośrednictwem zewnętrzny serwer RDBMS. Zapewni to prawdopodobnie znacznie prostszy sposób sprawdzania i aktualizowania pliku oraz uniknięcia konieczności ręcznego pisania kodu trwałości.
Czy to nie jest plik mapowany w pamięci (http://en.wikipedia.org/wiki/Memory-mapped_file)? Mimo to, zadzwonię do OP chce zamknąć uchwyt pliku tak szybko, jak to możliwe. – Noldorin
Mapowanie pamięci to plik, w którym system operacyjny używa pliku (do wyboru) w celu zapewnienia magazynu pamięci wirtualnej dla regionu przestrzeni adresowej procesu. (Plik stronicowania służy temu celowi w przypadku zwykłej pamięci alokacji.) Mówię o tym, że system operacyjny ma buforowanie dysku, które działa niezależnie od tego, w jaki sposób uzyskujesz dostęp do pliku. Spróbuj użyć grep lub podobnego do przeszukiwania kilkuset MB plików tekstowych. Za drugim razem stanie się to znacznie szybciej, a twój dysk twardy nie wyda dźwięku, ponieważ wszystko jest w pamięci. –
@Earwicker: Tak, jestem pewien, że masz rację. Niemniej jednak, kopiowanie zawartości do MemoryStream wydaje się być najlepszym rozwiązaniem, ponieważ a) nie utrzymuje blokady pliku b) Podejrzewam, że nadal będzie oferować wzrost wydajności. – Noldorin
Cóż, można oczywiście odczytać plik do tablicy byte [] i rozpocząć pracę nad nim. A jeśli chcesz używać strumienia można skopiować FileStream do MemoryStream i rozpocząć pracę z nim - jak:
public static void CopyStream(Stream input, Stream output)
{
var buffer = new byte[32768];
int readBytes;
while((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, readBytes);
}
}
Jeśli chodzi o wydajność - dobrze, normalnie mechanizmy wbudowany w innym pliku metody dostępu powinny wystarczyć.
Nie wiem, co dokładnie robisz, ale oferują tę sugestię (które mogą lub nie mogą być opłacalne w zależności od tego, co robisz):
Zamiast tylko buforowanie zawartości katalogu plik, dlaczego nie umieścisz zawartości pliku w ładnie mocno wpisanej kolekcji przedmiotów, a następnie w pamięci podręcznej? Prawdopodobnie ułatwi to wyszukiwanie przedmiotów i przyspieszy, ponieważ nie ma potrzeby analizowania.
plik zawiera wiele rekordów. w rzeczywistości jest to plik binarny bazy danych kraju maxmind –
, z którego możemy przyjąć, że prawdziwym problemem jest to, że nie otrzymujesz wydajności, jaką chcesz od swoich zapytań? –
Istnieje bardzo elegancki system buforowania w Lucene, który buforuje bajty z dysku do pamięci i inteligentnie aktualizuje sklep itp. Możesz chcieć rzucić okiem na ten kod, aby zorientować się, jak to robią. Możesz również chcieć przeczytać na temat warstwy przechowywania danych Microsoft SQL Server - ponieważ zespół MSSQL jest dość otwarty na temat niektórych najważniejszych szczegółów implementacji.
- 1. Czytanie i pisanie int do pliku binarnego w języku C++
- 2. Parsowanie pliku binarnego w języku Ruby
- 3. Ścieżka do pliku binarnego w C
- 4. Napisz na środku istniejącego pliku binarnego C++
- 5. Czytanie i pisanie na środku pliku binarnego w C/C++
- 6. Czy buforowanie w języku C# jest odpowiednie dla mnie?
- 7. Zapisywanie pliku dziennika w języku c/C++
- 8. Wysyłanie pliku binarnego w Tornado
- 9. Deserializacja części pliku binarnego
- 10. Generowanie losowego pliku binarnego
- 11. Pobieranie pliku binarnego
- 12. Aktualizuj tylko część pliku binarnego za pomocą C++
- 13. Buforowanie aplikacji internetowych w języku Java
- 14. Kompilowanie pliku binarnego C# .NET x64 w systemie x86
- 15. Buforowanie pliku css
- 16. Drzewo wyszukiwania binarnego w C
- 17. odczytywanie pliku .bmp w języku C++
- 18. Czytanie pliku PDF w języku C#
- 19. Jakość zapisanego pliku JPG w języku C#
- 20. Usuwanie linii z pliku w języku C
- 21. Znajdowanie długości pliku MP3 w języku C#
- 22. Czytanie z pliku tekstowego w języku C#
- 23. Podwójne buforowanie? Win32 C++
- 24. Czytanie pliku binarnego z pythonem
- 25. Przesyłanie pliku binarnego na Node.js
- 26. Numer referencyjny układu pliku binarnego
- 27. zapisywanie i ładowanie połączonej listy do pliku binarnego (C)
- 28. Jak edytować wartość szesnastkową pliku binarnego za pomocą C#
- 29. Wyświetlanie pliku binarnego (pdf) w IE 11
- 30. Określanie typu pliku binarnego/tekstowego w Javie?
Huh? Co masz na myśli przez 1) Pamięć podręczna? 2) Plik binarny (np. Plik tekstowy, plik wykonywalny, obraz)? 3) Operacje "Normalny plik"? –
Również dlaczego chcesz go cache'ować? Może to jest niepotrzebne? – uriDium
podaj proszę przypadek użycia. –