Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

[VB6] regel uit .txt bestand verwijderen

None
17 antwoorden
  • is het mogelijk om met VB6 een regel uit een (extern) txt-bestand te laten verwijderen zonder daarvoor weer een heel nieuw bestand te moeten opslaan??
  • Als je een bestand veranderd of aanpast dan zul je die veranderingen toch op moeten slaan, lijkt mij tenminste. Je kunt dit op 2 manieren doen.

    1 bestand regel voor regel inlezen en toevoegen aan een variabele in het geheugen maar niet de regel toevoegen die je verwijderen wil.

    2 het hele bestand lezen en dan dmv zoeken het stukje tekst vinden en verwijderen. Kost je extra geheugen.

    Uiteraard kun je het originele bestand verwijderen en het bestand in het geheugen dan opslaan onder de originele naam maar de FAT zal altijd aangeven dat het bestand anders is (lengte, tijdstip, etc). Het enigste dat je voor elkaar gekregen hebis dat je werkt zonder een extra tijdelijk bestand, want je hebt alles in het geheugen gedaan.

    Bedoel je dit soms?
  • nee, dat is het ook niet helemaal.

    Wat ik wil (en wat te horen aan de reacties die ik krijg waarschijnlijk niet mogelijk is) is als er gewoon een txt-bestand open staat een regel eruit halen, verwijderen met 1 simpel commando omdat als ik het anders doe dan kost het veel te veel geheugen en dan kost het meer tijd om het programma te draaien en dat is nou juist de reden dat ik die regel wil laten verwijderen.
  • Nope, gaat niet lukken

    1 Open source file for read

    2 open dest file for write

    copy regel voor regel behalve diegene die je weg wil hebben
    Of als de file niet te groot de hele file inlezen in eev variabele, deze bewerken en weer terugschrijven. Helaas alleen in een keer mogelijk als file niet langer is dan 65Kb (max lengte voor string)
    Sorry geen andere optie via VB

    Jan Willem
  • [quote:3e000040b0="pc_freak17"]nee, dat is het ook niet helemaal.

    Wat ik wil (en wat te horen aan de reacties die ik krijg waarschijnlijk niet mogelijk is) is als er gewoon een txt-bestand open staat een regel eruit halen, verwijderen met 1 simpel commando omdat als ik het anders doe dan kost het veel te veel geheugen en dan kost het meer tijd om het programma te draaien en dat is nou juist de reden dat ik die regel wil laten verwijderen.[/quote:3e000040b0]

    Dat moet me dan nogal een bestand zijn zeg als het zoveel geheugen kost. Je kunt je dan direct al afvragen of opslag in een txt-file wel een goede keus is.
    Maar goed, als je zonder al te veel geheugen te gebruiken toch dat regeltje wilt verwijderen lees je toch gewoon in een loupe regel voor regel in en schrijf je deze direct weer weg naar een tussenbestand. (Behalve de regel die je wilt verwijderen natuurlijk). Aan het eind verwijder je het originele bestand en hernoem je het tussenbestand naar de naam van het oorspronkelijke bestand. Dat gaat zo snel dat je over performance echt niet in hoeft te zitten.

    Zomaar een regel wegmikken uit een tekstfile zal niet lukken, nog in VB, nog in welke andere taal dan ook.
  • het is een txt-bestand van ongeveer 15 mb (bijna 7 miljoen regels) en het probleem bij het weer wegschrijven is dat ik dit tijdens het draaien van het programma heel vaak moet doen (waarschijnlijk wel een keer of 500.000).

    Laat ik maar eens uitleggen wat het programma precies doet dan snappen jullie dat in een nieuw bestand wegschrijven veel te veel tijd kost.

    De hoofdopdracht van het programma is niet om die regels eruit te halen, maar het programma berekent via allerlei voorwaarden omgevingseffecten. Dit is een zware taak omdat hij 2 txt-bestanden heeft. Eentje waarin steeds 1 regel wordt ingelezen en een tweede (duplicate) waarin de regel uit het eerste bestand wordt vergeleken. Dit wordt bij het tweede bestand voor het hele bestand gedaan. Als dit klaar is gaat het eerste bestand naar de volgende regel en loopt het tweede bestand weer helemaal door.

    Er worden dus in totaal 7 miljoen * 7 miljoen regels vergeleken. Dit kost met de pc die ik nu heb al richting de 10 uur als ik het duplicaat-bestand in stukken knip (als ik dat niet doe kost het ongeveer 50 uur!). Dat knippen wilde ik dus ook in het programma inbouwen (door die regels te verwijderen), maar als het bestand daar steeds weer voor opgeslagen moet worden dan denk ik dat de pc veel meer dan 10 uur nodig gaat hebben.

    Iemand suggesties voor een andere oplossing om het programma sneller te maken?
  • ff checken of ik het goed begrepen heb:

    je hebt 2 bestanden, bestand 1: vergelijk jhe m,et bestand 2. (regel voor regel dan..

    dan is mijn enige oplossing:
    bestand 1 vast zetten in een loop, dus regel voor regel in lezen.
    bestand 2 gewoon in het geheugen zetten. (dus een array aanmaken, bestand 2 VOLLEDIG (of in delen, weet niet precies wat de max grote van array is) in het geheugen zetten.
    best interesant dit, ik denk dat ik zelf ook maar ff wat lijnen code ga schrijven..
  • ik ben er nu mee bezig..
    bedoelde je niet 150 mb? ik heb een bestand 7 miljoen regels is 150 MB!!
    dan word hety allemaal wat moelijker idd
  • Wat is de vervolgaktie van de vergelijking? Ik kan me totaal niet voorstellen waarom je een duplicate file regel voor regel met het origineel zou vergelijken. Tenzij je hier een of andere eigenaardig in tekstvorm uitgewerkte 1 op n of n op n bij de hand hebt. (In dat geval zou je direct de boel in een of ander rdbms moeten inlezen en van daaruit verder gaan).
    De opslagvorm deugt hoe dan ook niet. Bestanden van dergelijke omvang die in puur sequentiele vorm zijn opgeslagen vallen never nooit in redelijk tijdsbestek te manipuleren, dus daar zal sowieso iets aan moeten gebeuren. Maar goed, voorlopig heb je daar wel mee te maken.

    Maar vertel eens wat gedetailleerder wat er hoe en waarom er vergeleken moet worden en wat er met het resultaat moet gebeuren? Kunnen wij je (heel misschien) wat verder helpen.
  • Hierbij een voorbeeld van hoe één van de txt-bestanden eruit ziet:
    [code:1:55041679f0]
    24045450 12567500 2 15
    24045450 13756450 1 2
    24045450 12895500 0 4
    24045550 12654550 3 16
    24045650 13756550 3 1
    [/code:1:55041679f0]
    De eerste twee waardes op een regel zijn coordinaten, de derde is een groepnummer en de vierde is een cijfer.
    De 2 bestanden die vergeleken worden zijn precies hetzelfde omdat ze worden vergeleken op de coordinaten. In het eerste bestand word dan bijvoorbeeld 24045550 en 12654550 ingelezen. Dan wordt er in het tweede bestand steeds gekeken of de coordinaten van die regel binnen 200 en -200 van de regel in het tweede bestand liggen. Als dat zo is dan worden de cijfers bij elkaar opgeteld en de groepsnummers worden met 1 verhoogd (waarom ga ik niet allemaal uitleggen). Dan wordt er naar de volgende regel gekeken enzovoorts. Het gaat om omgevingseffecten (als jullie dat iets zegt).
  • Zou het gezien de hoeveelheid basisdata niet een mogelijkheid zijn dit in een acces/sql of oracle database te zetten. Met filters en querys moet het aantal leesacties om de gewenste regels te vinden vlgs mij een behoorlijke snelheidswinst opleveren. In ieder geval veel sneller dan regel voor regel in te lezen en te vergelijken. Om over het toevoegen en/ verwijderen van regels helemaal maar te zwijgen

    Jan Willem
  • Hmmmm, wat ik begrijp is dat het eerste bestand op zich niet zo groot is, klopt dat? Als dat zo is kun je alle regels van het eerste bestand in een array van strings inlezen, en dan het tweede bestand regel testen tegen elk element in je string. Op die manier scheelt dat je een enorme hoeveelheid leesacties omdat je nu beide bestanden slechts eenmaal hoeft te lezen en vergelijken in het geheugen gaat natuurlijk heel veel sneller.

    En als je bestand wel te groot is voor je geheugen doe je blokken van het eerste bestand, zeg maar bijvoorbeeld eerst de eerste 200 regels tegelijk testen op het tweede bestand, en dan de volgende 200 regels. Je array zou je (met ReDim Preserve) dynamisch aan kunnen passen aan de totale hoeveelheid regels die je per keer inleest vanuit het eerste bestand, uiteraard met een teller zodat ook je loop dynamisch wordt.

    Ook even een tellertje op het scherm maken om de gebruiker bezig te houden, dan lijkt het programma toch nog iets sneller. :wink:
  • [quote:e3cb966f86]Ook even een tellertje op het scherm maken om de gebruiker bezig te houden, dan lijkt het programma toch nog iets sneller. [/quote:e3cb966f86]
    Die teller op het scherm heb ik al, maar het gaat hier om 2 duplicaten (dezelfde bestanden dus) die allebei ongeveer 7 miljoen regels hebben. Het eerste bestand hoeft maar 1 keer ingelezen te worden en regel voor regel bekeken en het tweede wordt steeds doorgekeken.

    Aangezien beide bestanden op x-coordinaten (zo noem ik de eerste maar ff) gesorteerd zijn en de grenzen bij 200 en -200 afwijking liggen leek het me handig om de stukken uit het tweede bestand die toch niet meer relevant zijn te verwijderen

    Deze zijn niet meer relevant omdat ze al meer dan 200 onder de x-coordinaat in het eerste bestand zitten, en dat blijven omdat de x-coordinaat in het eerste bestand gesorteerd is en dus alleen nog maar groter wordt.

    Maar dat kost dus blijkbaar teveel geheugen omdat ik het tweede bestand dan steeds weer moet opslaan en dat is langzamer dan het bestand met de hand in een aantal stukken knippen om het programma wat sneller te maken.

    [quote:e3cb966f86]
    Zou het gezien de hoeveelheid basisdata niet een mogelijkheid zijn dit in een acces/sql of oracle database te zetten. Met filters en querys moet het aantal leesacties om de gewenste regels te vinden vlgs mij een behoorlijke snelheidswinst opleveren. In ieder geval veel sneller dan regel voor regel in te lezen en te vergelijken. Om over het toevoegen en/ verwijderen van regels helemaal maar te zwijgen [/quote:e3cb966f86]

    Nee, dat lijkt me niet handig want ik ben niet echt thuis in sql en zeker niet als het gaat om het maken van crosstabs (want dat zijn het toch?)
  • [quote:7bc20268dd="pc_freak17"]
    [quote:7bc20268dd]
    Zou het gezien de hoeveelheid basisdata niet een mogelijkheid zijn dit in een acces/sql of oracle database te zetten. Met filters en querys moet het aantal leesacties om de gewenste regels te vinden vlgs mij een behoorlijke snelheidswinst opleveren. In ieder geval veel sneller dan regel voor regel in te lezen en te vergelijken. Om over het toevoegen en/ verwijderen van regels helemaal maar te zwijgen [/quote:7bc20268dd]

    Nee, dat lijkt me niet handig want ik ben niet echt thuis in sql en zeker niet als het gaat om het maken van crosstabs (want dat zijn het toch?)[/quote:7bc20268dd]

    Goed dat je het even zegt. Stop ik met meedenken. Gezien de grootte van je bestanden en akties die je uit wilt voeren zul je het over een volkomen andere boeg moeten gooien. Maar als je daar niet voor voelt is dat jouw keus.
    Suc6 met een oplossing en laat je nog even weten wat het geworden is?
  • ik denk dat ik gewoon mijn oude manier ga gebruiken (het bestand van 7 miljoen regels in ongeveer 15 stukken knippen) om daarmee wat tijdwinst te hebben. In 10 uur vindt ik best acceptabel, want dan kan ik het programma gewoon 's avonds aanzetten en dan is het in de ochtend klaar
  • 10 uur :o Volgens mij moet dat een stuk sneller kunnen. Veranderen de bestanden nog terwijl je bezig bent? Als dat niet gebeurt dan moet dit toch echt wel sneller kunnen, 7 miljoen regels lijkt heel veel maar valt best wel mee. Als je de str4eams gewoon open laat hoef je niet steeds op te slaan en opnieuw te openen, dat scheelt al een stuk. Is regel 1 in bestand 1 gelijk aan regel 1 in bestand 2? en regel 436 in bestand 1 gelijk aan 436 in bestand 2? Uiteraard zijn de waarden in die regels wel anders maar hebben de regels betrekking tot elkaar?
  • [quote:7218b8e56b="pc_freak17"]Hierbij een voorbeeld van hoe één van de txt-bestanden eruit ziet:
    [code:1:7218b8e56b]
    24045450 12567500 2 15
    24045450 13756450 1 2
    24045450 12895500 0 4
    24045550 12654550 3 16
    24045650 13756550 3 1
    [/code:1:7218b8e56b]
    De eerste twee waardes op een regel zijn coordinaten, de derde is een groepnummer en de vierde is een cijfer.
    [/quote:7218b8e56b]
    Zorg dat alle regels even lang zijn en benader dan elke regel als een record/struct.

    Je zou eventueel het bestand kunnen benaderen d.m.v. een 'memory mapped file'

    Als je alleen maar leest uit het bestand dan zal Windows op enig moment het bestand volledig in de cache hebben staan en niet meer van de harde schijf hoeven te lezen.

    Het continu wijzigen van het bestand zal het programma in dit geval alleen maar vertragen.

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.