1 #Region "Microsoft.VisualBasic::adeed41ba1eaafc5aead39fac5f18d11, Microsoft.VisualBasic.Core\Language\Language\UnixBash\FileSystem\File.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class File
35     
36     '         Function: Save
37     '         Operators: <, >, >>
38     
39     '     Structure FileHandle
40     
41     '         Properties: IsDirectory, IsFile, IsHTTP
42     
43     '         FunctionToString
44     
45     '     Module FileHandles
46     
47     '         Constructor: (+1 OverloadsSub New
48     
49     '         Function: __getHandle, FileOpened, OpenHandle, OpenTemp, Wait
50     
51     '         Sub: Close
52     
53     
54     ' /********************************************************************************/
55
56 #End Region
57
58 Imports System.Runtime.CompilerServices
59 Imports System.Text
60 Imports System.Threading
61 Imports Microsoft.VisualBasic.ComponentModel
62 Imports Microsoft.VisualBasic.Serialization.JSON
63 Imports Microsoft.VisualBasic.Text
64
65 Namespace Language.UnixBash.FileSystem
66
67     ''' <summary>
68     ''' Asbtract file IO model
69     ''' </summary>
70     Public MustInherit Class File : Inherits BaseClass
71         Implements ISaveHandle
72
73         Public Function Save(Optional Path As String = ""Optional encoding As Encodings = Encodings.UTF8) As Boolean Implements ISaveHandle.Save
74             Return Save(Path, encoding.CodePage)
75         End Function
76
77         Public MustOverride Function Save(Optional Path As String = ""Optional encoding As Encoding = NothingAs Boolean Implements ISaveHandle.Save
78
79         Public Shared Operator >(file As File, path As StringAs Boolean
80             Return file.Save(path, Encodings.UTF8)
81         End Operator
82
83         Public Shared Operator <(file As File, path As StringAs Boolean
84             Throw New NotImplementedException
85         End Operator
86
87         Public Shared Operator >>(file As File, path As IntegerAs Boolean
88             Dim handle As FileHandle = __getHandle(path)
89             Return file.Save(handle.FileName, handle.encoding)
90         End Operator
91     End Class
92
93     ''' <summary>
94     ''' 文件系统对象的句柄
95     ''' </summary>
96     Public Structure FileHandle
97         Dim FileName As String
98         Dim handle As Integer
99         Dim encoding As Encoding
100
101         ''' <summary>
102         ''' Determined that is this filename is a network location.
103         ''' </summary>
104         ''' <returns></returns>
105         Public ReadOnly Property IsHTTP As Boolean
106             Get
107                 Return FileName.isURL
108             End Get
109         End Property
110
111         Public ReadOnly Property IsFile As Boolean
112             Get
113                 Return FileName.FileExists
114             End Get
115         End Property
116
117         Public ReadOnly Property IsDirectory As Boolean
118             Get
119                 Return FileName.DirectoryExists
120             End Get
121         End Property
122
123         Public Overrides Function ToString() As String
124             Return Me.GetJson
125         End Function
126     End Structure
127
128     Public Module FileHandles
129
130         ReadOnly ___opendHandles As Dictionary(Of Integer, FileHandle)
131
132         Sub New()
133             ___opendHandles = New Dictionary(Of Integer, FileHandle)
134         End Sub
135
136         Friend Function __getHandle(path As IntegerAs FileHandle
137             If Not FileHandles.___opendHandles.ContainsKey(path) Then
138                 Throw New ObjectNotFoundException($"Path {path} pointer to a null file handle!")
139             Else
140                 Return FileHandles.___opendHandles(path)
141             End If
142         End Function
143
144         ''' <summary>
145         ''' 不存在的文件句柄会在这个函数之中被忽略掉
146         ''' </summary>
147         ''' <param name="file%"></param>
148         Public Sub Close(file%)
149             SyncLock ___opendHandles
150                 With ___opendHandles
151                     If .ContainsKey(file) Then
152                         Call .Remove(file)
153                     Else
154                         Do Nothing.
155                     End If
156                 End With
157             End SyncLock
158         End Sub
159
160         Dim __handle As Value(Of Integer) = New Value(Of Integer)(Integer.MinValue)
161
162         ''' <summary>
163         ''' Open a file system handle
164         ''' </summary>
165         ''' <param name="file"></param>
166         ''' <param name="encoding"></param>
167         ''' <returns></returns>
168         <Extension> Public Function OpenHandle(file$, Optional encoding As Encodings = Encodings.UTF8) As Integer
169             If String.IsNullOrEmpty(file) Then
170                 Throw New NullReferenceException("File handle null pointer!")
171             End If
172
173             SyncLock ___opendHandles
174                 SyncLock __handle
175                     __handle.value += 1
176
177                     Dim handle As New FileHandle With {
178                         .encoding = encoding.CodePage,
179                         .FileName = file,
180                         .handle = __handle.value
181                     }
182
183                     Call ___opendHandles.Add(__handle.value, handle)
184                     Call FileIO.FileSystem.CreateDirectory(file.ParentPath)
185
186                     Return __handle.value
187                 End SyncLock
188             End SyncLock
189         End Function
190
191         Public Function OpenTemp() As Integer
192             Return OpenHandle(App.GetAppSysTempFile(App.Process.Id))
193         End Function
194
195         ''' <summary>
196         ''' Is this file opened
197         ''' </summary>
198         ''' <param name="filename"></param>
199         ''' <returns></returns>
200         <Extension> Public Function FileOpened(filename As StringAs Boolean
201             If Not filename.FileExists Then
202                 Return False
203             Else
204                 Try
205                     Using file As New IO.FileStream(filename, IO.FileMode.OpenOrCreate)
206                     End Using
207
208                     Return False
209                 Catch ex As Exception
210                     Return True
211                 Finally
212                 End Try
213             End If
214         End Function
215
216         ''' <summary>
217         ''' 等待文件句柄的关闭
218         ''' </summary>
219         ''' <param name="file$"></param>
220         ''' <param name="timeout">等待的时间长度,默认为100s,单位为毫秒</param>
221         ''' <returns></returns>
222         Public Function Wait(file$, Optional timeout& = 1000 * 100) As Boolean
223             Dim sw As Stopwatch = Stopwatch.StartNew
224
225             Do While file.FileOpened
226                 Call Thread.Sleep(1)
227
228                 If sw.ElapsedMilliseconds >= timeout Then
229                     Return False
230                 End If
231             Loop
232
233             Return True
234         End Function
235     End Module
236 End Namespace