Author Topic: write to specific line of txt file  (Read 5836 times)

0 Members and 1 Guest are viewing this topic.

andrew_nao

  • Guest
write to specific line of txt file
« on: January 16, 2013, 01:46:05 PM »
i have code to read a specific line of a text file.

how can i write to a specific line in a text file?


dgorsman

  • Water Moccasin
  • Posts: 2437
Re: write to specific line of txt file
« Reply #1 on: January 16, 2013, 02:11:16 PM »
There is no random seek in the (open...) (write-line...) (close) sequence, so you will need to read the lines into a list, replace the line you need to, then write the lines back to the file.  If you are doing multiple operations its best to do them all on the list of strings first, then do a single write operation to push the accumulated changes to file.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: write to specific line of txt file
« Reply #2 on: January 17, 2013, 01:58:47 AM »
You could open the file through the ADODB.Stream object and then position the current spot to a specific character:
http://www.theswamp.org/index.php?topic=36656.0
http://www.cadtutor.net/forum/showthread.php?57294-Read-Write-Binary-Files
http://www.w3schools.com/ado/ado_ref_stream.asp

But even then you'd need to step through lines in order to get to line #X. So it won't be more efficient than doing a normal read-line X times into a lst. At least not by much. At best it would mean you don't need to re-write the lines before the one in question, but if your new line is shorter than the old one - you might make your file corrupt.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

JohnK

  • Administrator
  • Seagull
  • Posts: 10652
Re: write to specific line of txt file
« Reply #3 on: January 17, 2013, 08:55:11 AM »
I agree with dgorsman; read, correct, output.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

andrew_nao

  • Guest
Re: write to specific line of txt file
« Reply #4 on: January 17, 2013, 09:10:09 AM »

what im after is something that will require a little bit though
to read and write back n forth to a specific line in a txt file


thanks for the input

ronjonp

  • Needs a day job
  • Posts: 7529
Re: write to specific line of txt file
« Reply #5 on: January 17, 2013, 09:21:25 AM »

what im after is something that will require a little bit though
to read and write back n forth to a specific line in a txt file


thanks for the input

Require a little bit of what?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: write to specific line of txt file
« Reply #6 on: January 17, 2013, 10:27:21 AM »

what im after is something that will require a little bit though
to read and write back n forth to a specific line in a txt file


thanks for the input

Standard text file may not be the best for that.  Is it absolutely essential that the file is kept up to date?  Could you read the data into a global variable (one of the few time this is a good idea), keep that up-to-date, then write it back when its no  longer needed?
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

pBe

  • Bull Frog
  • Posts: 402
Re: write to specific line of txt file
« Reply #7 on: January 17, 2013, 10:57:38 AM »
"

i have code to read a specific line of a text file.
Yes..
Quote
how can i write to a specific line in a text file?

I  think the same way "the code" read the specific line of text file.? correct? If that mysterious code have the capability to read a specific line, then in the same manner it could write by using....

wait a minute , what code?  ;D


irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: write to specific line of txt file
« Reply #8 on: January 18, 2013, 12:38:10 AM »
The issue is that a "line" in a text file can mean many things. It's because of the way a text file is saved (all text files, not just those from lisp). Say you have the following in a text file:
Code: [Select]
First line
Second line
Third line is a bit longer
Fourth
Fifth line
How would you get to the Fourth line? Any line could be any length. The above file is saved thus:
Quote
First line[CR][LF]Second line[CR][LF]Third line is a bit longer[CR][LF]Fourth[CR][LF]Fifth line
So in this case the Fourth line starts at the 56th character, but if any of the lines before it is only slightly different that character is at a different position.

So no way to simply go to a specific place in the file for all possibilities. You have to read the first set of lines to find out where the line you're interested in starts. But say you've now figured out that the Fourth line starts at character 56. You want to change it into: "Fourth Line". This will alter the file to this:
Quote
First line[CR][LF]Second line[CR][LF]Third line is a bit longer[CR][LF]Fourth Lineth line
Which corrupts the rest of the file since you're actually overwriting part of the fifth line to get something which looks like this:
Code: [Select]
First line
Second line
Third line is a bit longer
Fourth Lineth line
Therefore it's never a good idea to work on only parts of a text file - unless you make it into a structured file (like a database file). These are split into packets, which never vary in size. The simplest structured file would work similar to an old Pascal string Array. E.g. each line can only be a maximum of 255 characters long, but the blank space is also saved - just ignored, the 1st character lists the actual length of the text in the line as binary digit. The above would be saved as:
Code: [Select]
\013First line............some garbage not even worrying about this....up to the 256't character
\014Second line.....................
\033Third line is a bit longer.........................
\007Fourth.........................
\013Fifth line.....................
Now you know that the 4th line always starts at the 769th character and ends at 1024 - no matter how long any one line's actual text is.

Clearly this file has lots of wasted space, because none of those lines even come close to using the full space allotted to them. This is the major example of what's meant when a programmer says efficiency is a balance between speed and space. The text file uses the least space but takes the longest to edit, the structured file uses the most space but can be edited near instantaneously.

There's another drawback when using structured. Very few (if any) text editors will read that file correctly. So your program would be the only thing which could make sense of it, or you'd need to write some new version of Notepad so someone else could open that file to even just see what's inside.

In lisp I'd only start considering structured files when I want to randomly replace single lines in a file with 1000's of lines on a very short interval. If it's only say 100 lines, it's probably not worth the effort to try and steer clear of the following code:
Code - Auto/Visual Lisp: [Select]
  1. (defun TextFile-ReadLine#  (FileName Number / f str)
  2.   (if (setq f (open (findfile FileName) "r"))
  3.     (progn (while (and (setq str (read-line f)) (> Number 0)) (setq Number (1- Number))) str)))
  4.  
  5. (defun TextFile-WriteLine#  (FileName Number Text / f lst str)
  6.   (if (setq f (open (findfile FileName) "r"))
  7.     (progn (while (setq str (read-line f))
  8.              (setq lst (cons (cond ((= (setq Number (1- Number)) -1) Text)
  9.                                    (str))
  10.                              lst)))
  11.            (close f)
  12.            (if (setq f (open (findfile FileName) "w"))
  13.              (progn (foreach str (reverse lst) (write-line str f)) (close f) Text)))))
And even if it's more lines I'd look at saving each line as an item in a global list (as mentioned previously). That way you read the entire file once into RAM, then replace the item(s) in the list as your program continues working. Then you could add something like a DrawingClosing reactor to save that list back to the file just before the Dwg is closed. That would be a lot more efficient than the constant file access you're after.

Edit: Bug corrected in code.
« Last Edit: January 18, 2013, 12:56:20 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: write to specific line of txt file
« Reply #9 on: January 18, 2013, 01:14:53 PM »

what im after is something that will require a little bit though
to read and write back n forth to a specific line in a txt file


thanks for the input

Require a little bit of what?

lol sorry.   a little bit of thought

andrew_nao

  • Guest
Re: write to specific line of txt file
« Reply #10 on: January 18, 2013, 01:23:35 PM »
what my plan is/was to do, is make a drawing number program.
i select what size paper (IE A, C, D, etc)
and it reads a line (in a file or list) and returns a number to be used for a drawing.

example A-12345

and then it takes that number and writes it back to the file for when the next person goes to assign a number to a drawing he gets the next number in the series

example A-12346

the reason for the different lines is for the difference size paper
1 line for the A
1 line for the C
1 line for the D
etc..
i did quickly make one that works but it writes to 3 different text files
im just trying to make it use 1 text file

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: write to specific line of txt file
« Reply #11 on: January 18, 2013, 01:35:27 PM »
Could always use XML, SQLite, or MS Access without too much extra work.  Allows for easier management of additional information, as well as specific item replacement.  Gotta watch the sequence of events when you have multiple users hitting up the data at the same time though.  If you have multiple concurrent users you pretty much have to institute a locking file (such as DWL files for DWG) unless you are working with a database system that supports indivdual record locking.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

Lee Mac

  • Seagull
  • Posts: 12916
  • London, England
Re: write to specific line of txt file
« Reply #12 on: January 18, 2013, 05:57:47 PM »
If you are struggling with the programming, an simple shortcut might be to use the setcfg / getcfg functions, e.g.:

Code: [Select]
(setcfg "AppData/andrew_nao/A" "12345")
(getcfg "AppData/andrew_nao/A")

fixo

  • Guest
Re: write to specific line of txt file
« Reply #13 on: January 19, 2013, 01:04:00 AM »
what my plan is/was to do, is make a drawing number program.
i select what size paper (IE A, C, D, etc)
and it reads a line (in a file or list) and returns a number to be used for a drawing.

example A-12345

and then it takes that number and writes it back to the file for when the next person goes to assign a number to a drawing he gets the next number in the series

example A-12346

the reason for the different lines is for the difference size paper
1 line for the A
1 line for the C
1 line for the D
etc..
i did quickly make one that works but it writes to 3 different text files
im just trying to make it use 1 text file
Try this one from my oldies
Code: [Select]
;;frx.lsp
;; find / replace string in the text (.sat in this example but may any) file

(defun C:FRX (/ fdesc fname fnew fso readstr source sourcepath
        stringfind stringreplace target targetpath)

  (setq stringfind "44675K32" ;<-- set old string here
stringfind (strcat "8 " stringfind " #")
stringreplace "NewLayerName" ;<-- set new layer name here
stringreplace (strcat "8 " stringreplace " #")
)
  (setq sourcepath (getfiled "Select SAT file:" (getvar "dwgprefix") "SAT" 16))

  (setq targetpath (strcat
     (vl-filename-directory sourcepath); <--in the same folder
   "\\"
   "TempSatFileName"; <--change the temp file name if you need though no matter
   (vl-filename-extension sourcepath)))

  (setq fso (vlax-create-object "Scripting.FileSystemObject"))
  (if (zerop (vlax-invoke fso 'FileExists (findfile sourcepath)))
  (progn
  (alert "File does not exist")
  (exit)
  (princ))
  )
(vl-catch-all-apply (function (lambda(); <--to bypass if copy is already exist 
(vl-file-copy sourcepath
  (strcat "C:\\Temp\\" ;<-- set path to folder that contains your copy files
  "CopyOfSourceFile"
  (vl-filename-extension sourcepath)))))); <-- copy source file to keep working, who knows...
 
(setq source (vlax-invoke fso 'OpenTextFile sourcepath 1 :vlax-false))
(setq target (vlax-invoke fso 'CreateTextFile targetpath :vlax-true))

(while
  (equal (vlax-get-property source 'AtEndOfStream) :vlax-false)
  (setq readstr (vlax-invoke source 'ReadLine))
  ;;; search for string to replace
  (if
  (not (vl-string-search stringfind readstr));<-- if not found
  (vlax-invoke target 'WriteLine readstr);<-- write the same one
  (vlax-invoke target 'WriteLine (vl-string-subst stringreplace stringfind readstr)) ;<-- else write edited line
  )
)
 
(vlax-invoke source 'Close)
(vlax-invoke target 'Close)
 
(setq fdesc (vlax-invoke fso 'GetFile sourcepath))
(setq fname (vlax-get fdesc 'Name)); <-- replace temp file name with source file name

(vlax-invoke fdesc 'Delete); <-- delete source file
(princ "\nSource file was deleted"); <-- dummy input for micro pause
(setq fnew (vlax-invoke fso 'GetFile targetpath))
(vlax-put fnew 'Name fname); <-- short name only!

(vlax-release-object fdesc) 
(vlax-release-object fnew) 
(vlax-release-object source)
(vlax-release-object target)       
(vlax-release-object fso)

(gc)

(alert "Pokey")
(princ)
)
(prompt "\n====================================\n")
(prompt "\n***     Type FRX to execute ...  ***\n")
(prompt "\n====================================\n")
(prin1)

(or(vl-load-com)(princ))

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: write to specific line of txt file
« Reply #14 on: January 20, 2013, 11:44:34 PM »
Could always use XML, SQLite, or MS Access without too much extra work.  Allows for easier management of additional information, as well as specific item replacement.  Gotta watch the sequence of events when you have multiple users hitting up the data at the same time though.  If you have multiple concurrent users you pretty much have to institute a locking file (such as DWL files for DWG) unless you are working with a database system that supports indivdual record locking.
+1 on a Client-Server type DBMS for more than one user. Makes it much simpler to handle concurrent user access. Not to mention a DB would allow all sorts of editable stuff on item / multiple items at a time.

Lee, would using the setcfg/getcfg necessitate sharing the acad.cfg file?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12916
  • London, England
Re: write to specific line of txt file
« Reply #15 on: January 21, 2013, 07:46:55 AM »
Lee, would using the setcfg/getcfg necessitate sharing the acad.cfg file?

I guess if the application is to be used across a network there would need to be a single acad.cfg file residing in a network support path; for such a simple task as the OP has described, (i.e. with minimal data), the setcfg/getcfg seemed a good solution without requiring extensive programming knowledge.

pBe

  • Bull Frog
  • Posts: 402
Re: write to specific line of txt file
« Reply #16 on: January 21, 2013, 08:59:59 AM »

example A-12345

and then it takes that number and writes it back to the file for when the next person goes to assign a number to a drawing he gets the next number in the series

example A-12346
....

Nice, I like the idea. 8)

andrew_nao

  • Guest
Re: write to specific line of txt file
« Reply #17 on: January 21, 2013, 10:41:20 AM »
Could always use XML, SQLite, or MS Access without too much extra work.  Allows for easier management of additional information, as well as specific item replacement.  Gotta watch the sequence of events when you have multiple users hitting up the data at the same time though.  If you have multiple concurrent users you pretty much have to institute a locking file (such as DWL files for DWG) unless you are working with a database system that supports indivdual record locking.
i often scratch my head while coding in lisp
thanks for the suggestion tho

andrew_nao

  • Guest
Re: write to specific line of txt file
« Reply #18 on: January 21, 2013, 10:45:31 AM »
i appreciate all the suggestions..
as soon as i have some type of working code ill share for critiquing