2011-01-30 24 views
16

Tôi cần truy cập các bộ mô tả tệp được đánh số từ Java - ngoài 0, 1 hoặc 2.Sử dụng bộ mô tả tệp được đánh số từ Java

Làm cách nào để thực hiện điều này? Tôi nhìn vào lớp FileDescriptor nhưng did'nt tìm thấy bất kỳ cách nào để khởi tạo nó với một số mô tả tập tin nhất định.

Ví dụ cụ thể cho phép giả sử Java được gọi là quá trình con từ một ngôn ngữ lập trình khác. Các bộ mô tả tệp 3 và 4 được cung cấp bởi ngôn ngữ khác cho đầu vào và đầu ra.

Những gì tôi cần trong Java là InputStreamOutputStream đối tượng kết nối với những tập tin mô tả, giống như System.in, System.out và System.error được kết nối với tập tin-desctiptors 0, 1 và 2.

Tôi đang sử dụng Java 1.6 và điều này sẽ chạy trên các hệ thống Unix giống nhau.

giải pháp làm việc Tested:

Câu trả lời với các bộ mô tả tập tin mục hệ thống tập tin đặc biệt đã chỉ cho tôi đến các giải pháp khả thi sau:

  1. tìm hiểu xem và nơi hệ thống cũng như Unix của bạn có một hệ thống tập tin đặc biệt chứa các mục được đặt tên cho tất cả các bộ mô tả tập tin.

    • Tôi đang sử dụng FreeBSD trong đó fdescfs(5) là hệ thống tệp chỉ thực hiện việc này. Dưới Linux nó sẽ là procfs.
  2. đảm bảo hệ thống tập tin này được gắn

    • FreeBSD: đặt fdescfs /dev/fd fdescfs rw 0 0 trong /etc/fstab

      hoặc chạy mount -t fdescfs null /dev/fd trên một dấu nhắc shell (có lẽ với sudo)

  3. Sử dụng mới FileInputStream("/dev/fd/3")new FileOutputStream("/dev/fd/4") để có được những con suối kết nối với filedescriptors (những con đường dành cho FreeBSD, thay bằng đường dẫn hệ điều hành của bạn)

+1

http://www.kfu.com/~nsayer/Java/jni-filedesc.html có thể giúp –

Trả lời

13

Tôi khá chắc chắn điều này không thể được thực hiện bằng Java thuần túy - có thể bạn sẽ phải sử dụng mã gốc để liên kết một bộ mô tả tệp cho đối tượng FileDescriptor hoặc đối tượng FileInputStream hoặc FileOutputStream.

EDIT
Nếu bạn đang sử dụng Linux, * BSD hoặc hệ điều hành MacOS, bạn có thể sử dụng các tập tin giả/dev/fd/nnn để truy cập tập tin mô tả nnn.

+1

Vâng khi học hỏi từ câu trả lời của bạn rằng điều này là không thể trong Java chính nó (mà tôi đã không mơ ước) Tôi đã xem xét hỗ trợ hệ điều hành cho nó. Tôi đang chạy dưới FreeBSD và có/dev/fd/ cho tất cả các mô tả tệp đang mở. –

2

Để bắt đầu với:

Các ứng dụng không nên tạo file descriptor của mình

Bạn có thể thử sử dụng phản ánh để gọi constructor private FileDescriptor(int fd), bằng cách lấy các nhà xây dựng và kêu gọi setAccessible(true) vào nó . Nhưng đó là một hack và tôi không thể đảm bảo nó sẽ làm việc (nó có khả năng là nó sẽ không). Đặc biệt là trích dẫn tôi đã bắt đầu.

+2

Vấn đề của tôi là các bộ mô tả tập tin mà tôi nhận được thông qua là do thời gian chạy của ngôn ngữ khác và các ràng buộc bên ngoài khác mà tôi không có ảnh hưởng. Vì vậy, nhu cầu này không phải do sự lựa chọn của tôi. Tôi sẽ thử đề xuất của bạn cho việc hack. –

+0

Như bạn nghi ngờ ... nó sẽ không hoạt động. Tôi chỉ có thể nhận được các nhà thầu công khai thông qua Class.getConstructor –

+1

@Peer Stritzinger - sử dụng 'FileDescriptor.getDeclaredConstructor (..)' – Bozho

8

Với một SUN JavaVM bạn có thể làm:

FileDescriptor fd = new FileDescriptor(); 
sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess().set(fd,3); 
FileInputStream fin = new FileInputStream(fd); 
+1

Điều này không được hỗ trợ, không phải API và sẽ ngắt bằng Java 9. –

4

thời gian gần đây tôi cần phải làm điều này cho một quá trình con Java chạy trong một nhà tù. Điều này có nghĩa là nó không có quyền truy cập vào hệ thống tập tin/dev/fd.

@Bozho đã nhận xét rằng phản ánh có thể có hoặc không hoạt động để tạo đối tượng FileDescriptor. Dường như nó hoạt động trong một thử nghiệm đơn giản mà tôi đã làm. Sau đây là nguồn cho 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()); 
    } 
} 

Để kiểm tra điều này, tôi đã thực hiện một kịch bản Bash đơn giản mà biên dịch nó, thiết lập fd3, và chạy chương trình java:

#!/bin/bash 

javac TestFD.java 

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

Chắc chắn đủ, fd3 được chuyển hướng đến stdout và xuất ra "hi there \ n" trên thiết bị đầu cuối. Nhận xét ra dòng lệnh "exec 3> & 1" và chương trình Java không thành công như mong đợi với "IOException" không được định cấu hình thiết bị.

Phản ánh trên hàm tạo FileDescriptor riêng có vẻ hoạt động tốt trong trường hợp không thể truy cập/dev/fd và ít phức tạp hơn là cố gắng tạo FileDescriptor bằng JNI, gợi ý mà tôi đã thấy ở nơi khác.

Lưu ý: Tôi đã thử nghiệm điều này trên hệ thống BSD. Nó có thể hoặc có thể không hoạt động trên các hệ thống khác.

+0

Điều này không hoạt động trên Windows, vì hàm tạo duy nhất là mặc định. – Vulcan

Các vấn đề liên quan