Humble Little Ruby Book/Chap4
최근 언어들의 라이브러리에서 이루어지고 있는 작업은 사람들이 Perl이나 Bash script 대신에 Python이나 Ruby 와 같은 더 친근한 솔루션으로 처리할 수 있도록 하는 것입니다. 그런 언어들을 사용하면 더 작은 노력으로도 같은 작업을 수행할 수 있기 때문입니다. 그 라이브러리들 덕택에 Ruby는 그런 난해한 솔루션들(Perl, Bash 등) 만큼 시스템과 상호작용을 할 수 있습니다. 그럼 그 시스템 라이브러리 일부와 루비의 내장 함수에 대해서 살펴봅시다. 아마 당신은 1시간 내에 Perl 매뉴얼의 복사본을 팔아치워버리게 될 것입니다!
1. 파일시스템 ¶Ruby의 File 클래스는 다른 비슷한 성격을 지닌 언어(ex. Python)와 비교하면 매우 강력합니다. 더 많은 메소드를 가지고 있을 뿐 아니라 논리적으로 더 적합한 이름을 가지고 있습니다.(e.g. Python 에서 unlink 가 하는 일이 뭐지? delete? 그럼 왜 그렇게 부르지 않는거야!?). Ruby의 File 클래스의 강렴함과 사용의 편리함을 다른 언어들과 비교하면 눈오는 날에 클래식 음악과 함께 따뜻한 스프를 먹는 것처럼 더 편안할 겁니다.
우선, 하나의 파일에 관하여 알아낼 수 있는 것에 대해서 살펴봅시다. 파일이 존재하는가? 어떤 종류의 파일인가? 그건 파일이 맞는가? 아래에 몇개의 예제가 있습니다.("textfile.txt" 가 현재 디렉토리에 있다고 가정합니다.)
File.directory?("textfile.txt") → false File.file?("textfile.txt") → true File.exists?("textfile.txt") → true File.size?("textfile.txt") → 2063 File.extname("textfile.txt") → ".txt" File.extname("igotnoextension") → ""위의 것들의 의미에 대해서는 자세한 설명은 하지 않겠습니다. 당신들의 지능을 의심하긴 싫으니까요 :). 하지만 두가지는 짚고 넘어가겠습니다. 우선 "size?" 메소드는 kilobytes가 아닌 bytes 사이즈를 리턴합니다. 두번째로는 "size?" 메소드는 파일의 size가 0일때 nil 을 리턴합니다. 또한 File 클래스는 파일에 대한 소유권(ownership)과 허가권(permission)과 같은 메타데이터들에 대한 정보를 제공합니다.
File.executable?("textfile.txt") → false File.readable?("textfile.txt") → true File.writable?("textfile.txt") → true File.owned?("textfile.txt") → true File.grpowned?("textfile.txt") → false File.setgid?("textfile.txt") → false File.setuid?("textfile.txt") → false The executable? (which determines if the user has the ability to execute a file according to filesystem permissions, not whether or not the file is an executable), readable?, and writable? methods have companion methods called executable_real?, readable_real?, and writable_real? (respectively, obviously) which make sure that the owner of the process has that ability with that file. Of course, if you own the file it probably doesn't matter. You can find out if you own it using the owned? method, which will return true if the process owner indeed owns the specified file. Normally the grpowned?, setgid?, and setuid? are very helpful in finding out certain metadata about a file, but these methods don't apply to and will always return false on operating systems that don't support them (I'm looking right at you Windows!). For those not in the know, on UNIX filesystems a file is owned by a user in a group rather than "just" a user; the grpowned? gains you access to this data. The setgid? and setuid? check for a bit that is set on a file's filsystem entry that allows you to change the user and/or the group when accessing that file (this helps when a user needs elevated privileges for a certain task). Again, these methods allow you to see if these bits are set, but if you're on Windows or something else that doesn't support them then they always return false
1.1. 파일로부터 읽어오기 ¶I can hear you saying, "Who cares about that crap?! I need to read a file. I made the file. I know all that crap about it! Tell me how to read it or I challenge you to a knife fight, right now, behind the Waffle House! You and me, pal! We're taking it to the matresses!" I would like to now kindly respond to your anger with this little tidbit:
myfile = File.open("textfile.txt", "r") myfile.each_line {|line| puts line } myfile.closeUsing the File#open method, you can open a file and create a new File instance. The first parameter for open is the file path (either relative or absolute), and the second parameter is the file mode. You can view the table of options you have for this parameter in the table at the end of this section; this parameter defaults to reading if you don't specify. After you call open, you can use the each_line method to grab each line and print it out, play around with it, whatever you want to do inside the block. You can optionally feed each_line a parameter that will act as the line ending in place of "\n"; if you, like me, tend to end each line of text with the word "pastry" you can respect this feature. Always be sure to call the close method if you are opening files this way. "But, Dad!" you whine. "I don't wanna call close!" Well, Son/Daughter/Androgynous Offspring, Ruby can help you cure your incessant moaning:
File.open("textfile.txt") do |myfile| myfile.each_line {|line| puts line } endThis does the same thing, but now the file stream is automatically closed when the enclosing block exits. "Wow!" you exclaim. I'm glad you're amazed, but it gets better: IO.foreach("textfile.txt") {|line| puts line }Using the IO#foreach method does the same thing as the previous two examples, just simpler, more compact, and far more beautifully. It opens the file specified, feeds it line by line into a block, then closes it. Mmm...now that's Rubylicious. 1.2. 파일에 쓰기 ¶Your options for writing to a file are numerous; they all accomplish essentially the same objective but in slightly different ways. The first (and most obviously named) way I'd like to cover is the write method. It goes something like this:
File.open("textfile.txt", "w") do |myfile| myfile.write("Howdy!") endYou open a file with the File#open method, create an enclosing block, and simply call the write method on the file instance created by the block. You can do writing the same way I showed you reading the first time (i.e. without a block at all and calling close), but I thought that would be needlessly redundant to include it here. You can write any sort of data to a file as long as it can be converted to a string (i.e. it has a to_s method); if it can't be converted to a string Ruby will simply issue it a string representation to the effect of "#<ClassName:SomeData>". Other methods such as print and puts can easily be plugged into where write is; they take the same number of parameters and behave essentially the same way (except that puts will tag a new line on the end of the string when it is written). Another way of writing to a file is utilizing the << operator; if you've ever used IOStream in C++ then you should feel right at home with this:
File.open("textfile.txt", "w") do |myfile| myfile << "Howdy!\n" << "There are " << count << "pandas!" endOpening the file is the same as always, but now instead of calling a method and feeding in parameters (at least in the traditional sense) you are now using the << operator. It behaves the same as the other methods (i.e. it converts the data to a string if it is not a string and writes it to the file) so there shouldn't be any surprising parts there. BOOGABLARGABOO! Okay, maybe that surprised you, but nothing else should. 1.3. 더 많은 파일 작업 ¶The File class also supports a number of other file operations that promote all sorts of filesystem hooliganism. Here are a few:
File.delete("textfile.txt") File.rename("textfile.txt", "textfile.txt.bak") File.chown(nil, 201, "textfile.txt") File.chmod(0777, "textfile.txt")The first two method's names should give away their function. If the proverbial cat is not out of the bag, they delete and rename the provided files (with the renamed filename fed in as the second parameter). The delete method will return the number of files deleted (i.e. 1 for this case). The last two methods may be a little confusing if you are not up to snuff on your UNIX/Linux filesystems and their associated commands. The chown command allows a user with superuser privileges to change the owner of a file (or the owner may change the group ownership to any group of which he/she is a member); note that the chown method takes numeric owner and group IDs rather than string names (which the command line version allows). The chmod method allows the owner of a file (or a superuser) to change the permissions of a file (i.e. which users/groups can read, write to, or execute a file); the first parameter is a bit pattern which represents the permissions on the filesystem. Check Appendix A for URLs with more information on UNIX filesystem metadata (including bit patterns to be used with the chmod method).
File Access Modes
|
Be careful how you get yourself involved with persons or situations that can't bear inspection. |