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 | ' Function: ToString |
44 | ' |
45 | ' Module FileHandles |
46 | ' |
47 | ' Constructor: (+1 Overloads) Sub 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 = Nothing) As Boolean Implements ISaveHandle.Save |
78 | |
79 | Public Shared Operator >(file As File, path As String) As Boolean |
80 | Return file.Save(path, Encodings.UTF8) |
81 | End Operator |
82 | |
83 | Public Shared Operator <(file As File, path As String) As Boolean |
84 | Throw New NotImplementedException |
85 | End Operator |
86 | |
87 | Public Shared Operator >>(file As File, path As Integer) As 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 Integer) As 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 String) As 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 |