2010-01-12 18 views
22

Nasıl bir atomik dosya yazma işlemi oluştururum? Dosya bir Java servisi tarafından yazılacak ve python betikleri ile okunacaktır.
Kayıt için, okumalar yazımlardan çok daha büyüktür. Fakat bu yazma partiler halinde gerçekleşir ve uzun olma eğilimindedir. Dosya boyutu mega bayttır.Atomik dosya yazma işlemleri (çapraz platform)

Şu anda benim yaklaşımdır: aynı dizinde bir geçici dosyaya

  • Yaz dosya içeriği
  • eski dosya adına eski dosyayı
  • yeniden adlandır geçici dosya silin.

Bu doğru yaklaşım mı? Eski dosyanın silindiği durumları nasıl önleyebiliriz, ancak yeni dosya adı henüz yeniden adlandırılmamış mı?

Bu programlama dilleri (python ve java) bu durumu kilitlemek ve önlemek için yapılar sunar mı?

+2

Yan not: Java NIO.2'nin bunun için daha iyi bir desteği var (en azından API düzeyinde): http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path .html # moveTo% 28java.nio.file.Path,% 20java.nio.file.CopyOption ...% 29 –

+0

http://stackoverflow.com/questions/1812115/how-to-safely-write-to benzer -a- –

+0

@Pascal. Onun Java 7. 7. Uzun yol gitmek için ... :-( –

cevap

8

AFAIK no.

Ve bunun nedeni, böyle bir atomik işlemin mümkün olması için, bir işlem dosya sistemi biçiminde İşletim Sistemi desteği olmalıdır. Ve ana işletim sistemi hiçbiri bir işlem dosya sistemi sunmuyor.

EDIT - En azından POSIX uyumlu sistemler için hatalıyım. POSIX rename syscall, @janneb tarafından belirtildiği gibi ... hedef adında bir dosya zaten mevcutsa, bir atomik değiştirmeyi gerçekleştirir. OP'nin operasyonunu atomik olarak yapmak için bu yeterli olmalıdır.

Ancak aslında Java File.renameTo() yöntem açıkça olduğuna kalır değil o OP'ın soruna bir çapraz platform çözümü sağlamaz, yani atomik olması garanti.

DÜZENLEME 2 - Eğer copyOptions ve ATOMIC_MOVE ile java.nio.file.Files.move(Path source, Path target, CopyOption... options) kullanabilirsiniz Java 7 ile. Bu desteklenmiyorsa (OS/dosya sistemi ile) bir istisna almalısınız.

+1

+1: Ahhh, "çapraz platform" çözümünü engelleyen bu sinir bozucu OS farklılıkları. –

+0

Gerçek bir cevap, dosya kilitleri yerine kullanılmalıdır. – unixman83

+0

"Ve hiçbiri mainstream işletim sisteminin bir işlem dosya sistemi sunuyor. "Ne? NTFS uzun bir süre işlem desteği vardı. http://msdn.microsoft.com/en-us/magazine/cc163388.aspx –

0

+1

Evet, ama bu bir atomik dosya değiştirmenize izin vermez. –

+1

Tam olarak doğru değilsiniz. Bu api ile ".lock" dosyasını oluşturabilir ve semafor olarak kullanabilirsiniz. Usecase: dosya kilitliyse - python kilidi açılıncaya kadar bekleyin, ardından kilit açma dosyasını okuduktan sonra okumaya başlayın (ve dosyayı kilitleyin). Hizmetin veri yazması gerektiğinde - Dosya kilitliyse, kontrol edilsin, kilitlenene kadar bekleyin, kilitleyin, veri yazın, kilidini açın. –

+0

Her nasılsa, bu etkili bir bağlantı sadece Cevap, ve bağlantı OP sorununun nasıl çözüleceğini açıklamıyor. Bugünün standartlarına göre düşük kaliteli bir cevaptır. –

1

denemek ve bir kilit görevi için fazladan dosyasını kullanabilirsiniz Java FileLock API deneyin, ama bu Tamam hazırlayacağız olmadığından emin değilim. (Bu, her iki tarafta, java ve python'da kilit denetimi oluşturmayı ve yeniden denemeyi zorlamanızı sağlar)

Başka bir çözüm de dosya oluşturmamanız olabilir, belki de java işleminizi bir bağlantı noktasında dinleyebilir ve veri sunabilirsiniz. oradan bir dosyadan değil mi?

5

En az POSIX platformlarında, 3. adımı (eski dosyayı sil) kaldırın. POSIX'te, bir dosya sistemi içinde yeniden adlandırmak atomik olarak garantilidir ve varolan bir dosyanın üzerine yeniden adlandırma işlemi atomun yerine geçer.

1

Python komut dosyalarının hizmetten izin almasını isteyin. Servis yazarken dosyaya bir kilit yerleştirir. Kilit varsa, hizmet python isteğini reddeder.

3

Bu klasik bir üretici/tüketici sorunudur.Bunu POSIX sistemlerinde atomik olan dosya yeniden adlandırma kullanarak çözebilmelisiniz.

2

Linux'ta Solaris, Unix, bu kolaydır. Programınızdan veya mv'dan rename() öğesini kullanın. Dosyaların aynı dosya sisteminde olması gerekiyor.

Windows'ta, her iki programı da denetleyebiliyorsanız bu mümkündür. LockFileEx. Okumalar için, kilit dosyada bir shared lock açın. Yazmalar için, kilit dosyasında bir exclusive lock açın. Kilitleme, Windows'da garip, bu yüzden bunun için ayrı bir kilit dosyası kullanmanızı öneririz.

İlgili konular