System.out, stdout и cout - это одно и то же? - PullRequest
3 голосов
/ 06 октября 2010

Являются ли System.out, stdout и cout ТОЧНЫМ в Java, C и C ++, соответственно?

Почему три разных имени для одной и той же вещи (особенно когда C, C ++ и Java имеют много общего)?

Кроме того, я знаю, для чего они используются, но что именно они, под капотом, я имею в виду?

Ответы [ 4 ]

5 голосов
/ 06 октября 2010

cout по существу совпадает с stdout, но разница в том, что cout имеет тип ostream (что означает, что вы можете вводить форматированные данные, используя << или неформатированные данные, с помощью writeМетод.

stdout присоединен к дескриптору файла (стандартный вывод FILE*). stdout дескриптор файла 1. Поскольку он возвращает ссылку на дескриптор файла, его можно использоватьв fputs и fprintf.

Java System.out по существу похож на stdout (он использует java.io.FileDescriptor с дескриптором 1) и передается в FileOutputStream и, наконец, оборачивается в BufferedOutputStream.

Вот как инициализируется java.lang.System:

 /**
     * Initialize the system class.  Called after thread initialization.
     */
    private static void initializeSystemClass() {
    props = new Properties();
    initProperties(props);
    sun.misc.Version.init();

        // Workaround until DownloadManager initialization is revisited.
        // Make JavaLangAccess available early enough for internal
        // Shutdown hooks to be registered
        setJavaLangAccess();

        // Gets and removes system properties that configure the Integer
        // cache used to support the object identity semantics of autoboxing.
        // At this time, the size of the cache may be controlled by the
        // vm option -XX:AutoBoxCacheMax=<size>.
        Integer.getAndRemoveCacheProperties();

    // Load the zip library now in order to keep java.util.zip.ZipFile
    // from trying to use itself to load this library later.
    loadLibrary("zip");

    FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
    setIn0(new BufferedInputStream(fdIn));
    setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
    setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));

    // Setup Java signal handlers for HUP, TERM, and INT (where available).
        Terminator.setup();

        // Initialize any miscellenous operating system settings that need to be
        // set for the class libraries. Currently this is no-op everywhere except
        // for Windows where the process-wide error mode is set before the java.io
        // classes are used.
        sun.misc.VM.initializeOSEnvironment();

    // Set the maximum amount of direct memory.  This value is controlled
    // by the vm option -XX:MaxDirectMemorySize=<size>.  This method acts
    // as an initializer only if it is called before sun.misc.VM.booted().
    sun.misc.VM.maxDirectMemory();

    // Set a boolean to determine whether ClassLoader.loadClass accepts
    // array syntax.  This value is controlled by the system property
    // "sun.lang.ClassLoader.allowArraySyntax".  This method acts as
    // an initializer only if it is called before sun.misc.VM.booted().
    sun.misc.VM.allowArraySyntax();

    // Subsystems that are invoked during initialization can invoke
    // sun.misc.VM.isBooted() in order to avoid doing things that should
    // wait until the application class loader has been set up.
    sun.misc.VM.booted();

        // The main thread is not added to its thread group in the same
        // way as other threads; we must do it ourselves here.
        Thread current = Thread.currentThread();
        current.getThreadGroup().add(current);
    }

FileDescriptor.out:

/**
 * A handle to the standard output stream. Usually, this file
 * descriptor is not used directly, but rather via the output stream
 * known as <code>System.out</code>.
 * @see     java.lang.System#out
 */
public static final FileDescriptor out = standardStream(1);

Источник :

4 голосов
/ 06 октября 2010

Это одно и то же, но они не одного типа.Например, stdout - это FILE*, а cout - это std::ostream.Так как C ++ поддерживает оба, необходимы разные имена.

Под капотом все эти переменные ссылаются на стандартный вывод вызывающего процесса.Это один из трех файловых дескрипторов (stdin, stdout, stderr), которые всегда открываются ОС, когда она порождает новый процесс.Все, что записано в этот дескриптор файла, попадает на экран или туда, куда stdout был перенаправлен (используя операторы оболочки > или >>).

0 голосов
/ 06 октября 2010

Каждый из них является специфическим для языка способом записи в файл программы «стандартный вывод», концепция, которая возникла в C / UNIX. Они отличаются точными функциями / методами, которые они предоставляют для выполнения вывода.

Стоит также упомянуть, что и cout, и stdout доступны в C ++, так как он на полпути пытается быть надмножеством языка C, но смешивание использования этих двух может быть плохой идеей, если вы не отключите буферизацию полностью на обоих. Мне не известно о каких-либо требованиях к двоим для совместного использования буфера, поэтому возможно, что результат будет неправильным, если вы смешаете их.

0 голосов
/ 06 октября 2010

Теоретически это одно и то же, все они отправляются на стандартный вывод.

Но в C и C ++ cout строится поверх stdout, чтобы добавить некоторые функции, которые System.out предоставляет, например, форматирование. Поскольку java не имеет понятия указателей, System out была переработана для использования PrintStream для выполнения задач, аналогичных cout.

PritnStream предоставляет некоторые дополнительные функции, например, PrintStream не генерирует IOException, а вместо этого устанавливает внутренний флаг ошибки, к которому затем можно получить доступ, используя checkError.

Я думаю, что соглашения об именах были соблюдены, потому что дизайнеры каждого языка были разными. C, C ++ тесно связаны с Unix, и поэтому они использовали такие термины, как стандартный вывод и консоль и т. Д. Java была разработана, чтобы быть более объектно-ориентированной, и поэтому создатель Java решил назвать ее немного иначе.

...