Read once file handle - ruby

I have a situation where I'd like to return a file handle from a routine. When the last byte of that file handle is read, the file being read is deleted. This will be a simple way to create a temporary file that is deleted once it's been read.
Tempfile doesn't really work for this purpose. To use Tempfile I would have to create the Tempfile, read and write in the entire contents of the source file to the Tempfile, rewind the Tempfile, then return the Tempfile object. Very wasteful. I just want to open a file and return a file handle, but one which deletes the file when the last byte is read.
I could probably write this class myself, but I'd rather use an existing solution if it exists.

Does it have to return a file handle type or can it be something that works on a file handle? If its the latter then you could use a closure and a lambda. Something like below:
def sp_handle(fname)
handle = File.open(fname)
->(){
line = handle.gets
line ? line : (File.unlink(fname); handle.close)
}
end

Related

I want to backup file when the file is replaced by the same file

I want to backup file when the file is replaced by the same file. And I handle it in precreate, but FltQueryInformationFile return STATUS_INVALID_PARAMETER (c000000d), and if I handle it in postCreate, FltQueryInformationFile return the file size is zero byte. How should I solve it ?

Save twitter search result to JSON file

I am using twitter ruby gem to fetch twitter search result. The example code from Github extracts the information from search result.I am wondering how to save the search result, which is JSON i think, to a separate JSON file.
Here is part of the example code:
results = #search.perform("$aaa", 1000)
aFile = File.new("data.txt", "w")
results.map do |status|
myStr="#{status.from_user}: #{status.text} #{status.created_at}"
aFile.write(myStr)
aFile.write("\n")
end
Is there any way to save all the search result to a separate JSON file instead of writing strings to a file?
Thanks in advance.
If you want to save to a file all you need to do is open the file, write it it, then close it:
File.open("myFileName.txt", "a") do |mFile|
mFile.syswrite("Your content here")
mFile.close
end
When you use open you will create the file if it doesn't exist.
One thing to be aware of is that there are different ways to open file, of which will determine where the program writes to. The "a" indicates that it will append everything you write to the file, to the end of the current content.
Here is some of the options:
r Read-only mode. The file pointer is placed at the beginning of the file. This is the default mode.
r+ Read-write mode. The file pointer will be at the beginning of the file.
w Write-only mode. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.
w+ Read-write mode. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.
a Write-only mode. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.
a+ Read and write mode. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing.
So in your case, you would want to pull out the data you want to save, then write it to a file as I have shown. You can also specify file paths by doing:
File.open("/the/path/to/yourfile/myFileName.txt", "a") do |mFile|
mFile.syswrite("Your content here")
mFile.close
end
Another thing to be aware of is that open does not create directories, so you will either need to create directories yourself, or you can do it with your program. Here is a link that is helpful for file input/output:
http://www.tutorialspoint.com/ruby/ruby_input_output.htm

write into file by changing the file to rtf - awk

i am stumbling over one thing:
i am sorting a bunch of files in awk and saving the sorted particles as txt. but now i need to save them as .doc and especially in landscape format. i googled a lot and found out that the only way of doing this is save the file as doc but during creating the file, write these rtf code into file and then write the real content into file.
rtf start-tag code:
{\rtf1\ansi\deff0 {\fonttbl {\f0 Courier;}}
{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}
\landscape
\paperw15840\paperh12240\margl720\margr720\margt720\margb720
and rtf close-tag:
}
the close tag will be written after the last line of the file as the last line into the new created file.
my problem is, how can i find the last line of the file inside the awk before coming to END.
this is my code. http://pastebin.com/mfjH4NYY
it is huge code to know what is happenning, but the point is: the fnnID is not available in the END tag, thru this, a new file will be created if i try to append the } char to close the rtf format. can someone help me figure out the clue?
thanks a lot
Let's say you'll have a function write_header(filepath) that will write the RTF header into a file. Make this function record in some global variable all the filepaths it was passed. Then, in your END, loop over these filepaths and write the RTF footer into them.
As for your new "ls -l" question: I don't see why you need to use it.
Here's what I suggested:
function write_header(filepath) {
print "{\\rtf1\\ans .... " >> filepath
tracked[max_header++] = filepath
}
BEGIN {
# You don't have to write the headers in BEGIN. Just make sure it's the
# first thing you write to the files.
write_header("file1.doc")
write_header("file2.doc")
write_header("another_file.doc")
}
END {
# Write the footers.
for(i in tracked) {
print "}" >> tracked[i]
}
}

Replace a line in a file using '+' File IO modes in Ruby

Ruby beginner here!
I am aware that Ruby's File.open method has certain modes like r,w,a,r+,w+,a+ and the complimentary b. I totally understand the use of r,w and a modes. But I cannot seem to understand how to use the ones with the '+' symbol. Can anyone provide me with some links where there are examples as well as explanations for the use of it?
Can it be used to read a line and edit/replace it in place by a equal amount of content? If so, then how?
Sample data file: a.txt
aaa
bbb
ccc
ddd
Demo.rb
file = File.open "a.txt","r+"
file.each do |line|
line = line.chomp
if(line=="bbb")then
file.puts "big"
end
end
file.close
I am trying to replace "bbb" with "big" but I am getting this:-
in notepad++
aaa
bbb
big
ddd
in notepad
aaa
bbb
bigddd
snatched this documentation from another answer, so not mine, the solution is mine
r Read-only mode. The file pointer is placed at the beginning of the file. This is the default mode.
r+ Read-write mode. The file pointer will be at the beginning of the file.
w Write-only mode. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.
w+ Read-write mode. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.
a Write-only mode. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.
a+ Read and write mode. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing.
EDIT: here the solution to your sample, most of the time the whole string is gsubbed and written back to the file but 'infile' replacing without rewriting the whole file is also possible
You should be cautious to replace with a string of the same length.
File.open('a.txt', 'r+') do |file|
file.each_line do |line|
if (line=~/bbb/)
file.seek(-line.length-3, IO::SEEK_CUR)
file.write 'big'
end
end
end
=>
aaa
big
ccc
ddd
And this is a more conventional way, though more concise then most other solutions
File.open(filename = "a.txt", "r+") { |file| file << File.read(filename).gsub(/bbb/,"big") }
EDIT2: i now realize this can still shorter
File.write(f = "a.txt", File.read(f).gsub(/bbb/,"big"))
So you are reading an entire file into a variable, then performing the
substitution, and the writing the variable's contents back to the
file. Am I right? I was looking for something kinda inline
That's the way to do it. You can alternativly use IO#readlines to read all lines into Array and then process them.
And this has been already answered:
How to search file text for a pattern and replace it with a given value
If you are woried about performance or memory usage then use the right tools for the right job. On *nix (or cygwin on windows):
sed -i -e "s/bbb/big/g" a.txt
Will do exactly what you want.

How to write a string to a text file without deleting/replacing any word in the original file?

In Cocoa, how can I write a string to a text file without replacing the contents of the file, like writing at the end of the file?
For example the following code:
BOOL written = [data writeToFile:[path stringByAppendingPathComponent:#"conf.txt"] options:NSAtomicWrite error:&error];
The data (string) was written to the text file however it replaced the original contents of the file.
Any suggestions?
Use an NSFileHandle.
First call -[NSFileHandle seekToEndOfFile] to seek to the end of the file.
Then use -[NSFileHandle writeData:] (instead of -[NSData writeToFile:]) to append your data to the end of the file.

Resources