Как получить доступ к файлу с помощью дескриптора файла в Java? [Дубликат]

Симон Моурир дал этот пример :

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

, где unboxing преобразование (литье) из object (или из одного из классов System.ValueType или System.Enum или из типа интерфейса) - тип значения (кроме Nullable<>) сам по себе дает NullReferenceException.

В другом направлении конверсия бокса из a Nullable<>, которая имеет HasValue, равную false , на ссылочный тип, может дать ссылку null, которая затем может привести к NullReferenceException. Классический пример:

DateTime? d = null;
var s = d.ToString();  // OK, no exception (no boxing), returns ""
var t = d.GetType();   // Bang! d is boxed, NullReferenceException

Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:

public static void MyExtension(this object x)
{
  x.ToString();
}

следующий код будет проблематичным:

DateTime? d = null;
d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.

Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<> экземпляров.

16
задан Peer Stritzinger 30 January 2011 в 21:51
поделиться

4 ответа

Я уверен, что это невозможно сделать с использованием чистой Java - вам, вероятно, придется использовать собственный код для привязки дескриптора файла к объекту FileDescriptor или к объекту FileInputStream или FileOutputStream.

EDIT Если вы используете Linux, * BSD или macOS, вы можете использовать псевдо-файлы / dev / fd / nnn для доступа к файловому дескриптору nnn.

13
ответ дан Adrian Pronk 24 August 2018 в 02:47
поделиться

С помощью SUN JavaVM вы можете:

FileDescriptor fd = new FileDescriptor();
sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess().set(fd,3);
FileInputStream fin = new FileInputStream(fd);
8
ответ дан Alexandre DuBreuil 24 August 2018 в 02:47
поделиться

Для начала:

Приложения не должны создавать свои собственные дескрипторы файлов

Вы можете попробовать использовать отражение для вызова конструктор private FileDescriptor(int fd), получив конструктор и называя setAccessible(true) на нем. Но это взломать, и я не могу гарантировать, что это сработает (скорее всего, этого не произойдет). Особенно с цитатой, с которой я начал.

2
ответ дан Bozho 24 August 2018 в 02:47
поделиться

Мне недавно понадобилось сделать это для дочернего процесса Java, работающего в тюрьме. Это означало, что у него не было доступа к файловой системе / dev / fd.

@Bozho сделал комментарий, что отражение может или не может работать для создания объекта FileDescriptor. Однако, похоже, он работает в простом тесте. Ниже приведен источник для TestFD.java:

import java.lang.reflect.Constructor;
import java.io.FileDescriptor;
import java.io.FileOutputStream;

public class TestFD {
  public static void main(String[] args) throws Exception {
    Constructor<FileDescriptor> ctor = FileDescriptor.class.getDeclaredConstructor(Integer.TYPE);
    ctor.setAccessible(true);
    FileDescriptor fd = ctor.newInstance(3);
    ctor.setAccessible(false);

    new FileOutputStream(fd).write("hi there\n".getBytes());
  }
}

Чтобы проверить это, я создал простой скрипт Bash, который его компилирует, устанавливает fd3 и запускает java-программу:

#!/bin/bash

javac TestFD.java

exec 3>&1  # open fd3, redirect to stdout
java TestFD
exec 3>&-

Конечно, fd3 перенаправляется на stdout и выводит «hi there there\n» на терминал. Прокомментируйте строку «exec 3> & amp; 1», и программа Java завершится неудачно, как ожидалось, с «IOException», не настроенным на устройство.

Отражение в частном конструкторе FileDescriptor, похоже, отлично работает в тех случаях, когда доступ к / dev / fd невозможно, и он менее суровый, чем попытка создания FileDescriptor с использованием JNI, предложение, которое я видел в другом месте.

Примечание. Я тестировал это в системе BSD. Он может работать или не работать в других системах.

5
ответ дан user2760151 24 August 2018 в 02:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: