tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル 共有フォルダ上のあるファイルへ複数ユーザーからランダムアクセスすると読みだせなくなる
投稿日: 2019/07/09(Tue) 18:28
投稿者皆月
知恵を貸してください。

プログラム@
パソコン(A)より共有フォルダ(NAS)上の「yyMMdd.txt」へ固定文字列長(Sift-JIS)の文字列を
1秒に1回、追記し続けています。(日付が変わるとファイル名も変わります)

プログラムA
パソコン(B〜/複数台)より共有フォルダ(NAS)上の「yyMMdd.txt」より
Seekで新しい固定文字列長(Shift-JIS)を読みだしています。

困っていること:
パソコン数台でデータを読みだしている間は問題なく動いているのですが、
プログラムAを実行するパソコンが増えてくると、一部パソコンで「yyMMdd.txt」より
固定文字列が読み込めなく?なります。 ※Try Catchでは特にエラーは出ていません
デバッグで確認すると固定文字列がNull?になっていました。
ランダムアクセス?での同時アクセス数に限界があるのかな?と素人推論しています。
感覚でいうと10台ぐらいで発生している気がします。

【Q.】どうにか読み出すパソコンが増えても動作するように改造したいのですが、何か良い案はありませんか?

ファイルアクセス数に問題があるのならパソコン(A)よりUDP通信で
パソコン(B〜)に文字列配信しようかとも考えてはいますが、二の足踏んでいます。
データベース化すればいいのかもしれませんが、小生の力量では現状不可です。

開発環境:Windows7 64bit VisualBasic2010 Express / NetFramework3.5用アプリケーション
実行環境:Win7(32bit/64bit)、Win10(64bit)
共有フォルダ:Linuxサーバー(バッファローの安いNAS)

******************
※ c変数名 はConstで宣言してある文字列です

プログラム@(抜粋)
Private FS As FileStream
Private DataLength As Long
Private DataEnc As System.Text.Encoding
Private tim1 As New Windows.Forms.Timer

Private Sub frmMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    '***** データ書出し処理実行 *****
    DataLength = cDataFormat.Length
    DataEnc = System.Text.Encoding.GetEncoding("Shift_JIS")
    tim1.Interval = 950    
    tim1.Enabled = True
    AddHandler tim1.Tick, AddressOf tim1_Tick
End Sub

'データを定周期書出し
    Private Sub tim1_Tick(sender As System.Object, e As System.EventArgs)

        '***日付変更確認***
        Static today As String
        If today <> Format$(Now, "yyMMdd") Or today = "" Then
            today = Format$(Now, "yyMMdd")
            CreateNewFile()
        End If

        '***書込み***
        Dim bufNow As Date = Now
        Dim seekNo As Double = CDbl(Format$(bufNow, "HH")) * 3600 _
                                + CDbl(Format$(bufNow, "mm")) * 60 + CDbl(Format$(bufNow, "ss"))
        Dim Data As String = Format$(bufNow, "HHmmss") & "-" & 固定文字列 & vbCrLf

        FS.Seek(DataLength * seekNo, SeekOrigin.Begin)
        Dim bytData As Byte() = DataEnc.GetBytes(Data)
        FS.Write(bytData, 0, DataLength)

        'Debug.Print("Now:{0} SeekNo:{1} Data:{2}", bufNow, seekNo, Data)
        lblOUT.Text = String.Format("Now:{0} SeekNo:{1} Data:{2}", bufNow, seekNo, Data)

    End Sub
    '*****ファイル準備*****
    Private Sub CreateNewFile()

        Try
            '開いていたら閉じる
            If Not FS Is Nothing Then FS.Close()

            '保存フォルダ作成(年)
            Dim filePath As String = cSaveDir & Format$(Now, "yyyy")
            If Dir(filePath, FileAttribute.Directory) = "" Then MkDir(filePath)

            'ランダムアクセスでファイルオープン  別プロセスからは読出しのみ可。
            FS = New FileStream(filePath & "\" & Format$(Now, "yyMMdd") & "txt" ,_
                        FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)

        Catch ex As Exception
            lblERR.Text = String.Format("Now:{0} ファイル切替失敗", Now)

        End Try

    End Sub

動作Aのプログラム(抜粋)
'データ書出し用
    Private FS As FileStream
    Private DataLength As Long
    Private DataEnc As System.Text.Encoding

'*****タイマーイベント*****
    Private Sub tim1_Tick(sender As System.Object, e As System.EventArgs)

        tim1.Enabled = False

        Try
            Dim bufDate As Date = Now.AddSeconds(-5) '5秒前のデータを読む
            '***日付変更確認***
            Static today As String
            If today <> bufDate.ToString("yyMMdd") Or today = "" Then
                today = bufDate.ToString("yyMMdd")
                FileOpen(bufDate)
            End If

            Dim LineN As Integer = bufDate.Hour * 3600 + bufDate.Minute * 60 _
                                     + bufDate.Second   '何行目?
            Dim flowData As String = ReadData(LineN)  '文字列を貰う

            '***貰った文字列の処理***

        Catch ex As Exception
            Debug.Print("{0}:タイマーイベントでエラー {1}", Now.ToString("HH:mm:ss"), ex.Message)

        Finally
            tim1.Enabled = True

        End Try

    End Sub

    '*****ファイル準備*****
    Private Sub FileOpen(ByVal bufDate As Date)

        '開いていたら閉じる
        If Not FS Is Nothing Then FS.Close()

        Dim fileName As String = cSaveDir & Format$(Now, "yyyy") & "\" & _
                                  Format$(bufDate, "yyMMdd") & cFileExt

        'ランダムアクセスでファイルオープン  別パソコンからは読出しのみ可。
        Debug.Print("{0}をひらきまーす", fileName)
        FS = New FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

    End Sub

    '*****ランダムアクセスで吸い出す*****
    Private Function ReadData(ByVal LineN As Integer) As String

        Dim bufRecord(DataLength) As Byte       '読出し格納用

        Try
            FS.Seek(LineN * DataLength, SeekOrigin.Begin)       '読出し位置へ移動
            FS.Read(bufRecord, 0, DataLength)                   '何文字読み出す?

            Dim strBuf As String = DataEnc.GetString(bufRecord) 'ByteデータをStringへ変換
      ***【↑ここのbufRecordがNullになって困っています】***
            
            Debug.Print("{0}行目のデータ {1}", LineN, strBuf)

            If Mid(strBuf, 7, 1) = "-" Then Return strBuf '7文字目は[-]のはず。

        Catch ex As System.IO.IOException
            Debug.Print("{0}:データ読出しIOException →{1}({2})", _
                          Now.ToString("HH:mm:ss"), ex.ToString, ex.Message)
            'ファイルが見当たらないなら開き直そう
            Dim bufDate As Date = Now.AddSeconds(subSecond) '時間差
            FileOpen(bufDate)

        Catch ex As System.ObjectDisposedException
            Debug.Print("{0}:データ読出しObjectDisposedException →{1}({2})", _
                          Now.ToString("HH:mm:ss"), ex.ToString, ex.Message)
            'ファイルが見当たらないなら開き直そう
            Dim bufDate As Date = Now.AddSeconds(subSecond) '時間差
            FileOpen(bufDate)

        Catch ex As Exception
            Debug.Print("{0}:データ読出しでエラー {1}({2})", _
                        Now.ToString("HH:mm:ss"), ex.ToString, ex.Message)
            
        End Try

        Return cDataFormat '0データを表示させる。

    End Function

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。