2010-07-10 21 views
5

पर पर्ल में फ़ाइल का उपयोग किया जा रहा है या नहीं, मैं कुछ पर्ल लिख रहा हूं जो विंडोज मीडिया सेंटर पर दर्ज टीवी शो लेता है और कुछ मानदंडों के आधार पर उन्हें स्थानांतरित/नाम/हटा देता है।यह निर्धारित करें कि विंडोज

चूंकि पर्ल काफी बार चलता है, इसलिए मैं साफ-सफाई करना चाहता हूं कि फ़ाइल उपयोग में है या नहीं (दूसरे शब्दों में, शो रिकॉर्ड होने की प्रक्रिया में है) इसलिए मैं इसके साथ कुछ भी करने से बच सकता हूं।

मेरे वर्तमान विधि फ़ाइल की स्थिति पर लग रहा है ("स्टेट" का प्रयोग करके) और 5 सेकंड के बाद इसे फिर से तुलना, इसलिए जैसे:

sub file_in_use 
{ 
    my $file = shift; 

    my @before = stat($file); 
    sleep 5; 
    my @after = stat($file); 

    return 0 if ($before ~~ $after); 
    return 1; 
} 

यह काम करने के लिए लगता है, लेकिन मैं सचेत कर रहा हूँ कि वहाँ ऐसा करने के लिए शायद एक बेहतर और साफ तरीका है।

क्या आप सलाह दे सकते हैं?

+0

यह यह करने के लिए एक ठीक approch है और साथ में विफल रहता है मैं विश्वास नहीं करता कि आपको चारों ओर कई विकल्प मिलेंगे ... ऐसा करने का एक और तरीका एप्लिकेशन पिड पढ़कर और फ़ाइलों को एक बार बंद कर दिया जाएगा ... – Prix

+1

प्रिक्स से (मुझे लगता है कि यह इंगित करना महत्वपूर्ण है आउट): * यदि फ़ाइल का पूर्ण समय उपयोग किया जा रहा है और जारी नहीं किया गया है तो आप फ़ाइल पर एक चाल [या हटाएं] नहीं कर सकते क्योंकि यह एक त्रुटि उत्पन्न करेगा ... *। (एक प्रति विभिन्न फ़ाइल मोड सेटिंग्स के आधार पर काम कर सकती है।) यहां तक ​​कि स्टेट दृष्टिकोण के साथ, आपको * अभी भी * एफएस परिदृश्य को संभालना होगा और 'file_in_use' को केवल' संकेत 'के रूप में उपयोग करना होगा (हालांकि संभावित दौड़ की स्थिति कभी भी भौतिक नहीं हो सकती है यहाँ)। –

+0

@pst True, यही कारण है कि मुझे लगता है कि चाल चलने का एक अच्छा तरीका है ... चूंकि फ़ाइल अभी भी लॉक है, तो यह या तो 0 लौटाएगी या आपको यह बताएगी कि आप इसे कैसे कोड करते हैं और आप केवल तब तक प्रयास कर सकते हैं जब तक आप इसे जारी नहीं रख सकते यह जारी किया गया है या तो ... – Prix

उत्तर

8

रिकॉर्डिंग हैं प्रक्रिया फ़ाइल को लॉक करती है, आप इसे रीड-राइट मोड में खोलने का प्रयास कर सकते हैं और देख सकते हैं कि यह ERROR_SHARING_VIOLATIONGetLastError के रूप में विफल रहता है (पर्ल के $^E विशेष चर के माध्यम से पहुंचाया गया है)।

उदाहरण के लिए:

Dir100526Lt.pdf एडोब रीडर द्वारा खुले साथ
#! /usr/bin/perl 

use warnings; 
use strict; 

sub usage { "Usage: $0 file ..\n" } 

die usage unless @ARGV; 

foreach my $path (@ARGV) { 
    print "$path: "; 

    if (open my $fh, "+<", $path) { 
    print "available\n"; 
    close $fh; 
    } 
    else { 
    print $^E == 0x20 ? "in use by another process\n" : "$!\n"; 
    } 
} 

नमूना उत्पादन:

C:\Users\Greg\Downloads>check-lock.pl Dir100526Lt.pdf setup.exe 
Dir100526Lt.pdf: in use by another process 
setup.exe: available

बाद में पता है कि किसी भी समय आप पहली बार एक स्थिति का परीक्षण हो और उसके बाद के परिणाम के आधार पर कार्य वह परीक्षण, आप race condition बना रहे हैं। ऐसा लगता है कि सबसे खराब यह अपने आवेदन में आपको काट सकता है निम्न अशुभ अनुक्रम में है:

  1. परीक्षण ऊपर
  2. जवाब के रूप में उपलब्धता के लिए एक वीडियो: उपलब्ध है!
  3. इस बीच में, एक रिकॉर्डर शुरू होता है और
  4. वापस वीडियो ताले अपने कार्यक्रम में, आप वीडियो ले जाने की कोशिश की, लेकिन यह एक साझा उल्लंघन
+0

बिल्कुल सही! आपका बहुत बहुत धन्यवाद। दौड़ की स्थिति के बारे में अच्छी बात - जैसे कि मैं उम्मीद कर रहा हूं कि, रिकॉर्डिंग समाप्त होने के बाद, इसे फिर से शुरू करने के लिए कोई कारण नहीं होना चाहिए। – Richard

+0

आपके लिए कुकी मुझे यह विशेष चर पसंद है ... बस एक त्वरित सवाल है, अगर वह उस फ़ाइल को जानता है जिसे उसे जांचने की ज़रूरत है और जांचें कि यह उस समय उपलब्धता है और इसे तुरंत लॉक करें तो यह मिलिसेकंड की तरह होगा जब तक कोई अन्य एप्लिकेशन प्राप्त नहीं हो जाता इसकी पकड़ है तो ऐसा नहीं होना बहुत मुश्किल होगा? – Prix

+1

@Prix एक मिलीसेकंड कंप्यूटर के लिए एक लंबा समय है। असंभव अर्थ यह है कि यह कभी-कभी होता है, और इन प्रकार की त्रुटियों को डीबग करना मुश्किल होता है। अनुमोदित, इस मामले में, यह शायद झगड़े के लायक नहीं है, लेकिन सिंक्रनाइज़ेशन दरारों को स्पॉट करने के लिए खुद को प्रशिक्षित करना हमारे लिए अच्छा है। उपलब्धता की जांच करने और फिर लॉक करने के बजाय, लॉक को तुरंत प्राप्त करें। अगर किसी और के पास यह है, तो सिस्टम इसे आपके पास उपलब्ध कराएगा जितनी जल्दी हो सके। अन्यथा, आप जानते हैं कि आपके पास यह है, और यह किसी और के लिए उपलब्ध नहीं होगा। –

1

केवल सुधार मेरा सुझाव है, एक ही बार में आपकी फ़ाइलों के stat सब करने के लिए है ताकि आप केवल बजाय हर फ़ाइल के लिए 5 सेकंड सो में से एक समय 5 सेकंड के लिए सोने के लिए की जरूरत है:

my (%before, %after); 
foreach my $file (@files_that_might_be_in_use) { 
    $before{$file} = [ stat $file ]; 
} 
sleep 5; 
foreach my $file (@files_that_might_be_in_use) { 
    $after{$file} = [ stat $file ]; 

    if ($before{$file} ~~ $after{$file}) { 
     # file is not in use ... 
    } else { 
     # file is in use ... 
    } 
} 
संबंधित मुद्दे