6
A
回答
6
下面的代碼使用dup2
到stdout堵塞到一個NSPipe
對象的寫入端。讀端由一個GCD調度源來觀察,它從管道讀取數據並將其附加到文本視圖。
NSPipe* pipe = [NSPipe pipe];
NSFileHandle* pipeReadHandle = [pipe fileHandleForReading];
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [pipeReadHandle fileDescriptor], 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(source, ^{
void* data = malloc(4096);
ssize_t readResult = 0;
do
{
errno = 0;
readResult = read([pipeReadHandle fileDescriptor], data, 4096);
} while (readResult == -1 && errno == EINTR);
if (readResult > 0)
{
//AppKit UI should only be updated from the main thread
dispatch_async(dispatch_get_main_queue(),^{
NSString* stdOutString = [[NSString alloc] initWithBytesNoCopy:data length:readResult encoding:NSUTF8StringEncoding freeWhenDone:YES];
NSAttributedString* stdOutAttributedString = [[NSAttributedString alloc] initWithString:stdOutString];
[self.logView.textStorage appendAttributedString:stdOutAttributedString];
});
}
else{free(data);}
});
dispatch_resume(source);
NSLog(@"...")
不輸出到stdout
雖然 - 它打印到stderr
。如果你想重定向到您的TextView,改變
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
到
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
0
如果目標是隻能處理您的NSLog輸出,而不是生成系統錯誤日誌,有一個其他的方式來這樣做,這是一個代碼來覆蓋NSLog。此代碼只打印日誌和標準錯誤,而不是通常的NSLog輸出一些額外的信息,但可以作出這樣的套房HyperLog函數內部需求的任何變化:
HyperLog.h
#import <Foundation/Foundation.h>
#ifdef HYPER_LOG
#define NSLog(args...) HyperLog(__FILE__,__LINE__,__PRETTY_FUNCTION__,args);
#else
#define NSLog(x...)
#endif
void HyperLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...);
Hyperlog .M
#import "HyperLog.h"
void HyperLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...)
{
va_list ap;
va_start (ap, format);
if (![format hasSuffix: @"\n"])
{
format = [format stringByAppendingString: @"\n"];
}
NSString *body = [[NSString alloc] initWithFormat:format arguments:ap];
va_end (ap);
NSString *fileName = [[NSString stringWithUTF8String:file] lastPathComponent];
char mesg[8192]="\0";
NSDate *now =[NSDate date];
NSString *dateString = [NSDateFormatter localizedStringFromDate:now dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterMediumStyle];
if (sprintf(mesg, "<%s.%03.0f> : %s\n<%s : %d - %s>\n", [dateString UTF8String],roundf(fmod([now timeIntervalSinceReferenceDate], 1) * 1000), [body UTF8String], [fileName UTF8String],
lineNumber,
functionName) < 0) printf("message creation failed\n");
fprintf(stderr, "%s", mesg);
}
然後你只需把這些2行上的任何程序文件的頂部 有它的工作
#define HYPER_LOG
#import "HyperLog.h"
我試圖使用托馬斯的上述代碼將系統的結果數據生成的錯誤日誌寫入使用C函數的文本文件,該函數在其他上下文中正常工作,但它保持並崩潰,並且錯誤在這個過程中失去了理智。任何人有一個想法爲什麼?
相關問題
- 1. 在可可中將stdout重定向到NSTextView的最佳方式是什麼?
- 2. Python。將stdout重定向到套接字
- 3. Tomcat將'stderr'內容重定向到'stdout'
- 4. 將stdin _and_ stdout重定向到管道
- 5. 只將stdout重定向到/ dev/null
- 6. 將subprocess.check_call的stdout重定向到函數?
- 7. 將stdout重定向到文件問題?
- 8. 嘗試將stdout重定向到文件
- 9. JNA將STDOUT重定向到JFrame
- 10. 將子進程stderr重定向到stdout
- 11. 將stdout和stderr重定向到函數
- 12. D將stdout重定向到函數
- 13. 將Stdin和Stdout重定向到文件
- 14. 將log4j stdout重定向到InputStream
- 15. 將stdout重定向到套接字
- 16. Unix C - 將stdout重定向到pipe然後返回stdout
- 17. 如何在Java中將子進程stdout/stderr重定向到主進程stdout/stderr?
- 18. 如何將stderr/stdout重定向到我在C++中的日誌?
- 19. 如何將stdout重定向到tcl文件中
- 20. 如何將stdout和stderr重定向到Python中的記錄器
- 21. 如何將stderr重定向到Ant中的stderr或stdout?
- 22. c#如何將stdout重定向到新的進程窗口?
- 23. 在Linux系統上,我如何將stdout重定向到stderr?
- 24. 如何將jmeter stdout重定向到一個文件
- 25. 如何將stdout重定向到一個子進程的stdin?
- 26. 如何將stdout輸出重定向到新的Vim選項卡?
- 27. 如何將stdout重定向到文件和`sys .__ stdout__`?
- 28. 如何將STDOUT和STDERR重定向到變量
- 29. 如何將stdout和stdin重定向到telnet連接?
- 30. 如何將stderr重定向到Ant JUnit目標中的stdout?
這可能是一個愚蠢的問題,但是:如果NSPipe已經被緩衝了(通過它自己的實現或者由它包裝的OS構造),那麼爲什麼需要定義自己的數據緩衝區? – algal 2015-12-08 00:33:54
你是對的NSPipe默認被緩衝(來自文檔「...管道被緩衝;緩衝區的大小由底層操作系統決定......」)。但是,在分塊讀取時,可能還是一個好主意,以便在您自己的進程中更好地控制內存消耗。 (聽起來像管道的緩衝區由操作系統維護) – 2015-12-09 08:35:16
另外,是否有可能'do'循環錯誤地測試錯誤或終止條件,而不是缺少這些條件? – algal 2015-12-09 17:04:04