@@ -45,13 +45,19 @@ Public Class ConvertLineEndings
4545 convertMode As TextConvertMode) As Task( Of Integer )
4646
4747 Try
48- Using oldFileStream As New FileStream(originalFile, FileMode.Open)
49- ' Attempt to detect encoding
50- Dim fileEncoding As Encoding = GetEncoding(oldFileStream)
51- If fileEncoding Is Nothing Then Return 4
48+ ' Do not attempt to work on symbolic links
49+ If IsSymbolic(originalFile) Then Return - 1
50+
51+ Using oldFileStream As New FileStream(originalFile, FileMode.Open, FileAccess.Read)
52+ ' Attempt to detect encoding we will use for reading and writing
53+ Dim fileEncoding As Encoding = Await GetEncoding(oldFileStream)
5254 Debug.Print(fileEncoding.ToString())
5355
54- 'Write the result out to a new file
56+ ' Rewind stream
57+ oldFileStream.Position = 0
58+ Await oldFileStream.FlushAsync
59+
60+ ' Reading and writing is done in this one line
5561 File.WriteAllText(newFile, Await GetConvertedText(oldFileStream, fileEncoding, convertMode), fileEncoding)
5662 End Using
5763 Catch ex As Exception
@@ -63,78 +69,42 @@ Public Class ConvertLineEndings
6369 End Function
6470
6571 Private Shared Async Function GetConvertedText(originalFile As FileStream, fileEncoding As Encoding, convertMode As TextConvertMode) As Task( Of String )
66- Const cr As Char = ChrW( 13 )
67- Const lf As Char = ChrW( 10 )
72+ Const CR As Char = ChrW( 13 )
73+ Const LF As Char = ChrW( 10 )
6874
69- Dim convertedLines As StringBuilder = Nothing
70- Try
71- Using oldFile As New StreamReader(originalFile, fileEncoding, True )
72- Do Until oldFile.EndOfStream ' Read through the whole file
73- Dim readBuffer( 0 ) As Char
74- Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0 , 1 )
75- If readChars >= 1 Then
76- Select Case convertMode
77- Case TextConvertMode.Dos2Ux
78- If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
79- ' Strip out CR chars if followed by LF
80- Await oldFile.ReadAsync(readBuffer, 0 , 1 )
81- End If
82- Case TextConvertMode.Ux2Dos
83- If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
84- ReDim Preserve readBuffer( 1 )
85- ' This is a DOS line ending, keep it.
86- Dim tempBuffer( 1 ) As Char
87- Await oldFile.ReadAsync(tempBuffer, 0 , 1 )
88- readBuffer( 1 ) = tempBuffer( 0 )
89- ElseIf readBuffer( 0 ) = lf Then
90- ReDim readBuffer( 1 )
91- ' Add preceeding CR
92- readBuffer( 0 ) = cr
93- readBuffer( 1 ) = lf
94- End If
95- End Select
75+ Dim convertedLines As New StringBuilder
76+ Using oldFile As New StreamReader(originalFile, fileEncoding, True )
77+ Do Until oldFile.EndOfStream ' Read through the whole file
78+ Dim readBuffer( 0 ) As Char
79+ Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0 , 1 )
80+ If readChars >= 1 Then
81+ Select Case convertMode
82+ Case TextConvertMode.Dos2Ux
83+ If readBuffer( 0 ) = CR AndAlso oldFile.Peek() = 10 Then
84+ ' Strip out CR chars if followed by LF
85+ Await oldFile.ReadAsync(readBuffer, 0 , 1 )
86+ End If
87+ Case TextConvertMode.Ux2Dos
88+ If readBuffer( 0 ) = CR AndAlso oldFile.Peek() = 10 Then
89+ ReDim Preserve readBuffer( 1 )
90+ ' This is a DOS line ending, keep it.
91+ Dim tempBuffer( 1 ) As Char
92+ Await oldFile.ReadAsync(tempBuffer, 0 , 1 )
93+ readBuffer( 1 ) = tempBuffer( 0 )
94+ ElseIf readBuffer( 0 ) = LF Then
95+ ReDim readBuffer( 1 )
96+ ' Add preceeding CR
97+ readBuffer( 0 ) = CR
98+ readBuffer( 1 ) = LF
99+ End If
100+ End Select
96101
97- 'Yield readBuffer
98- convertedLines.Append(readBuffer)
99- End If
100- Loop
101- End Using
102- Catch ex As Exception
103- Debug.Print( "Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString)
104- Return ex.HResult.ToString
105- End Try
102+ 'Yield readBuffer
103+ convertedLines.Append(readBuffer)
104+ End If
105+ Loop
106+ End Using
106107
107108 Return convertedLines.ToString
108109 End Function
109-
110- ''' <summary>
111- ''' Attempt to detect the encoding of a file.
112- ''' </summary>
113- ''' <param name="filename">The file to get the encoding pattern from.</param>
114- ''' <returns>Encoding type, defaults to ASCII.</returns>
115- Public Shared Function GetEncoding(theFile As FileStream) As Encoding
116- Dim bom = New Byte ( 3 ) {}
117- Try ' to read BOM
118- theFile.Read(bom, 0 , 4 )
119- Catch ex As Exception
120- Debug.Print( "Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString)
121- Return Nothing
122- End Try
123-
124- ' Detect BOM type
125- If bom( 0 ) = &H2B AndAlso bom( 1 ) = &H2F AndAlso bom( 2 ) = &H76 Then
126- Return Encoding.UTF7
127- ElseIf bom( 0 ) = &HEF AndAlso bom( 1 ) = &HBB AndAlso bom( 2 ) = &HBF Then
128- Return Encoding.UTF8
129- ElseIf bom( 0 ) = &HFF AndAlso bom( 1 ) = &HFE Then
130- Return Encoding.Unicode
131- ElseIf bom( 0 ) = &HFE AndAlso bom( 1 ) = &HFF Then
132- Return Encoding.BigEndianUnicode
133- ElseIf bom( 0 ) = 0 AndAlso bom( 1 ) = 0 AndAlso bom( 2 ) = &HFE AndAlso bom( 3 ) = &HFF Then
134- Return Encoding.UTF32
135- Else
136- ' Default to
137- Return Encoding.ASCII
138- End If
139- End Function
140110End Class
0 commit comments