我要读的是文本文件,可是读不出来 源程序如下 dim para(10,10) as varint dim a as integer dim b as integer open app.path & "\a.sys" for Binary as #1 Get #1,,para() close #1 for a= 0 to 10 for b= 0 to 10 list1.additem para(a,b) next b next a
读出来的都是空字符。 可是同样的源码,在别人写的程序里却能读出来,为什么??
你的问题是没有给数组分配内存空间:Private Sub Command1_Click() Dim arr() As Byte Dim i As Long Dim filename As String filename = App.Path & "\a.sys" i = FileLen(filename) ReDim arr(i - 1)
Open filename For Binary As #1 Get #1, , arr Close #1 Dim s As String s = StrConv(arr, vbUnicode)'这也是关键 Dim listarr listarr = Split(s, vbCrLf) Dim j As Long For j = 0 To UBound(listarr) List1.AddItem listarr(j) Next End Sub
你可以参考下面的程序. (行读入方式在如果文件很大时,例如达到1M以上时,比一次性读入要快得多,读小文件时两者差不多)' '读TEXT文件 '函数:RedTextFile '参数:FileName 打开的TXT文件名. '返回值:成功 返回文件内容.失败 返回"" Public Function RedTextFile(Filename As String) As String Dim FileID As Long Dim InputStr As String Dim LineStr As String
On Error Resume Next
InputStr = "": LineStr = "" FileID = FreeFile() Open Filename For Input As #FileID Do While Not EOF(FileID) ' 循环至文件尾。 LineStr = "" Line Input #FileID, LineStr InputStr = InputStr & LineStr Loop Close #FileID RedTextFile = IIf(Err.Number = 0, InputStr, "") Err.Clear End Function
回rainstormmaster(暴风雨 v2.0) 这是VB处理字符串的一个问题,很多人认为,一次性地读入一大堆数据会加快读入的速度,其实,也是很多人的误区. 打个比方吧.例如.你有没有编写字符查找的函数:DIM TT AS STRING FOR A=0 TO LEN(TT) 程序处理...... NEXT如果TT只有1K左右,你一定会觉得速度不错,但是,当TT的长度达到例如256K时,你试看,兄弟,你等吧.但是,当将256K分成256个等份,每份1K,你试试看两者的速度差别.还有,你一定用保存网格:MSHFLEXGRID了,我想,你一定也是用MSDN中的方法,就是把一个文件LOAD到一个字符串变量中,然后,是MSHFlexGrid1.Clip = myStr.当然,你的文件很小时,它的确工作得很好,但是,当你的文件达到例如:R20000*C30时,你再用该方法试试看,是不是好象死机了?但是,当我们以行读入的方式,一行一行地读入,一行一行地加载,它只需要1.98秒.如果再适当优化一下,可以达到0.8秒左右.对VB来说,处理大字符串时可以是一个BUG.处理一个128K字符串所需要时间并不32K的四位,而是更多,也许是16位左右,几科呈一个几何级数来增长.你已经有两个星了,想必在这里的时间也比较久了.而我,只是前二天才注CSDN的,我只有两个三个星,我本来不想说这么多,但是,你讽剌了我!!!
不用了,谢谢:)今天上午找了个3M的文本文件(170000行)测试了一下,如果按照你的方法将文件的全部内容读取到一个字串并在立即窗口输出每一行内容的话,我用了1小时30多分钟,而用我的方法只用了一分40秒//Open Filename For Input As #FileID Do While Not EOF(FileID) ' 循环至文件尾。 LineStr = "" Line Input #FileID, LineStr InputStr = InputStr & LineStr Loop Close #FileID 这句会明显降低速度 InputStr = InputStr & LineStr如果,不全部读出到字串的话,速度倒是差不多,你的算法只比我的慢几秒而已,不说也罢最后,祝你春节快乐
兄台,你错了,优化过程并非如君所述! 且看下面两个函数(由于是从我的类库是直接COPY出来的,所以,需要小改才能在你的计算机上运行). LoadFileToGrid 将文件加载到表格. SaveFile 将表格保存成文件. LoadFileToGrid 只能装载由SAVEFILE保存的表格文件.' '加载一个文件到表格. '函数:LoadFileToGrid '参数:FileName 加载的文件名 '返回值:=True 成功.=True 失败. Public Function LoadFile(FileName As String) As Long Dim InputID As Long, FileID As Long Dim EndRow As Long, DltAdd As Long Dim AddFlag As Boolean Dim KeyTab As String, KeyEnter As String Dim FixedRows As Long, FixedCols As Long Dim GridInput As String, AddSum As String, RowColMax() As String Dim GridColMax As Long, GridRowMax As Long Dim OleRow As Long, OleCol As Long Dim SumFmtStr As String Dim DltCol As Long
On Error Resume Next
Timer1.Enabled = False With Ev_GridObj M_MoveFlag = False UserControl.Extender.Visible = False .Redraw = False OleRow = M_EditRow: OleCol = M_EditCol Err.Clear: SetAttr FileName, 0 If Err.Number <> 0 Then '如果文件不存在 Err.Clear Call SaveFile(FileName) .Redraw = True GoTo EndReutrn Exit Function End If
FileID = FreeFile Open FileName For Input As #FileID Do While Not EOF(FileID) ' 循环至文件尾。 Line Input #FileID, GridInput If InputID <= 1 Then If InputID = 0 Then RowColMax = Split(GridInput, "|") GridRowMax = CLng("0" & RowColMax(0)): GridColMax = CLng("0" & RowColMax(1)) If CLng("0" & RowColMax(0)) < 2 Then GridRowMax = 1 If CLng("0" & RowColMax(1)) < 2 Then GridColMax = 1 .Rows = GridRowMax: .Cols = GridColMax Else SumFmtStr = GridInput '格式字符串. End If Else If AddFlag Then AddSum = AddSum & KeyEnter & GridInput Else AddSum = GridInput: AddFlag = True End If '/------------------------------------------------------ If (InputID - DltCol) Mod DltAdd = 0 Then .Row = InputID - DltAdd - DltCol: .Col = 0 .RowSel = InputID - 1 - DltCol: .ColSel = GridColMax - 1 .Clip = AddSum: AddSum = "" EndRow = InputID - DltCol: AddFlag = False End If End If InputID = InputID + 1 Loop '/-------------------------------------------------------- If (InputID - DltCol) - EndRow > 1 Then .Row = EndRow: .Col = 0 .RowSel = GridRowMax - 1 .ColSel = GridColMax - 1 .Clip = AddSum AddSum = "" End If Close #FileID
Call FormatGrid(SumFmtStr)
.FixedRows = CLng("0" & RowColMax(2)): .FixedCols = CLng("0" & RowColMax(3)) .Redraw = True If (OleRow > 0 And M_EditCol > 0) And _ (OleRow < .Rows - 1 And OleCol < .Cols - 1) And _ (OleRow > .FixedRows And OleCol > .FixedCols) Then M_EditRow = OleRow: M_EditCol = OleCol Call GridMouseDown Else If .Rows > .FixedRows And .Cols > .FixedCols Then .Row = .FixedRows .Col = .FixedCols .RowSel = .FixedRows .ColSel = .FixedCols End If End If M_MoveFlag = True End WithEndReutrn: Timer1.Enabled = M_Author LoadFile = Err.Number M_OleRow = 0: M_OleCol = 0 End Function' '保存表格数据 '函数:SaveFile '参数:FileName 加载的文件名 '返回值:=True 成功.=True 失败. Public Function SaveFile(FileName As String) As Boolean '/保存文件 Dim FileID As Long, ConTents As String Dim A As Long, B As Long Dim RowMax As Long, ColMax As Long Dim FixRows As Long, FixCols As Long Dim OleRow As Long, OleCol As Long Dim SFmtStr As String
Do While Not EOF(1)
Line Input #1, tempState
lineNum = lineNum + 1
Loop
直接用FileSystemObject对象中的OpenTextFile方法就可以了。
源程序如下
dim para(10,10) as varint
dim a as integer
dim b as integer
open app.path & "\a.sys" for Binary as #1
Get #1,,para()
close #1
for a= 0 to 10
for b= 0 to 10
list1.additem para(a,b)
next b
next a
读出来的都是空字符。
可是同样的源码,在别人写的程序里却能读出来,为什么??
Dim arr() As Byte
Dim i As Long
Dim filename As String
filename = App.Path & "\a.sys"
i = FileLen(filename)
ReDim arr(i - 1)
Open filename For Binary As #1
Get #1, , arr
Close #1
Dim s As String
s = StrConv(arr, vbUnicode)'这也是关键
Dim listarr
listarr = Split(s, vbCrLf)
Dim j As Long
For j = 0 To UBound(listarr)
List1.AddItem listarr(j)
Next
End Sub
(行读入方式在如果文件很大时,例如达到1M以上时,比一次性读入要快得多,读小文件时两者差不多)'
'读TEXT文件
'函数:RedTextFile
'参数:FileName 打开的TXT文件名.
'返回值:成功 返回文件内容.失败 返回""
Public Function RedTextFile(Filename As String) As String
Dim FileID As Long
Dim InputStr As String
Dim LineStr As String
On Error Resume Next
InputStr = "": LineStr = ""
FileID = FreeFile()
Open Filename For Input As #FileID
Do While Not EOF(FileID) ' 循环至文件尾。
LineStr = ""
Line Input #FileID, LineStr
InputStr = InputStr & LineStr
Loop
Close #FileID
RedTextFile = IIf(Err.Number = 0, InputStr, "")
Err.Clear
End Function
打个比方吧.例如.你有没有编写字符查找的函数:DIM TT AS STRING
FOR A=0 TO LEN(TT)
程序处理......
NEXT如果TT只有1K左右,你一定会觉得速度不错,但是,当TT的长度达到例如256K时,你试看,兄弟,你等吧.但是,当将256K分成256个等份,每份1K,你试试看两者的速度差别.还有,你一定用保存网格:MSHFLEXGRID了,我想,你一定也是用MSDN中的方法,就是把一个文件LOAD到一个字符串变量中,然后,是MSHFlexGrid1.Clip = myStr.当然,你的文件很小时,它的确工作得很好,但是,当你的文件达到例如:R20000*C30时,你再用该方法试试看,是不是好象死机了?但是,当我们以行读入的方式,一行一行地读入,一行一行地加载,它只需要1.98秒.如果再适当优化一下,可以达到0.8秒左右.对VB来说,处理大字符串时可以是一个BUG.处理一个128K字符串所需要时间并不32K的四位,而是更多,也许是16位左右,几科呈一个几何级数来增长.你已经有两个星了,想必在这里的时间也比较久了.而我,只是前二天才注CSDN的,我只有两个三个星,我本来不想说这么多,但是,你讽剌了我!!!
Do While Not EOF(FileID) ' 循环至文件尾。
LineStr = ""
Line Input #FileID, LineStr
InputStr = InputStr & LineStr
Loop
Close #FileID
这句会明显降低速度
InputStr = InputStr & LineStr如果,不全部读出到字串的话,速度倒是差不多,你的算法只比我的慢几秒而已,不说也罢最后,祝你春节快乐
且看下面两个函数(由于是从我的类库是直接COPY出来的,所以,需要小改才能在你的计算机上运行).
LoadFileToGrid 将文件加载到表格.
SaveFile 将表格保存成文件.
LoadFileToGrid 只能装载由SAVEFILE保存的表格文件.'
'加载一个文件到表格.
'函数:LoadFileToGrid
'参数:FileName 加载的文件名
'返回值:=True 成功.=True 失败.
Public Function LoadFile(FileName As String) As Long
Dim InputID As Long, FileID As Long
Dim EndRow As Long, DltAdd As Long
Dim AddFlag As Boolean
Dim KeyTab As String, KeyEnter As String
Dim FixedRows As Long, FixedCols As Long
Dim GridInput As String, AddSum As String, RowColMax() As String
Dim GridColMax As Long, GridRowMax As Long
Dim OleRow As Long, OleCol As Long
Dim SumFmtStr As String
Dim DltCol As Long
On Error Resume Next
Timer1.Enabled = False
With Ev_GridObj
M_MoveFlag = False
UserControl.Extender.Visible = False
.Redraw = False
OleRow = M_EditRow: OleCol = M_EditCol
Err.Clear: SetAttr FileName, 0
If Err.Number <> 0 Then '如果文件不存在
Err.Clear
Call SaveFile(FileName)
.Redraw = True
GoTo EndReutrn
Exit Function
End If
KeyTab = Chr$(vbKeyTab): KeyEnter = Chr$(13)
InputID = 0: AddSum = ""
AddFlag = False: DltAdd = 25: DltCol = 1
.Redraw = False: .FixedRows = 0: .FixedCols = 0
FileID = FreeFile
Open FileName For Input As #FileID
Do While Not EOF(FileID) ' 循环至文件尾。
Line Input #FileID, GridInput
If InputID <= 1 Then
If InputID = 0 Then
RowColMax = Split(GridInput, "|")
GridRowMax = CLng("0" & RowColMax(0)): GridColMax = CLng("0" & RowColMax(1))
If CLng("0" & RowColMax(0)) < 2 Then GridRowMax = 1
If CLng("0" & RowColMax(1)) < 2 Then GridColMax = 1
.Rows = GridRowMax: .Cols = GridColMax
Else
SumFmtStr = GridInput '格式字符串.
End If
Else
If AddFlag Then
AddSum = AddSum & KeyEnter & GridInput
Else
AddSum = GridInput: AddFlag = True
End If
'/------------------------------------------------------
If (InputID - DltCol) Mod DltAdd = 0 Then
.Row = InputID - DltAdd - DltCol: .Col = 0
.RowSel = InputID - 1 - DltCol: .ColSel = GridColMax - 1
.Clip = AddSum: AddSum = ""
EndRow = InputID - DltCol: AddFlag = False
End If
End If
InputID = InputID + 1
Loop
'/--------------------------------------------------------
If (InputID - DltCol) - EndRow > 1 Then
.Row = EndRow: .Col = 0
.RowSel = GridRowMax - 1
.ColSel = GridColMax - 1
.Clip = AddSum
AddSum = ""
End If
Close #FileID
Call FormatGrid(SumFmtStr)
.FixedRows = CLng("0" & RowColMax(2)): .FixedCols = CLng("0" & RowColMax(3))
.Redraw = True
If (OleRow > 0 And M_EditCol > 0) And _
(OleRow < .Rows - 1 And OleCol < .Cols - 1) And _
(OleRow > .FixedRows And OleCol > .FixedCols) Then
M_EditRow = OleRow: M_EditCol = OleCol
Call GridMouseDown
Else
If .Rows > .FixedRows And .Cols > .FixedCols Then
.Row = .FixedRows
.Col = .FixedCols
.RowSel = .FixedRows
.ColSel = .FixedCols
End If
End If
M_MoveFlag = True
End WithEndReutrn:
Timer1.Enabled = M_Author
LoadFile = Err.Number
M_OleRow = 0: M_OleCol = 0
End Function'
'保存表格数据
'函数:SaveFile
'参数:FileName 加载的文件名
'返回值:=True 成功.=True 失败.
Public Function SaveFile(FileName As String) As Boolean
'/保存文件
Dim FileID As Long, ConTents As String
Dim A As Long, B As Long
Dim RowMax As Long, ColMax As Long
Dim FixRows As Long, FixCols As Long
Dim OleRow As Long, OleCol As Long
Dim SFmtStr As String
On Error Resume Next
Timer1.Enabled = False
With Ev_GridObj
M_MoveFlag = False
UserControl.Extender.Visible = False
.Redraw = False
OleRow = M_EditRow: OleCol = M_EditCol
FixRows = .FixedRows: FixCols = .FixedCols
RowMax = .Rows - 1: ColMax = .Cols - 1
.FixedRows = 0: .FixedCols = 0
FileID = FreeFile
For A = 0 To ColMax '将格式字符串取出.
SFmtStr = SFmtStr & MakeFmtStr(A, True)
Next
Open FileName For Output As #FileID
ConTents = RowMax + 1 & "|" & ColMax + 1 & "|" & FixRows & "|" & FixCols & "|"
Print #FileID, ConTents '保存总的行数和列数.
Print #FileID, SFmtStr '保存格式字符串.
For A = 0 To RowMax
.Row = A: .Col = 0
.RowSel = A: .ColSel = ColMax
ConTents = .Clip
Print #FileID, ConTents
Next A
Close #FileID
.FixedRows = FixRows: .FixedCols = FixCols
.Redraw = True
If (OleRow > 0 And M_EditCol > 0) And _
(OleRow < .Rows - 1 And OleCol < .Cols - 1) And _
(OleRow > .FixedRows And OleCol > .FixedCols) Then
M_EditRow = OleRow: M_EditCol = OleCol
Call GridMouseDown
End If
M_MoveFlag = True
End With
Timer1.Enabled = M_Author
M_OleRow = 0: M_OleCol = 0
SaveFile = (Err.Number = 0)
Err.Clear
End Function
二位争吵确实有意思, 可以肯定mstop(cjh)你是错的 :) 原因下述1:全部读取比一次一行要快的多. 你测试的文件R20000*C30不足以说明问题
该文件连1m都没有..居然也来测试..... 要知道现在不是dma33的年代
昨天ghost一个80g的硬盘只要44分钟..汗..按这个速度你自己算算1m文件要多久..
以单从文件读出内容来说(不进一步操作)
我做实验证明. 对于一个500M的文件. 一次1byte硬盘偶尔亮下,一次1k硬盘闪个不停
一次10k.100k more..已经没有区别了. 只听硬盘叫个不停. 至于和行读入的时间相差
多少呢? 由于我等不了行读入把文件读完.强制关闭了ide.也就无从计算了.2: 但是,当你的文件达到例如:R20000*C30时,你再用该方法试试看,是不是好象死机了?
该方法指的是? 你有没有试过? 请试过在说.3: 你知道str处理速度慢. 可为什么会这么慢了? 因为会频繁的malloc free memory
但你在说明str速度慢的时候偏偏犯了这个致命错误. LOOK Do While Not EOF(FileID) ' 循环至文件尾。
LineStr = "" ' 该行其实没必要
Line Input #FileID, LineStr
InputStr = InputStr & LineStr
Loop InputStr = InputStr & LineStr 慢在这个地方!
就是因为vb智能程度不高.不知道你这个str会不断增加.原先malloc的内存无法承受
于是重新malloc && copymemory 不过可以用以下改进.保证速度有了质的提高:
打开先 inputstr=space(1000000):startpos = 1 先分配内存
然后用 mid函数覆盖 (mid函数不会copy内存.前提是容量足够,覆盖大小相同)
mid(inputstr, startpos, len(linestr)) = linestr
startpos = startpos + linestr
关闭文件后
inputstr = left(inputstr, startpos-1) (left函数不会copy内存)
当然你可以发现startpos>1000000的时候进一步处理. rainstormmaster的方法快在内存重分配少上. 而且读文件速度也比你快, 所以
"如果,不全部读出到字串的话,速度倒是差不多,你的算法只比我的慢几秒而已,不说也罢"
有次结果.
ps: