[VB.NET] ファイルのバイト処理を高速化する方法

このQ&Aのポイント
  • VB.NETを使用してファイルのバイト処理を行っていますが、大きいファイルでは処理時間がかかってしまいます。処理を高速化する方法はありますか?
  • VB.NETでファイルのバイト処理を行っていますが、大きいファイルを扱うと処理時間が長くなってしまいます。処理の高速化方法を教えてください。
  • VB.NETでファイルのバイト処理を行っていますが、大きいファイルを扱うと処理時間が増えます。処理を高速化する方法があれば教えてください。
回答を見る
  • ベストアンサー

[VB.NET] 処理の高速化を行いたい。

教えて下さい。 あるファイルの1バイトづつローテートを行いファイルの書き出しを行っています。(ビット演算による暗号化) しかし以下の処理の場合、サイズの大きいファイルを扱った場合に多くの処理時間がかかってしまいます。 もっと処理を高速化する事は可能でしょうか? ----------------------------------------------------------------- ' 読み込みファイル Private Const READ_FILE As String = "c:\temp\date.Text" ' 書き込みファイル Private WRIT_FILE As String = "c:\temp\date.dat" ' オブジェクト作成 Dim br As New System.IO.FileStream(READ_FILE, IO.FileMode.Open, IO.FileAccess.Read) Dim bw As New System.IO.StreamWriter(WRIT_FILE, False, System.Text.Encoding.GetEncoding("iso-8859-1")) Dim m As Integer = 3 ' 3ビット左回転 Dim n As Integer ' 1バイトづつ処理 For I As Integer = 0 To CType(br.Length, Integer) - 1 ' 16進数を10進数へ変換 n = ("&h" & String.Format("{0:X2}", br.ReadByte)) ' mビット左へローテート処理を行いファイルへ書き込み bw.Write(ChrW("&h" & Hex(Int((n / 2 ^ (8 - m)) + (n * 2 ^ m And 255))))) Next ' 閉じる bw.Close() br.Close() ----------------------------------------------------------------- よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.1

> ' 16進数を10進数へ変換 > n = ("&h" & String.Format("{0:X2}", br.ReadByte)) コメントとやっていることが合っていません。 Byte型を &h75 の様な文字列に変換し、 その後暗黙の型変換でInteger型に変換するという (無駄な)処理がここでは行われています。 Byte型は数値なのでそのまま演算処理すれば良いです。 素直にこんな感じに書いてみては? =================================== ' インデントに全角空白を使っています。要削除。 Imports System Imports System.IO Class BRotate  Shared Sub main(ByVal args As String())   Dim srcName As String = args(0) ' コピー元のファイル名   Dim destName As String = args(1) ' コピー先のファイル名   Dim BUFSIZE As Integer = 2048 ' 1度に処理するサイズ   Dim buf(BUFSIZE) As Byte ' 読み込み用バッファ   Dim m As Integer = 3 ' 3ビット左回転   Dim readSize As Integer ' Readメソッドで読み込んだバイト数   Using src As New FileStream( _     srcName, FileMode.Open, FileAccess.Read)    Using dest As New FileStream( _      destName, FileMode.Create, FileAccess.Write)     While True      readSize = src.Read(buf, 0, BUFSIZE) ' 読み込み      If readSize = 0 Then       Exit While ' 完了      End If      For i As Integer = 0 To readSize - 1        buf(i) = (buf(i) << m) Or (buf(i) >> (8-m)) ' ビット回転      Next      dest.Write(buf, 0, readSize) ' 書き込み     End While    End Using   End Using  End Sub End Class ' 参考にしたページ:以下のページのファイルコピープログラムをベースにした ' バイナリ・ファイルを読み書きするには?[C#、VB] - @IT ' http://www.atmarkit.co.jp/fdotnet/dotnettips/669bincopy/bincopy.html

wansui
質問者

お礼

ありがとうございました! 信じられないくらい高速化する事が出来ました! (一瞬で処理が終わる!) まじありがとおおおおおおおおおおw

その他の回答 (1)

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2

C#しか書けないけど、こんな感じ //変換表を作成 byte[] convList = new byte[256]; for (byte i = 0; i <= 255; i++) { convList[i] = (byte)((i << 3) & 255 | (i >> 5)); } using (FileStream reader = new FileStream(~)) using (FileStream writer = new FileStream(~)) { while (true) { int c = reader.ReadByte(); if (c == -1) break; writer.WriteByte(convList[c]); } }

wansui
質問者

お礼

ありがとうございました。

関連するQ&A

  • バイナリの高速読み取り

    vb2005でバイナリデータを16進数で読み込みたいのですが、 Dim br As New System.IO.FileStream("フルパス",IO.FileMode.Open, IO.FileAccess.Read) Dim strbyte As String For I As Integer = 0 To CType(br.Length, Integer) - 1 strbyte = Hex(br.ReadByte).ToString If strbyte.Length = 1 Then strbyte = "0" & strbyte End If TextBox1.Text = TextBox1.Text & " " & strbyte Application.DoEvents() Next とか、他に Dim arByte() As Byte = My.Computer.FileSystem.ReadAllBytes("フルパス") Dim obyte As Byte Dim strbyte As String For Each obyte In arByte strbyte = Hex(obyte).ToString If strbyte.Length = 1 Then strbyte = "0" & strbyte End If TextBox1.Text = TextBox1.Text & " " & strbyte Application.DoEvents() Next なんかも試してみたのですが、ぜんぜん読み込みが遅くて困っています。 なんか高速にバイナリデータを16進数で読み込む方法がありましたら教えてください。(一般のバイナリエディタ並に)

  • FTP接続の例外処理

    vb.netで開発しています。 以下のソースはFTPでtxtファイルを外部ホスティングサーバーにアップロードしている箇所です。 Private Function UpRoad(ByVal Flnm As String) As Boolean Dim s As Integer 'Err数 Dim Int_Err As Integer = 0 For s = 0 To 2 ' アップロードするファイル() Dim upFile As String = "C:\HighwayMail\SendData\Data\" & Flnm 'アップロード先のURI Dim u As New Uri(ftpad & "/data/" & Flnm) 'FtpWebRequestの作成 Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(u), System.Net.FtpWebRequest) 'ログインユーザー名とパスワードを設定 ftpReq.Credentials = New System.Net.NetworkCredential(usernm, pass) 'MethodにWebRequestMethods.Ftp.UploadFile("STOR")を設定 ftpReq.Method = System.Net.WebRequestMethods.Ftp.UploadFile '要求の完了後に接続を閉じる ftpReq.KeepAlive = False 'ASCIIモードで転送する ftpReq.UseBinary = False 'PASVモードを無効にする ftpReq.UsePassive = False Try 'ファイルをアップロードするためのStreamを取得 Dim reqStrm As System.IO.Stream = ftpReq.GetRequestStream() 'アップロードするファイルを開く Dim fs As New System.IO.FileStream( _ upFile, System.IO.FileMode.Open, System.IO.FileAccess.Read) 'アップロードStreamに書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = fs.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If reqStrm.Write(buffer, 0, readSize) End While fs.Close() reqStrm.Close() UpRoad = False Exit For Catch wex As System.Net.WebException Dim Err As String = wex.Status If Err = "2" Then UpRoad = True Exit For Else Int_Err = Int_Err + 1 If Int_Err = 3 Then System.IO.File.WriteAllText("C:\UL.log", wex.ToString) UpRoad = True Exit For Else Exit Try '10秒間(10000ミリ秒)停止する System.Threading.Thread.Sleep(10000) End If End If End Try Next End Function 「Streamを取得」=>「ファイルを開く」=>「Streamに書き込む」 のような手順でアップロードが行われています。 「Streamを取得」したあとに、サーバー側で接続を切断された場合reqStrm.Close() が実行されないまま、例外処理にはいります。 (つまり接続しっぱなしの状態になってしまいます) このような例外的なことが起こった場合でも、確実に切断(reqStrm.Close())されるにはどのようにソースを修正したらよろしいでしょうか? ご教授よろしくお願いします。

  • リストボックスの内容を テキストファイルに出力

    エクセル vba初心者です。 (1)ini fileからデータを取得 (2)その内容のリストボックスに表示 (3)リストボックス内容をテキストボックスに出力 (2)、(3)がわかりません。 なんとなくやってたら余計にわからなくなりました。助けてください。 Private Sub CommandButton1_Click() '読込み(1)を押した時の処理 Dim listbox As String Dim strL_Data As String '取得した値 Dim n As Integer n = FreeFile    ListBox1.Clear   Open "C:\filepath.ini" For Input As #n Do While Not EOF(n) Line Input #n, listbox ListBox1.AddItem listbox Loop Close #n End Sub Private Sub CommandButton2_Click() '書込み(1)を押した時の処理  Dim listbox As String Dim strL_Data As String '取得した値 Dim n As Integer n = FreeFile    Open "c:\example.txt" For Output As #n Print #n, strL_Data Close #n End Sub よろしくお願いいたします。

  • VB.NETのメモリ領域について

    VB.NETのメモリ領域について 以下の(1)~(12)の変数のために、 スタック領域、静的領域、ヒープ領域のどこのメモリが使われるか教えてください。 Class Sample   Dim a As Integer '(1)   Dim b As String = "BBB" '(2)   Shared c As Integer '(3)   Shared d As String = "DDD" '(4)   Sub X()     Dim f As Integer '(5)     Dim g As String = "GGG" '(6)     Static h As Integer '(7)     Static i As String = "III" '(8)   End Sub   Shared Sub Y()     Dim k As Integer '(9)     Dim l As String = "LLL" '(10)     Static m As Integer '(11)     Static n As String = "NNN" '(12)   End Sub End Class それぞれこんな認識で合ってますか? スタック領域 (1)(5)(9) スタック領域にポインタ+ヒープ領域に実体 (2)(6)(10) 静的領域 (3)(7)(11) 静的領域にポインタ+ヒープ領域に実体 (4)(8)(12)

  • VB2008 2バイト文字の化け字は当然! Yes or No?

    Function FileGetChar(ByVal f As String, ByVal p As Integer) As String   Dim n As Integer = FreeFile()   Dim c As Char = “”   If File.Exists(f) Then     FileOpen(n, f, OpenMode.Random, OpenAccess.Read, , 1)     Seek(n, p)     If Not EOF(n) Then       FileGet(n, c)     End If     FileClose(n)   End If   Return c End Function このようにSeek関数とFileGet関数を利用する限りでは2バイト文字の化け字は避けられない! 一体、この私の判断は正しいのでしょうか? VB2008 Express Edition

  • 【VB.Net】バイト型配列に読み込んで改行区切り

    教えて下さい。 ファイルをバイト型配列に読み込んで、ある固定長に区切(改行)って出力したいです。 以下簡単にサンプルとして作っているのが以下です。 【読み込みファイル.txt】 ---------------------------------------------------------------------------------- AB ---------------------------------------------------------------------------------- このテキストファイルの内容(byte型では、"41 42")を1バイトづつに改行で区切りたいです。 【VB.Net】 ---------------------------------------------------------------------------------- Dim BUFSIZE As Integer = 1 ' 1バイトづつ処理 Dim buf(BUFSIZE) As Byte ' 読み込み用バッファ Dim readSize As Integer ' Readメソッドで読み込んだバイト数 Dim srcName As String = "C:\Temp\読み込みファイル.txt" ' 読み込みファイル名 Dim dstName As String = "C:\Temp\書き込みファイル.txt" ' 書き込みファイル名 Using src As New FileStream(srcName, FileMode.Open, FileAccess.Read) Using dest As New FileStream(dstName, FileMode.Create, FileAccess.Write) While True ' 1バイト読み込み readSize = src.Read(buf, 0, BUFSIZE) ' 読み込むものが無ければ終了 If readSize = 0 Then Exit While ' 改行いれたい部分(動かないけど、、、) buf = (0D,0A) ' 書き込み dest.Write(buf, 0, BUFSIZE) End While End Using End Using ---------------------------------------------------------------------------------- ↓ 理想の処理後 【書き込みファイル.txt】 ---------------------------------------------------------------------------------- A B ---------------------------------------------------------------------------------- 重要なのはバイト型で処理を行いたいです。(文字列ではない) すいませんがよろしくお願いします。

  • VB 2008: Do Whie...Loop文について

    Function FileGetChar(ByVal f As String, ByVal p As Integer) As String   Dim i As Integer = 1   Dim j As Integer = 0   Dim l As Integer   Dim n As Integer = FreeFile()   Dim c As Char   If File.Exists(f) Then     FileOpen(n, f, OpenMode.Random, OpenAccess.Read, , 1)     l = FileLen(f)     Do While (i + j <= l)       FileGet(n, c, i + j)       j = j - (Math.Abs(Asc(c)) > 255)       i = i + 1       If i > p Then         Exit Do       Else         c = ""       End If     Loop     FileClose(n)   End If   Return c End Function [イミディエイトウインドウ] ? FileGetChar("D:\Temp\Test.txt",1) "1" ? FileGetChar("D:\Temp\Test.txt",2) "2" と、一応は動作しています。 l------->ファイル長 i+j----->読み込みのカレントポジション p------->読み込み指示ポジション 今、悩んでいるのはDo...Loop文中のIf Else End If の追放。 何か妙手があれば教えて頂きたい。

  • VB  FOR~NEXTについて

    下記の変数の宣言で、For w As Integer = 1 To 100 のWにチェックが付、デバックできません、考えられる点はどんな事があるのでしょうか? ご教授お願いします。 ' Button4のClickイベントを処理します。 Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click ' LineData用の変数です。 Dim cadLineData As New zwDrawCAD.LineData ' 線分の始点と終点を参照します。 Dim cadStartPoint As zwDrawCAD.DPoint = cadLineData.Start Dim cadEndPoint As zwDrawCAD.DPoint = cadLineData.End 'とりあえず線のセンターポイントは(100,100)にしてます。 Const X As Integer = 0 'cadStartPoint.x = 100 Const y As Integer = 0 'cadStartPoint.x = 100 Dim sr As System.IO.StreamReader = Nothing Try Dim file As String = TextBox1.Text 'SRとは New System.IO.StreamReaderの略 sr = New System.IO.StreamReader(file, System.Text.Encoding.GetEncoding("shift_jis")) Dim ansx As Double '計算された、xの座標 Dim ansy As Double '計算された、yの座標 Dim doc As String 'fileの1行 Dim x1 As String '1列目(X) Dim y2 As String '2列目(y)、 Dim x3 As String '3列目(X1)、 Dim y4 As String '4列目(y2) Dim angle As String '5列目(角度)、 Dim spare As String '6列目(予備)、 Dim item() As String ' Dim i As Integer '1行ずつテキストを読み取る doc = sr.ReadLine '1行読む Do Until IsNothing(doc) i += 1 item = doc.Split(",") 'カンマで区切る x1 = item(0) y2 = item(1) x3 = item(2) y4 = item(3) angle = item(4) spare = item(5) f2.data(x1, y2, x3, y4, angle, spare) f2.int(i) TextBox2.Text &= item(0) & " " & item(1) & " " & item(2) & " " & item(4) & " " & item(5) & " " & vbNewLine doc = sr.ReadLine '次の1行を読む Loop f2.println() Catch ex As Exception MessageBox.Show(ex.Message, "read") Finally If sr IsNot Nothing Then sr.Close() sr.Dispose() End If Dim len As Integer 'TextBox1に入力された線の長さ Dim angle As Double 'TextBox2に入力された角度 単位は度 Dim ansx As Double '計算された、xの座標 Dim ansy As Double '計算された、yの座標 '変数の宣言 Dim w As Integer Dim i As Integer '初期化 w = 0 i = 0 For w As Integer = 1 To 100 len = CDbl("x1" / 2) angle = CDbl(angle + 90) ansx = X + len * (Math.Cos(angle / 180 * Math.PI)) '終点のx座標 ansy = y + len * (Math.Sin(angle / 180 * Math.PI)) '終点のy座標 cadStartPoint.x = ansx * -1 cadStartPoint.y = ansy * -1 cadEndPoint.x = ansx cadEndPoint.y = ansy w = w + 1 Next End Try

  • 以前に回答いただいたVBAですが、理解できない部分があったので、抜粋し

    以前に回答いただいたVBAですが、理解できない部分があったので、抜粋して質問に投稿したところ、多くの方々から、「これでは、わからない」などの指摘をいただき、これでは、以前に回答していただいた回答者様の名誉にかかわると思い全文を記載させていただくことにしました。  あわせて、この、VBAの詳しい説明を快くしていただける方は回答よろしくお願いします。以下のとうりです。  A列  B列 1 期間  90 2 人数  21 3 4 氏名  回数 5 A   23 6 B   23 7 C   19 8 D   16 9 E   12 10 F   9 11 G   8 12 H   7 13 I   7 14 J   6 15 K   6 16 L   6 17 M   5 18 N   5 19 O   4 20 P   4 21 Q   4 22 R   4 23 S   4 24 T   4 25 U   4 Sub 当番割当() Dim 期間 As Integer Dim 人数 As Integer Dim 氏名() As String Dim 回数() As Integer Dim i As Integer Dim j As Integer Dim k As Integer Dim m As Integer Dim n As Integer Dim n1 As Integer Dim n2 As Integer Dim p As Single Dim q As Single Dim 当番() As String Dim 担当() As Single 期間 = Cells(1, 2) 人数 = Cells(2, 2) ReDim 氏名(人数) ReDim 回数(人数) For i = 1 To 人数 氏名(i) = Cells(4 + i, 1) 回数(i) = Cells(4 + i, 2) Next i ReDim 当番(期間 * 2) ReDim 担当(期間 * 2) n = 0 For i = 1 To 人数 n1 = 0 n2 = 0 For j = 1 To 人数 If 回数(j) = 回数(i) Then n1 = n1 + 1 If j <= i Then n2 = n2 + 1 End If Next j p = 期間 / 回数(i) For j = 1 To 回数(i) q = p * (n2 - 0.5) / n1 + p * (j - 1) m = 1 For k = n To 1 Step -1 If 担当(k) <= q Then m = k + 1 Exit For End If 当番(k + 1) = 当番(k) 担当(k + 1) = 担当(k) Next k 当番(m) = 氏名(i) 担当(m) = q n = n + 1 Next j Next i Range("E:G").Clear For n = 1 To 期間 Cells(n, 5) = n & "日" Cells(n, 6) = 当番(n * 2 - 1) Cells(n, 7) = 当番(n * 2) Next n End Sub

  • VBA初心者です。プログラム教えてください。

    行1にA~Kの値があり、この範囲で、A列に同じ値が入っている限り1、2、3と始まる値が入るよう処理をする。A列の値が変ったら、また1からスタートする値が入るよう処理をしたい。 Sub Work() Dim M As Integer Dim N As Integer M = 2 N = 2 Do While Cells(2 ,N) <> "" Cells(3 , N) <> "" Or C = Cells(3 , N - 1)  (1) N = N + 1 Loop End Sub 上記を作りましたが、(1)の所でデバックしてしまいます。 解決策をぜひ教えてください。よろしくお願いします。

専門家に質問してみよう