2013-09-21 31 views
1

在現代Java(僅使用標準庫)中讀取標準輸入的所有直到將EOF讀入字節數組,最好不必自己提供該數組,最簡單的方法是什麼? stdin數據是二進制文件,不是來自文件。將所有標準輸入讀入Java字節數組

I.e.像Ruby的

foo = $stdin.read 

唯一的部分解決方案,我能想到的是沿

byte[] buf = new byte[1000000]; 
int b; 
int i = 0; 

while (true) { 
    b = System.in.read(); 
    if (b == -1) 
     break; 
    buf[i++] = (byte) b; 
} 

byte[] foo[i] = Arrays.copyOfRange(buf, 0, i); 

行......但似乎奇怪的是冗長甚至對Java和使用一個固定大小的緩衝區。

回答

2

我會使用Guava及其ByteStreams.toByteArray方法:

byte[] data = ByteStreams.toByteArray(System.in); 

不使用任何第三方庫,我會使用一個ByteArrayOutputStream和臨時緩衝區:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buffer = new byte[32 * 1024]; 

int bytesRead; 
while ((bytesRead = System.in.read(buffer)) > 0) { 
    baos.write(buffer, 0, bytesRead); 
} 
byte[] bytes = baos.toByteArray(); 

...可能將其封裝在接受InputStream的方法中,然後基本上相當於ByteStreams.toByteArray ...

+0

感謝。非常瘋狂,像番石榴解決方案的東西不在主線stdlib。 – user2802683

+0

原因不是因爲Java作者試圖阻止將東西讀入字節數組(它將會破壞足夠大的數據),因爲它可以/應該作爲流處理(它可以處理無限數量的數據)。 –

1

如果您正在從文件中讀取數據,則需要使用Files.readAllBytes

否則,我會使用一個字節緩衝區:

ByteBuffer buf = ByteBuffer.allocate(1000000); 
ReadableByteChannel channel = Channels.newChannel(System.in); 
while (channel.read(buf) >= 0) 
    ; 
buf.flip(); 
byte[] bytes = Arrays.copyOf(buf.array(), buf.limit()); 
+0

這是錯誤的,因爲你沒有檢查buf.hasRemaining() – tmoschou

+0

其實,檢查hasRemaining()是一個壞主意。我們的目標是讀取所有的字節,所以我們不想因爲碰到緩衝區而停止讀取。例外情況好於將截斷數據視爲完整數據。我假定最大值爲1000000,因爲OP似乎對這個假設感到滿意。 – VGR