Это должен быть общий вопрос, который время от времени возникает у всех программистов. Как мне прочитать строку из текстового файла? Тогда следующий вопрос всегда - как мне написать это обратно.
Конечно, большинство из вас используют высокоуровневую инфраструктуру в повседневном программировании (которую можно использовать в ответах), но иногда приятно знать, как это делать и на низком уровне.
Я сам знаю, как сделать это в C
, C ++
и Objective-C
, но было бы удобно увидеть, как это делается на всех популярных языках, если только чтобы помочь нам принять лучшее решение о том, на каком языке делать наш файл. В частности, я думаю, что было бы интересно посмотреть, как это делается на языках манипулирования строками, например: python
, ruby
и, конечно, perl
.
Итак, я полагаю, что здесь мы можем создать ресурс сообщества , чтобы мы могли пометить звездочкой в наших профилях и сослаться на то, когда нам нужно выполнить файловый ввод / вывод на каком-то новом языке. Не говоря уже о воздействии, которое мы все получим на языки, с которыми мы не имеем дело изо дня в день.
Вот как вам нужно ответить:
Пояснение:
C
, C ++
, C #
, Java
, Objective-C
все великолепны.
Если вы знаете, как это сделать в Прологе
, Хаскеле
, Фортране
, Лиспе
или Базовом
] тогда, пожалуйста, продолжайте.
with open('fileio.txt', 'w') as f:
f.write('hello')
with open('fileio.txt', 'a') as f:
f.write('\nworld')
with open('fileio.txt') as f:
s = f.readlines()[1]
print(s)
Уточнения
readlines () возвращает список всех строк в файле. Следовательно, вызов readlines () приводит к чтению каждой строки файла. В этом конкретном случае можно использовать readlines (), потому что мы все равно должны прочитать весь файл (нам нужна его последняя строка). Но если наш файл содержит много строк, и мы просто хотим распечатать его n-ю строку, нет необходимости читать весь файл. Вот несколько лучших способов получить n-ю строку файла в Python: Что заменяет xreadlines () в Python 3? .
Что это с утверждением? Оператор with запускает блок кода, в котором вы можете использовать переменную f как объект потока , возвращаемый в результате вызова open (). Когда блок with заканчивается, python автоматически вызывает f.close (). Это гарантирует, что файл будет закрыт при выходе из блока with независимо от того, как и когда вы выйдете из блока. (даже если вы выйдете из него через необработанное исключение). Вы можете вызвать f.close () явно, но что, если ваш код вызывает исключение, а вы не перейдете к вызову f.close ()? Вот почему полезно использовать оператор with.
Вам не нужно повторно открывать файл перед каждой операцией. Вы можете написать весь код внутри одного с блоком.
с open ('fileio.txt', 'w +') как f:
f.write ('привет')
f.write ('\ nworld')
s = f.readlines () [1]
печать (и)
Я использовал три с блоками, чтобы подчеркнуть разницу между тремя операциями: запись (режим 'w'), добавление (режим 'a'), чтение (режим 'r', по умолчанию).
#!/usr/bin/env perl
use 5.10.0;
use utf8;
use strict;
use autodie;
use warnings qw< FATAL all >;
use open qw< :std :utf8 >;
use English qw< -no_match_vars >;
# and the last shall be first
END { close(STDOUT) }
my $filename = "fileio.txt";
my($handle, @lines);
$INPUT_RECORD_SEPARATOR = $OUTPUT_RECORD_SEPARATOR = "\n";
open($handle, ">", $filename);
print $handle "hello";
close($handle);
open($handle, ">>", $filename);
print $handle "world";
close($handle);
open($handle, "<", $filename);
chomp(@lines = <$handle>);
close($handle);
print STDOUT $lines[1];
Во-первых, множество вложенных обратных вызовов.
var fs = require("fs");
var sys = require("sys");
var path = "fileio.txt";
fs.writeFile(path, "hello", function (error) {
fs.open(path, "a", 0666, function (error, file) {
fs.write(file, "\nworld", null, "utf-8", function () {
fs.close(file, function (error) {
fs.readFile(path, "utf-8", function (error, data) {
var lines = data.split("\n");
sys.puts(lines[1]);
});
});
});
});
});
Немного почище:
var writeString = function (string, nextAction) {
fs.writeFile(path, string, nextAction);
};
var appendString = function (string, nextAction) {
return function (error, file) {
fs.open(path, "a", 0666, function (error, file) {
fs.write(file, string, null, "utf-8", function () {
fs.close(file, nextAction);
});
});
};
};
var readLine = function (index, nextAction) {
return function (error) {
fs.readFile(path, "utf-8", function (error, data) {
var lines = data.split("\n");
nextAction(lines[index]);
});
};
};
var writeToConsole = function (line) {
sys.puts(line);
};
writeString("hello", appendString("\nworld", readLine(1, writeToConsole)));
let path = "fileio.txt"
File.WriteAllText(path, "hello")
File.AppendAllText(path, "\nworld")
let secondLine = File.ReadLines path |> Seq.nth 1
printfn "%s" secondLine
string path = "fileio.txt";
File.WriteAllLines(path, new[] { "hello"}); //Will end it with Environment.NewLine
File.AppendAllText(path, "world");
string secondLine = File.ReadLines(path).ElementAt(1);
Console.WriteLine(secondLine);
File.ReadLines (путь). ElementAt (1)
- это только .Net 4.0, альтернатива - File.ReadAllLines (path) [1]
, которая анализирует весь файл в массив.
module d_io;
import std.stdio;
void main()
{
auto f = File("fileio.txt", "w");
f.writeln("hello");
f.writeln("world");
f.open("fileio.txt", "r");
f.readln;
auto s = f.readln;
writeln(s);
}
main :: IO ()
main = let filePath = "fileio.txt" in
do writeFile filePath "hello"
appendFile filePath "\nworld"
fileLines <- readFile filePath
let secondLine = (lines fileLines) !! 1
putStrLn secondLine
Если вы просто хотите прочитать / записать файл:
main :: IO ()
main = readFile "somefile.txt" >>= writeFile "someotherfile.txt"
Возможно, не самый идиоматичный Erlang, но:
#!/usr/bin/env escript
main(_Args) ->
Filename = "fileio.txt",
ok = file:write_file(Filename, "hello\n", [write]),
ok = file:write_file(Filename, "world\n", [append]),
{ok, File} = file:open(Filename, [read]),
{ok, _FirstLine} = file:read_line(File),
{ok, SecondLine} = file:read_line(File),
ok = file:close(File),
io:format(SecondLine).
Использование стандартной библиотеки:
val path = "fileio.txt"
val fout = new FileWriter(path)
fout write "hello\n"
fout.close()
val fout0 = new FileWriter(path, true)
fout0 write "world\n"
fout0.close()
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Использование библиотеки Josh Suereth Scala-ARM :
val path = "fileio.txt"
for(fout <- managed(new FileWriter(path)))
fout write "hello\n"
for(fout <- managed(new FileWriter(path, true)))
fout write "world\n"
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Поскольку многие люди использовали один и тот же дескриптор файла для записи двух строк, я также в том числе в моем ответе.
Использование стандартной библиотеки:
val path = "fileio.txt"
val fout = new FileWriter(path)
fout write "hello\n"
fout write "world\n"
fout.close()
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Использование библиотеки Josh Suereth Scala-ARM :
val path = "fileio.txt"
for(fout <- managed(new FileWriter(path))){
fout write "hello\n"
fout write "world\n"
}
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
package main
import (
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("fileio.txt", os.O_RDWR | os.O_CREATE, 0666)
if err != nil {
log.Exit(err)
}
defer file.Close()
_, err = file.Write([]byte("hello\n"))
if err != nil {
log.Exit(err)
}
_, err = file.Write([]byte("world\n"))
if err != nil {
log.Exit(err)
}
// seek to the beginning
_, err = file.Seek(0,0)
if err != nil {
log.Exit(err)
}
bfile := bufio.NewReader(file)
_, err = bfile.ReadBytes('\n')
if err != nil {
log.Exit(err)
}
line, err := bfile.ReadBytes('\n')
if err != nil {
log.Exit(err)
}
os.Stdout.Write(line)
}
Я не использовал BASIC почти 10 лет, но этот вопрос дал мне повод быстро освежить свои знания. :)
OPEN "fileio.txt" FOR OUTPUT AS 1
PRINT #1, "hello"
PRINT #1, "world"
CLOSE 1
OPEN "fileio.txt" FOR INPUT AS 1
LINE INPUT #1, A$
LINE INPUT #1, A$
CLOSE 1
PRINT A$
(defun main ()
(with-open-file (s "fileio.txt" :direction :output :if-exists :supersede)
(format s "hello"))
(with-open-file (s "fileio.txt" :direction :io :if-exists :append)
(format s "~%world")
(file-position s 0)
(loop repeat 2 for line = (read-line s nil nil) finally (print line))))
ANSI C
#include <stdio.h>
#include <stdlib.h>
int /*ARGSUSED*/
main(char *argv[0], int argc) {
FILE *file;
char buf[128];
if (!(file = fopen("fileio.txt", "w")) {
perror("couldn't open for writing fileio.txt");
exit(1);
}
fprintf(file, "hello");
fclose(file);
if (!(file = fopen("fileio.txt", "a")) {
perror("couldn't opened for appening fileio.txt");
exit(1);
}
fprintf(file, "\nworld");
fclose(file);
if (!(file = fopen("fileio.txt", "r")) {
perror("couldn't open for reading fileio.txt");
exit(1);
}
fgets(buf, sizeof(buf), file);
fgets(buf, sizeof(buf), file);
fclose(file);
puts(buf);
return 0;
}
new File("fileio.txt").with {
write "hello\n"
append "world\n"
println secondLine = readLines()[1]
}
,------------------------------------------------>,------------------------------------------------>,------------------------------------------------>[-]+++++++++>[-]+++++++++>[-]+++++++++<<<<<[>>>>>>+>>>+<<<<<<<<<-]>>>>>>>>>[<<<<<<<<<+>>>>>>>>>-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<<->>>->>>>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<->>>->>>>[-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<[-]+<[-]+<<<<<<[>>>>>>[-]<<<<<<[-]]>>>>>>[[-]+<<<<<[>>>>>[-]<<<<<[-]]>>>>>[[-]+<<<<[>>>>[-]<<<<[-]]>>>>[[-]+<<<[>>>[-]<<<[-]]>>>[[-]+<<[>>[-]<<[-]]>>[[-]+<[>[-]<[-]]>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++.-...>[-]<[-]]<>[-]]<<>>[-]]<<<>>>[-]]<<<<>>>>[-],------------------------------------------------>,------------------------------------------------>,------------------------------------------------>[-]+++++++++>[-]+++++++++>[-]+++++++++<<<<<[>>>>>>+>>>+<<<<<<<<<-]>>>>>>>>>[<<<<<<<<<+>>>>>>>>>-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<<->>>->>>>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<->>>->>>>[-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<[-]+<[-]+<<<<<<[>>>>>>[-]<<<<<<[-]]>>>>>>[[-]+<<<<<[>>>>>[-]<<<<<[-]]>>>>>[[-]+<<<<[>>>>[-]<<<<[-]]>>>>[[-]+<<<[>>>[-]<<<[-]]>>>[[-]+<<[>>[-]<<[-]]>>[[-]+<[>[-]<[-]]>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++.-...>[-]<[-]]<>[-]]<<>>[-]]<<<>>>[-]]<<<<>>>>[-]]<<<<<>>>>>[-]]<<<<<<>>>>>>>[<<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>[-]++++++++++<<+<<<<<<+>>>>>>>>>>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<->>->>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<[>[-]<[-]]>[[-]+>[<[-]>[-]]<[<<<<<<<[-]<+>>>>>>>>[-]]><[-]]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]>[-]++++++++++>>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<<[>>[-]<<[-]]>>[[-]+>[<[-]>[-]]<[<<<<<<<<[-]<+>>>>>>>>>[-]]><[-]]<<<<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>>>[-]]]<<<<<>>>>>[-]]<<<<<<>>>>>>>[<<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>[-]++++++++++<<+<<<<<<+>>>>>>>>>>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<->>->>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<[>[-]<[-]]>[[-]+>[<[-]>[-]]<[<<<<<<<[-]<+>>>>>>>>[-]]><[-]]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]>[-]++++++++++>>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<<[>>[-]<<[-]]>>[[-]+>[<[-]>[-]]<[<<<<<<<<[-]<+>>>>>>>>>[-]]><[-]]<<<<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>>>[-]]
Вот сценарий оболочки, использующий только встроенные команды, а не вызывающие внешние команды, такие как sed
или tail
, как это делалось в предыдущих ответах.
#!/bin/sh
echo hello > fileio.txt # Print "hello" to fileio.txt
echo world >> fileio.txt # Print "world" to fileio.txt, appending
# to what is already there
{ read input; read input; } < fileio.txt
# Read the first two lines of fileio.txt,
# storing the second in $input
echo $input # Print the contents of $input
При написании важных сценариев оболочки рекомендуется использовать как можно больше встроенных функций, поскольку создание отдельного процесса может быть медленным; Судя по быстрому тесту на моей машине, решение sed
примерно в 20 раз медленнее, чем при использовании read
. Если вы собираетесь вызвать sed
один раз, как в этом случае, на самом деле это не имеет большого значения, так как он будет выполняться быстрее, чем вы можете заметить, но если вы собираетесь выполнить его сотни или тысячи раз, это может складываться.
Для тех, кто не знаком с синтаксисом, {
и }
выполняют список команд в текущей среде оболочки (в отличие от (
и )
, которые создают подоболочку; нам нужно работать в текущей среде оболочки, чтобы мы могли использовать значение переменной позже). Нам нужно сгруппировать команды вместе, чтобы они обе работали с одним входным потоком, созданным перенаправлением из fileio.txt
; если бы мы просто запустили read
{
и }
зарезервированные слова, а не метасимволы), нам необходимо разделить {
и }
от остальных команд с пробелами и завершите список команд ;
.
Встроенная функция read
принимает в качестве аргумента имена переменных для чтения. Он потребляет строку ввода, разбивает ввод пробелами (технически он разбивает его в соответствии с содержимым $ IFS
, которое по умолчанию представляет собой символ пробела, где символ пробела означает разделение его на любой из пробелов. , табуляция или новая строка), присваивает каждое слово именам переменных, указанным по порядку, и присваивает остаток строки последней переменной. Поскольку мы просто предоставляем одну переменную, он просто помещает в эту переменную целую строку. Мы повторно используем переменную $ input
, так как нам все равно, что находится в первой строке (если мы используем Bash, мы могли бы просто не указывать имя переменной, но для обеспечения переносимости вы всегда должны указывать в хотя бы одно имя).
Обратите внимание, что, хотя вы можете читать строки по одной, как я здесь, гораздо более распространенным шаблоном было бы заключить их в цикл while:
while read foo bar baz
do
process $foo $bar $baz
done < input.txt
#!/bin/sh
echo "hello" > fileio.txt
echo "world" >> fileio.txt
LINE=`sed -ne2p fileio.txt`
echo $LINE
Фактически часть sed -n "2p"
выводит вторую строку, но вопрос требует, чтобы вторая строка была сохранена в переменную, а затем напечатали, так что ... :)
Поскольку никто больше этого не сделал......
IDENTIFICATION DIVISION.
PROGRAM-ID. WriteDemo.
AUTHOR. Mark Mullin.
* Hey, I don't even have a cobol compiler
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT StudentFile ASSIGN TO "STUDENTS.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD TestFile.
01 TestData.
02 LineNum PIC X.
02 LineText PIC X(72).
PROCEDURE DIVISION.
Begin.
OPEN OUTPUT TestFile
DISPLAY "This language is still around."
PERFORM GetFileDetails
PERFORM UNTIL TestData = SPACES
WRITE TestData
PERFORM GetStudentDetails
END-PERFORM
CLOSE TestFile
STOP RUN.
GetFileDetails.
DISPLAY "Enter - Line number, some text"
DISPLAY "NXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCEPT TestData.
cat("hello\n", file="fileio.txt") cat("world\n", file="fileio.txt", append=TRUE) line2 = readLines("fileio.txt", n=2)[2] cat(line2)
import java.io.*;
import java.util.*;
class Test {
public static void main(String[] args) throws IOException {
String path = "fileio.txt";
File file = new File(path);
//Creates New File...
try (FileOutputStream fout = new FileOutputStream(file)) {
fout.write("hello\n".getBytes());
}
//Appends To New File...
try (FileOutputStream fout2 = new FileOutputStream(file,true)) {
fout2.write("world\n".getBytes());
}
//Reading the File...
try (BufferedReader fin = new BufferedReader(new FileReader(file))) {
fin.readLine();
System.out.println(fin.readLine());
}
}
}
Несмотря на то, что некоторые говорят, что Emacs - это в основном текстовый редактор [1]. Итак, хотя Emacs Lisp можно использовать для решения всех видов проблем, он оптимизирован для нужд текстового редактора. Поскольку у текстовых редакторов (очевидно) есть довольно специфические потребности, когда дело доходит до того, как обрабатывать файлы, это влияет на функциональность, связанную с файлами, которую предлагает Emacs Lisp.
В основном это означает, что Emacs Lisp не предлагает функций для открытия файла как потока и чтения его по частям. Точно так же вы не можете добавить в файл, не загрузив сначала весь файл. Вместо этого файл полностью [2] считывается в буфер [3], редактируется и затем снова сохраняется в файл.
Для обязательных задач вы должны использовать Emacs Lisp, поскольку это подходит, и если вы хотите сделать что-то, что не требует редактирования, можно использовать те же функции.
Если вы хотите добавлять в файл снова и снова, это связано с огромными накладными расходами, но это возможно, как показано здесь. На практике вы обычно завершаете внесение изменений в буфер вручную или программно перед записью в файл (просто объедините первые два s-выражения в примере ниже).
(with-temp-file "file"
(insert "hello\n"))
(with-temp-file "file"
(insert-file-contents "file")
(goto-char (point-max))
(insert "world\n"))
(with-temp-buffer
(insert-file-contents "file")
(next-line)
(message "%s" (buffer-substring (point) (line-end-position))))
[1] По крайней мере, я бы не стал называть это ОС; альтернативный UI да, OS нет.
[2] Вы можете загружать только части файла, но это можно указывать только побайтно.
[3] Буфер - это и тип данных, чем-то похожий на строку, а также на «то, что вы видите при редактировании файла». При редактировании буфер отображается в окне, но буферы не обязательно должны быть видны пользователю.
Правка: если вы хотите видеть, как текст вставляется в буфер, вы, очевидно, должны сделать его видимым и спать между действиями. Поскольку Emacs обычно повторно отображает экран только при ожидании ввода пользователя (а сон - это не то же самое, что ожидание ввода), вам также необходимо принудительно повторно отобразить. Это необходимо в данном примере (используйте его вместо второго sexp); на практике мне никогда не приходилось использовать `redisplay 'ни разу - так что да, это некрасиво, но ...
(with-current-buffer (generate-new-buffer "*demo*")
(pop-to-buffer (current-buffer))
(redisplay)
(sleep-for 1)
(insert-file-contents "file")
(redisplay)
(sleep-for 1)
(goto-char (point-max))
(redisplay)
(sleep-for 1)
(insert "world\n")
(redisplay)
(sleep-for 1)
(write-file "file"))
<?php
$filePath = "fileio.txt";
file_put_contents($filePath, "hello");
file_put_contents($filePath, "\nworld", FILE_APPEND);
$lines = file($filePath);
echo $lines[1];
// closing PHP tags are bad practice in PHP-only files, don't use them
NSFileHandle *fh = [NSFileHandle fileHandleForUpdatingAtPath:@"fileio.txt"];
[[NSFileManager defaultManager] createFileAtPath:@"fileio.txt" contents:nil attributes:nil];
[fh writeData:[@"hello" dataUsingEncoding:NSUTF8StringEncoding]];
[fh writeData:[@"\nworld" dataUsingEncoding:NSUTF8StringEncoding]];
NSArray *linesInFile = [[[NSString stringWithContentsOfFile:@"fileio.txt"
encoding:NSUTF8StringEncoding
error:nil] stringByStandardizingPath]
componentsSeparatedByString:@"\n"];
NSLog(@"%@", [linesInFile objectAtIndex:1]);
sc fileio.txt 'hello'
ac fileio.txt 'world'
$line = (gc fileio.txt)[1]
$line
Я не трогал asm 7 лет, поэтому мне пришлось немного использовать Google, чтобы собрать его вместе, но все же он работает;) Я знаю, что это не на 100% правильно , но привет: D
Ладно, не работает. извините за это. хотя в конце он печатает world
, он печатает его не из файла, а из ecx
, который установлен в строке 27.
section .data
hello db 'hello',10
helloLen equ $-hello
world db 'world',10
worldLen equ $-world
helloFile db 'hello.txt'
section .text
global _start
_start:
mov eax,8
mov ebx,helloFile
mov ecx,00644Q
int 80h
mov ebx,eax
mov eax,4
mov ecx, hello
mov edx, helloLen
int 80h
mov eax,4
mov ecx, world
mov edx, worldLen
int 80h
mov eax,6
int 80h
mov eax,5
mov ebx,helloFile
int 80h
mov eax,3
int 80h
mov eax,4
mov ebx,1
int 80h
xor ebx,ebx
mov eax,1
int 80h
Использованные ссылки: http://www.cin.ufpe.br/~if817/arquivos/asmtut/quickstart.html
http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls. html
http://www.digilife.be/quickreferences/QRC/LINUX%20System%20Call%20Quick%20Reference.pdf
PATH = 'fileio.txt'
File.open(PATH, 'w') { |file| file.puts "hello" }
File.open(PATH, 'a') { |file| file.puts "world" }
puts line = File.readlines(PATH).last
#include <limits>
#include <string>
#include <fstream>
#include <iostream>
int main() {
std::fstream file( "fileio.txt",
std::ios::in | std::ios::out | std::ios::trunc );
file.exceptions( std::ios::failbit );
file << "hello\n" // << std::endl, not \n, if writing includes flushing
<< "world\n";
file.seekg( 0 )
.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
std::string input_string;
std::getline( file, input_string );
std::cout << input_string << '\n';
}
или несколько менее педантично,
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
fstream file( "fileio.txt", ios::in | ios::out | ios::trunc );
file.exceptions( ios::failbit );
file << "hello" << endl
<< "world" << endl;
file.seekg( 0 ).ignore( 10000, '\n' );
string input_string;
getline( file, input_string );
cout << input_string << endl;
}
Спецификации , мягко говоря, отрывочны, но я сделал все, что мог. Пусть начнется голосование против! :) Я до сих пор считаю это занятием забавным.
HAI
CAN HAS STDIO?
PLZ OPEN FILE "FILEIO.TXT" ITZ "TehFilez"?
AWSUM THX
BTW #There is no standard way to output to files yet...
VISIBLE "Hello" ON TehFilez
BTW #There isn't a standard way to append to files either...
MOAR VISIBLE "World" ON TehFilez
GIMMEH LINES TehLinez OUTTA TehFilez
I HAS A SecondLine ITZ 1 IN MAH TehLinez
VISIBLE SecondLine
O NOES
VISIBLE "OH NOES!!!"
KTHXBYE
@echo off
echo hello > fileio.txt
echo world >> fileio.txt
set /P answer=Insert:
echo %answer% >> fileio.txt
for /f "skip=1 tokens=*" %%A in (fileio.txt) do echo %%A
Чтобы объяснить этот последний ужасный цикл поиска, предполагается, что в файле есть только привет (новая строка) мир. Таким образом, он просто пропускает первую строку и повторяет только вторую.
Changelog
Хороший пример C # уже был предоставлен ранее, но я чувствовал, что включение того, как выполнять файловый ввод-вывод построчно с потоками, также было бы полезно.
string path = @"fileio.txt";
//creating file and writing to it
using (StreamWriter writer = File.CreateText(path))
{
writer.WriteLine("Hello");
}
//appending to existing file
using (StreamWriter writer = File.AppendText(path))
{
writer.WriteLine("World");
}
//reading file
using(StreamReader reader = File.OpenText(path))
{
int lineNum = 0;
string line = null;
while ((line = reader.ReadLine()) != null)//read until eof
{
if (++lineNum == 2)
{
Console.WriteLine(line);
}
}
}