2013-01-22 12 views
18

Mam aplikację do skanowania plików w Javie, która skanuje katalog na serwerze za pomocą FTP. pobiera listę plików z katalogu i pobiera je jeden po drugim. z drugiej strony na serwerze jest proces, który zapisuje te pliki. jeśli mam szczęście, nie będę próbował pobrać niekompletnego pliku, ale jak mogę się upewnić, czy proces zapisu na serwerze jest kompletny, a uchwyt pliku jest zamknięty i czy plik jest gotowy do pobrania?Jak sprawdzić, czy plik jest kompletny na serwerze za pomocą FTP?

Nie mam kontroli nad procesem zapisu, który znajduje się na serwerze. ponadto, nie mam uprawnień do zapisu w katalogu, aby spróbować uzyskać uchwyt zapisu, aby sprawdzić, czy jest już otwarty uchwyt zapisu, więc ta opcja jest poza tabelą.

Czy istnieje funkcja FTP rozwiązująca ten problem?

+4

Najlepsze co możesz zrobić, to zobaczyć, że plik nie był modyfikowany przez pewien czas, powiedzmy minutę. –

+0

jakiej biblioteki używasz dla klienta FTP? –

+0

Co się stanie, jeśli zapis zacznie się po rozpoczęciu pobierania? –

Odpowiedz

21

To bardzo stary i znany problem.

Nie można uzyskać absolutnej pewności, że plik napisany przez demona FTP jest kompletny. Jest nawet możliwe, że przesyłanie plików nie powiodło się, a następnie zostanie ponownie uruchomione i zakończone. Musisz odpytać rozmiar pliku i ustawić limit czasu, powiedzmy 5 minut. Jeśli rozmiar nie zmieni się w tym czasie, zakładasz, że plik jest kompletny.

Jeśli to możliwe, program przetwarzający plik powinien być w stanie radzić sobie z plikami częściowymi.

Znacznie lepszą alternatywą jest rsync, który jest znacznie bardziej wytrzymały i deterministyczny. Może nawet zostać skonfigurowany (poprzez opcję linii poleceń), aby zapisać dane początkowo do tymczasowej lokalizacji i przenieść je do swojej docelowej ścieżki po pomyślnym zakończeniu. Jeśli plik istnieje tam, gdzie go oczekujesz, jest z definicji kompletny.

+0

Właściwie używam już tego 5-minutowego progu, chodzi o to, że naprawdę mógłbym użyć szybszej dostępności plików. jednak być może uda mi się dwukrotnie sprawdzić rozmiar pliku w mniej niż minutę, aby Twoje rozwiązanie zadziałało na moją korzyść :) dziękuję Jim. –

+0

Zastanawiam się, czy nie istnieje sposób sprawdzania systemu operacyjnego pod kątem liczby otwartych "zapisanych uchwytów" w pliku? specjalnie przez ftp? –

+0

Nie dyskryminowałoby to nieudanego przelewu i pełnego przelewu. Zamiast tego użyj protokołu rsync, jeśli możesz, to działa o wiele lepiej. –

0

Można użyć biblioteki ftp z Apache Commons API get more information

boolean flag = retrieveFile(String remote, OutputStream local); 

Ta flaga strumień wyjściowy wyboru jest dostępne w bieżącym pliku.

+1

@Hossain, jego pytanie nie dotyczyło tego, której biblioteki użyć, ale w jaki sposób upewnić się, że nie pobiera niekompletnych plików z serwera, biblioteka FTP Apache nie gaurentee ci, że zawsze pobierze kompletny plik z serwera. –

+0

@Mohammod i tak przyjrzę się popularnemu FTPClient Apache, dziękuję –

+0

@Mohammod Sprawdziłem dokumentację, wygląda na to, że flaga jest prawdziwa, jeśli pobieranie zakończy się pomyślnie, nie oznacza, że ​​nie pobierze pliku, który jest nadal napisane na. Mam na myśli to, że pobierze plik tak samo, jak jest napisany. i zwróci true, jeśli uda się pobrać niekompletny plik z powodzeniem :) o to mi nie chodzi;) i tak dziękuję –

7

Jest to bardziej fundamentalne niż FTP: problem będzie podobny do odczytu tych plików, nawet jeśli zostały utworzone na komputerze lokalnym.

Jeśli nie możesz zmodyfikować procesu pisania, musisz przeskoczyć przez kilka kółek. Żadne nie są świetne, ale niektóre są bezpieczniejsze niż inne.

  • Czytaj dalej, aż nic się nie zmieni dla jakiegoś okna (może minutę, jak sugeruje David Schwartz). Możesz to nieco zoptymalizować oglądając rozmiar pliku.
  • Sprawdź, czy pliki są zapisywane seryjnie w niezawodny sposób. Kiedy pojawi się plik N, wiesz, że plik N-1 jest gotowy. (Zakłada, że ​​katalog jest pusty, zanim pliki zostaną zapisane, ale możesz również spojrzeć na sygnatury czasowe.) Wadą jest to, że twoja logika się zepsuje, jeśli pisarz kiedykolwiek zmieni kolejność lub zacznie pisać równolegle.

Niezawodne i bezpieczne rozwiązania wymagają udoskonalenia procesu pisania.

  • Writer może zapisywać pliki do ukrytych lub tymczasowych miejscach i tylko uczynić je widocznymi raz cały plik (lub katalog) jest gotowy, używając dowiązania lub plik poruszających lub chmod.
  • Program piszący tworzy specjalny plik (np. "./DONE") dopiero po zapisaniu wszystkich innych plików, a czytnik nie odczytuje żadnych plików, dopóki ten plik nie będzie obecny.
  • W zależności od typu pliku, autor może dodać na końcu pliku jakiś zapis/linię końca pliku, a czytelnik może upewnić się, że jest obecny.
+0

dzięki dbort, zastanawiam się, nie ma sposobu, aby zapytać system operacyjny o liczbę otwartych "napisz" -handles "w pliku? specjalnie przez ftp? –

12

Możliwe rozwiązanie to najpierw przesłanie pliku o innej nazwie (np. Dodanie ".partial"), a następnie zmiana nazwy na jego ostateczną nazwę.

Jeśli serwer znajdzie ostateczną nazwę, to przesyłanie zostało zakończone.

Jeśli nie możesz kontrolować procesu przesyłania, to z góry jest to niemożliwe: przesyłanie pliku może zostać zatrzymane z powodu problemu z siecią lub z powodu zatrzymania procesu wysyłania.

To, co zobaczy koniec odbiorcy, to tylko zamknięcie przychodzącego strumienia; nie ma możliwości zagwarantowania, że ​​dane nie będą stanowiły częściowego przeniesienia.

Inne obejścia mogą polegać na sprawdzeniu znacznika końca danych lub skorzystaniu z żądania na serwerze wysyłającym, aby sprawdzić, czy (w ich widoku) przelew został zakończony.

+0

Niestety proces pisarza jest poza moją kontrolą i nie będzie ze mną współpracował, więc jestem sam w tym. –

+0

Myślę, że to, o co prosisz, jest niemożliwe. Jeśli serwer wysyłający zostanie zamknięty w trakcie przesyłania i nigdy nie zostanie włączony ponownie, czy transfer zostanie zakończony? Nie można tego wykryć na stronie odbierającej. – 6502

+0

ok ale i tak dziękuję –

Powiązane problemy