2013-03-21 27 views
6

Làm cách nào để ghi vào stdout từ ứng dụng bảng điều khiển Delphi?Làm thế nào để ghi dữ liệu nhị phân vào stdout trong Delphi?

Đây là những gì tôi đã thử. Tôi đã gian lận ứng dụng thử nghiệm đơn giản này theo infos tôi có thể tìm thấy, để đọc một tập tin từ đĩa và xuất nó sang giao diện điều khiển stdout:

program ConsoleOut; 
{$APPTYPE CONSOLE} 
uses 
    Classes, Windows, SysUtils; 

var 
    S: TMemoryStream; 
    OutputStream: THandleStream; 
    ss: string; 
    Buffer: PByte; 
    i: Integer; 
begin 
    S := TMemoryStream.Create; 
    S.LoadFromFile('1.jpg'); 
    S.Seek(0, soFromBeginning); 

    //Am I right that from now on writing to OutputStream will write to stdout? 
    OutputStream := THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE)); 

    GetMem(Buffer, S.Size); 
    S.ReadBuffer(Buffer^, S.Size); 
    i := OutputStream.Write(Buffer^, S.Size); //i = 0 here for some reason 
    FreeMem(Buffer, S.Size); 

    Writeln(i, ' byte written to output'); 
    Readln(ss); //Don't exit app to read previous line 
    S.Free; 
end. 

Nhưng vì lý do nào đó nó không thành công. Bạn có thể vui lòng hướng dẫn tôi vào cách viết thích hợp để stdout không?

+0

tò mò TẠI SAO bạn muốn ghi âm nhị phân vào bàn điều khiển? Bạn đề cập đến một cái gì đó về văn bản để nói. Tại sao không đặt tên đường ống? –

+1

Ống dẫn có tên ưu điểm nào có chống lại stdout? – Kromster

+0

Được thiết kế để truyền dữ liệu nghiêm trọng thay vì giao diện người dùng, trên Windows. Đầu ra tiêu chuẩn Unix thường được sử dụng như một đường ống dữ liệu ẩn danh. Dos và Windows không thường xuyên sử dụng này. Như bạn đã học. –

Trả lời

7

Cách tiếp cận của bạn là âm thanh. Tuy nhiên, nếu stdout được gắn vào một giao diện điều khiển thì mã của bạn không thành công. Cuộc gọi đến GetLastError sau khi ghi luồng sẽ hiển thị mã lỗi ERROR_NOT_ENOUGH_MEMORY:

Không đủ bộ nhớ để xử lý lệnh này.

Nếu bạn chuyển hướng stdout vào tệp thì mã của bạn sẽ hoạt động tốt. Và chắc chắn bạn không thực sự muốn phun dữ liệu nhị phân lên bàn điều khiển. Đó là chỉ cần đặt nội dung không đọc được trên bàn điều khiển và làm cho tiếng bíp máy tính khó chịu!

Nếu bạn phải xuất ra bàn điều khiển, bạn sẽ cần phải tìm hiểu bộ đệm thiết bị bàn điều khiển lớn và ghi vào bộ phận có kích thước phù hợp như thế nào. Tôi phải thú nhận rằng tôi không chắc chắn làm thế nào bạn đi về làm điều đó. Bạn có thể sử dụng thử và sai, nhưng điều đó không hấp dẫn tôi. Có lẽ có một cách để truy vấn bàn điều khiển để tìm hiểu thông tin.

Nhìn vào tài liệu cho WriteConsole, có vẻ như 64K là giới hạn trên. Và thực sự nếu tôi viết không gian cho dòng xử lý của bạn thì tôi có thể viết gần 64K trong một lần. Tuy nhiên, nếu tôi viết dữ liệu nhị phân JPEG thô, thì nó sẽ đưa ra trước đó. Vì vậy, tôi nghĩ rằng đó là một phần của vấn đề quá - không đổ một JPEG lên bàn điều khiển.

Một nhận xét khác. Vì bạn đọc nội dung của tệp vào luồng bộ nhớ nên không cần phân bổ bộ đệm trung gian. Bạn có thể viết trực tiếp S.Memory^.

+1

Cảm ơn gợi ý, tôi nghĩ rằng nếu giao diện điều khiển là trống nó không hoạt động, nhưng chuyển hướng stdout vào một tập tin ("appname.exe> ​​out.jpg") làm việc ra tốt. – Kromster

+1

Trên một sidenote: Tôi đang làm việc trên một ứng dụng mà cần phải tạo ra và đầu ra text-to-speech vào stdout, do đó, có, đó là dữ liệu nhị phân và rất nhiều của nó (vài Mb). Nhưng câu trả lời của bạn bao gồm nhiều khía cạnh, vì vậy xin đừng cắt nó, để nó hữu ích cho người khác) – Kromster

+0

@KromStern: Nhận xét cuối cùng của bạn không có ý nghĩa gì cả. Nếu bạn đang thực hiện 'text to speech to stdout' và sau đó chuyển hướng' stdout' sang một tệp, bạn có thể chỉ đơn giản là 'text to speech to file' và cắt ra trung gian' stdout'. Không có điểm bằng văn bản cho giao diện điều khiển để ngay lập tức chuyển hướng đầu ra đó vào một tệp. –

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