Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Byta ut textrader i textfil?

Postades av 2001-02-13 20:37:00 - Lars Sellbom, i forum visual basic - allmänt, Tråden har 18 Kommentarer och lästs av 3049 personer

Skulle vilja att min VB applikation bytte ut de två sista raderna i en textfil mot två nya rader. Hur kommer man åt just de två sista raderna?


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-13 21:02:00 - Peter Holm

Tja du.... Som vanligt finns det skitmånga sätt att fixa problemet på....

Är det en stor fil är inte följande sätt det bästa..... Men för mindre filer duger det så himla bra så.....

============================================

Private Sub Command1_Click()
Dim path As String
Dim file As String
Dim fil As String
Dim filRad() As String
Dim fNr As Integer
path = "c:\minmapp\"
file = "minfil.txt"
If Dir(path & file) <> "" Then
fNr = FreeFile()
Open path & file For Binary Access Read As #fNr
fil = Space$(LOF(fNr))
Get #fNr, , fil
Close #fNr
filRad() = Split(fil, vbCrLf, -1, vbTextCompare)
filRad(UBound(filRad()) - 2) = "Ersättningsrad 1" 'Näst sista raden
filRad(UBound(filRad()) - 1) = "Ersättningsrad 2" 'Sista raden
Open "c:\test.txt" For Binary Access Write As #fNr
Put #fNr, , Join(filRad(), vbCrLf)
Close #fNr
End If
End Sub

============================================

Lycka till...

/peterh <=> hpeter


Svara

Sv: Byta ut textrader i textfil? Tack hpeter!!

Postades av 2001-02-14 06:45:00 - Lars Sellbom

Tack hpeter!


/lsm


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 14:37:00 - Sven Åke Persson

Hej
>Hur kommer man åt just de två sista raderna?

Som sagt det finns olika sätt att lösa problemmet

Så här löser jag det

Option Explicit

Private Sub Command1_Click()
Call SistaRader
End Sub

Private Sub SistaRader()
Dim dummy As String * 1
Dim rader As Long, i As Long, tmpStr As String
Dim FileNum As Long, FileNum2 As Long

FileNum = FreeFile
Open "Test.txt" For Input As FileNum
FileNum2 = FreeFile
Open "Test.###" For Append As FileNum2
Do Until EOF(FileNum)
'Ta reda på antal rader
Line Input #FileNum, dummy
rader = rader + 1
Loop
Close #FileNum
FileNum = FreeFile
Open "Test.txt" For Input As FileNum
For i = 1 To rader - 2
Line Input #FileNum, tmpStr
Print #FileNum2, tmpStr
Next ' i
Print #FileNum2, "Min utbytes rad 1"
Print #FileNum2, "Min utbytes rad 2"
Close #FileNum
Close #FileNum2
Kill "Test.txt"
FileCopy "Test.###", "Test.txt"
Kill "Test.###"
End Sub

Testa och kommentera gärna
Mvh
Sven



Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 15:55:00 - Sven Åke Persson

Hej igen
Eftersom vi har disskuterat optimering så roade
jag mig med att göra en tidskontroll på "hpeters" lösning
och min

Resultat : SvenPon : s 3.18 sek
hpeter : s 5.60 sek

dvs skillnad på 45 %

Båda löste problemmet men Obs !
om textfilen:ens två sista rader är blankrader
kan resultat se förvirrande ut

mvh
Sven


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 17:41:00 - Peter Holm

SvenPon.... Undrar om du noterade följande text i min lösning...

> Är det en stor fil är inte följande sätt det bästa..... Men för mindre filer duger det så himla bra så.....


Det är inte så smart att allokera minne (sträng, dynamiskt för att lösa problemet)

Men som sagt för små filer funkar det finfint.

/peterh


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 17:48:00 - Sven Åke Persson

Igen
> Är det en stor fil är inte följande sätt det bästa.....

Hur vet du att jag kollat mot stor fil ???

DS


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 18:04:00 - Sven Åke Persson

Igen
> Dim fNr As Integer
En liten detalj

I 32 bits system skall du i princip aldrig deklarera Integer

det bytyder att processorn får göra några extra onödiga
runder för att vaska fram en Integer

DS


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 19:06:00 - Andreas Hillqvist

Får väl anta utmaningen... :O)

Liten beskrivning:
Fuskar ju lite med api anrop.
Söker enbart på tecknet cr (13). Har sina för och nackdelar.
Tar även med tomma rader från slutet.
Men den är betydligt mycket snabbare än tidigare två exempel i vilket hela filen läses och skrivs om. Vilket inte gör så mycket med små filer.
Men om filerna är över 1MB går det inte att jämföra funktionernas hastighet.
Desutom är min funktion lite mer dynamisk efter som man kan ang en eller flera rader.
Ex:
<code>
ReplaceLinesRev "c:\Test.txt","Sista raden"

ReplaceLinesRev "c:\Test.txt","Näst sista raden","Sista raden"

ReplaceLinesRev "c:\Test.txt","Raden innan dess...", "Näst sista raden","Sista raden"
</code>
osv...

Som sagt om man kan acceptera bristerna i min funktion så duger den nog...

Mitt bidrag:
<code>
Private Const FILE_BEGIN = 0
Private Const OPEN_EXISTING = 3
Private Const INVALID_HANDLE_VALUE = -1
Private Const GENERIC_WRITE = &H40000000

Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function SetEndOfFile Lib "kernel32" (ByVal hFile As Long) As Long

Public Function SetEOF(FileName As String, EOF As Long) As Boolean
Dim hFile As Long
Dim lReturn As Long
hFile = CreateFile(FileName, GENERIC_WRITE, 0&, ByVal 0&, OPEN_EXISTING, 0&, 0&)
If hFile = INVALID_HANDLE_VALUE Then
SetEOF = False
Else
lReturn = SetFilePointer(hFile, EOF, 0&, FILE_BEGIN)
If lReturn = -1& Then
SetEOF = False
Else
SetEOF = SetEndOfFile(hFile)
End If
CloseHandle hFile
End If
End Function

Public Function ReplaceLinesRev(FileName As String, ParamArray Lines() As Variant)
Dim FileNo As Integer
Dim Location As Long
Dim Char As Byte
Dim Index As Integer
Dim Count As Integer
FileNo = FreeFile()

Open FileName For Binary Access Read Write As #FileNo
Location = LOF(FileNo)
Count = UBound(Lines) + 1
Do While Location And Index < Count
Get #FileNo, Location, Char
If Char = 13 Then
Index = Index + 1
End If
Location = Location - 1
Loop
Put #FileNo, Location + 1, vbCrLf & Join(Lines, vbCrLf)
Location = Seek(FileNo)
Close #FileNo

SetEOF FileName, Location - 1

End Function
</code>


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 19:34:00 - Sven Åke Persson

Hej
Proffsig lösning förutom detta

Dim Index As Integer 'skall vara Long
Dim Count As Integer 'skall vara Long

Sven ;-)


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 19:57:00 - Andreas Hillqvist

Tack så mycket. Försökte mitt bästa.
Skulle ju kunna gjort allt med API'er för att slippa att öppna och stänga filen två gånger. Men Det var enklare att använda de interna funktionerna för att läsa och skriva till filen.


Jag är tveksam på att VB klarar Parameter Arrayer med mer än 32 tusen poster. Tvecksam om det är mer än hundra. Så då räcker det väl med en integer. Skulle kansk ändra storleken till en byte.

Om det inte finns nån begränsning, lär det ju inte heller vara roligt att skriva den kod raden med 32000 parametrar... :O)

Om man skulle vilja ha mer rader än Parameter Arrayen tillåter, eller kunna ange dem dynamiskt. Så är det ju bara att göra om den till en sträng array och om nödvändigt konvertera till Long.


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 20:17:00 - Peter Holm

Jaha Andreas hann före denna gång....

Men min är ändock snabbast.... Om vi nu skall snacka optimering >>>> SvenPon.

Följande tider upopmättes på min PIII-800 Mhz då två sista raderna byts ut i en textfil. Textfilens storlek 1.89 MB

SvenPon: 622 ms
Andreas Hillqvist: 2-3 ms
peterh: 0-1 ms

SvenPon, min rutin klarar det på 1/622 del av din tid och drygt halva Andreas tid.

När jag exekverar min variant får jag oftast 0 ms, ibland 1 ms.

Min rutin har dock en svaghet. Textfilen måste sluta med en vbCrLF. Men detta borde den göra då man förmodligen lägger till vbCrLf efter alla rader man skriver till fil.

Observera att jag dessutom inte använder API förutom att mäta exekveringstiden.

Slå detta ni....... (Äntligen blev jag störst snabbast och bäst)

Här är mitt final bidrag......

=============================================

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Form_Load()
Dim startT As Single
startT = GetTickCount()
Dim CRLF As Byte
Dim filNamn As String
Dim filPekare As Long
Dim filLangd As Long
Dim filNummer As Integer
Dim position As Byte
Dim str As String
Dim notFound As Boolean
Const step = 3
filNummer = FreeFile()
filNamn = "C:\test.txt"
filLangd = fileLen(filNamn)
filPekare = filLangd
notFound = True
str = Space$(step)
Open filNamn For Binary As #filNummer
Do While notFound
filPekare = filPekare - step
Get #filNummer, filPekare, str
position = InStr(1, str, vbCr)
If position <> 0 Then
CRLF = CRLF + 1
ElseIf CRLF = 3 Then
filPekare = filPekare + position + step + 2
Exit Do
End If
Loop
Seek #filNummer, filPekare
Put #filNummer, , "ersättningsrad nummer 1" & vbCrLf
Put #filNummer, , "ersättningsrad nummer 2" & vbCrLf
Close #filNummer
Debug.Print GetTickCount() - startT
End Sub

=============================================

/peterh

emotser kommentarer.......


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 20:26:00 - Andreas Hillqvist

Använder API anropet för att minska filen om de infogade raderna är mindre än de tidigare. Klarar din funktion det?
Tänkte lägga in en koll så att API anropet enbart utfördes vid behov. Men struntade i det.
Du använder ju dig egentligen av samma princip som jag använder. Bara en snabbara implementerning genom att söka större stycken. Så jag vet inte om det är något att skryta med. Dessutom är det ingen gennerel funktion utan en explicit lösning på problemet.

Om man jämför min hastighetsförändring mot ditt först förslag så är ju din hastighets förändring försummbar... :O)

Men jag tackar dig för ditt bidrag, du slog mig vad det gäller tid. Grattis...


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 20:38:00 - Peter Holm

Tja... Det blir ju inte så noga mätt med gettickcount(), vi säger att det är dött lopp.

Däremot säger SvenPon att man inte skall deklarera integertyper i VB om man kör 32-bitars system....

Jag är beredd att hålla med men förklara då resultatet av följande körning:

=============================================

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Form_Load()
Dim a As Single
Dim i1 As Long, j1 As Long
Dim i2 As Integer, j2 As Integer
a = GetTickCount()
For i1 = 0 To 8192
For j1 = -32768 To 0
Next j1
Next i1
Debug.Print GetTickCount() - a

a = GetTickCount()
For i2 = 0 To 8192
For j2 = -32768 To 0
Next j2
Next i2
Debug.Print GetTickCount() - a

End Sub

============================================

/peterh


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 20:48:00 - Sven Åke Persson

Hej
Skall analyser lite senare Men ytterligare ett
optimeringsfel.

For i1 = 0 To 8192
        For j1 = -32768 To 0
        Next j1
    Next i1
Den här slingan blir onödigt långsam pga
att du skriver Next j1 Och Next i1

Skall vara Next 'j1 Next 'i1

Kolla får du se

Sen blir förmodligen din mätning inkorrekt därför
att du blandar in GetTickCount
Mät med Timer det duger bra

Tror jag
Sven



Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 20:58:00 - Andreas Hillqvist

Tack för upplysningen. Kände inte till det.

Två gånger på en dag har du "överlistat" mig.
Hmm, jag håller nog på att tappa stinget... :O)


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 21:41:00 - Peter Holm

Jag var inte ute efter att optimera något i exemplet....

Jag gjorde de nästlade loparna på detta sätt därför att jag naturligtvis fick en overflow för denna typ av loop.

for i = 0 to 32767
next i

då i=32767 exekveras ändå next i och genererar en overflow. Därför satte jag looparna att loopa från -32768 till 0 istället.

För övrigt så är loparnas längder anpassat så körningen inte tar alltför lång tid.

Vad beträffar

next i
next j

Så såg jag ingen skillnad i exekveringstid jämfört med

next i,j

Men kolla in exemplet nedan då om du tycker att det verkar vara mer rättvist..

===========================================

Option Explicit

Private Sub Form_Load()
Dim q As Integer
For q = 1 To 5
loopInt q
loopLong q
Next q
For q = 6 To 10
loopLong q
loopInt q
Next q
For q = 11 To 15
loopLong q
Next q
For q = 11 To 15
loopInt q
Next q
For q = 16 To 20
loopInt q
Next q
For q = 16 To 20
loopLong q
Next q
End Sub

Private Sub loopInt(q As Integer)
Dim i As Integer, j As Integer
Dim t As Single
t = Timer: For i = 0 To 10000: For j = 0 To 10000: Next j, i: Debug.Print "Integer: "; q, Timer - t
End Sub

Private Sub loopLong(q As Integer)
Dim k As Long, l As Long
Dim u As Single
u = Timer: For k = 0 To 10000: For l = 0 To 10000: Next l, k: Debug.Print "Long : "; q, Timer - u
End Sub

=============================================

/peterh


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 22:03:00 - Peter Holm

Apropå SvenPon & det där med GetTickCount()

======================================
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub withTimer()
Dim t1 As Single
Dim t2 As Single
t1 = GetTickCount()
t2 = Timer
While Timer < (t2 + 5): Wend
Debug.Print (GetTickCount() - t1) * (Timer - t2) / 5000
End Sub

Private Sub withTickCount()
Dim t1 As Single
Dim t2 As Single
t1 = GetTickCount()
t2 = Timer
While GetTickCount() < (t1 + 5000): Wend
Debug.Print (GetTickCount() - t1) * (Timer - t2) / 5000
End Sub

Private Sub Form_Load()
withTickCount
withTimer
End Sub

=======================================

SÅvitt kan jag se det är det hugget som stucket, vilken som är bäst
att använda... Därför duger det med Timer.

Man får ju för sig att API är bättre i alla lägen... Men så är det ej...

Några kommentarer angående koden ovan....

Tiden att exekvera enskilda kommandon är försummbar mot tiden att exekvera hela snurran...

/peterh


Svara

Sv: Byta ut textrader i textfil?

Postades av 2001-02-14 22:09:00 - Sven Åke Persson

Igen
Igen
> Vad beträffar
  next i
next j

Nej jag kan inte heller se nån skillnad .

På den gamle kungens tid sa man att om man skrev " Next i "
så slöade detta ner därför att i varje loop så behövde
kontroll ske mot "For i "
Man menade att man bara skulle skriva "Next"

Med dagens snabba processorer verkar det inte
ge någon mätbar skillnad.

mvh
Sven


Svara

Nyligen

  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo
  • 14:25 Tips på verktyg för att skapa QR-k
  • 14:23 Tips på verktyg för att skapa QR-k
  • 20:52 Fungerer innskuddsbonuser egentlig

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 155
27 952
271 704
769
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies