Строки чтения и Двоичный файл от того же FileInputStream

Вы можете получить дескриптор файла (который Apple называет «Native Handle»), и с его помощью использовать типичные сетевые команды POSIX для получения адреса:

Получить дескриптор файла из потока:

CFDataRef handleData = (CFDataRef)CFReadStreamCopyProperty((__bridge CFReadStreamRef) inputStream, kCFStreamPropertySocketNativeHandle);
long length = CFDataGetLength(handleData);
uint8_t * buffer = malloc(length);
CFDataGetBytes(handleData, CFRangeMake(0, length), buffer);
int sock_fd = (int)*buffer;

Получите удаленный адрес для этого дескриптора файла:

struct sockaddr addr;
socklen_t addr_len = sizeof(addr);
getpeername(sock_fd, &addr, &addr_len);
NSString * remoteAddr;
if (addr.sa_family == AF_INET) {
    char addressString[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, addressString, INET_ADDRSTRLEN);
    remoteAddr = [[NSString alloc] initWithUTF8String:addressString];
} else if (addr.sa_family == AF_INET6) {
    char addressString[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, addressString, INET6_ADDRSTRLEN);
    remoteAddr = [[NSString alloc] initWithUTF8String:addressString];
}
free(buffer);

// Now you have remoteAddr which will be a
// string representation of a IPv4 or IPv6 address!
NSLog(@"Remote Address: %@", remoteAddr);
7
задан AlikElzin-kilaka 9 August 2014 в 05:27
поделиться

7 ответов

Если у Вас действительно есть файл (а не что-то тяжелее для поиска в, например, сетевой поток) затем, я предлагаю что-то вроде этого:

  • Откройте файл как FileInputStream
  • Перенесите его в InputStreamReader и BufferedReader
  • Прочитайте текст, таким образом, можно узнать, сколько там содержание
  • Закройте BufferedReader (который закроет InputStreamReader, который закроет FileInputStream),
  • Вновь откройте файл
  • Пропустите к (общая длина файла - двоичная длина содержания)
  • Считайте остальную часть данных как нормальную

Вы могли просто звонить mark() в начале FileInputStream и затем reset() и skip() добираться до правильного места, если Вы не хотите вновь открыть файл. (Я искал InputStream.seek() но я не вижу один - я не могу помнить желать это прежде в Java, но разве это действительно не имеет того? Ick.)

3
ответ дан 6 December 2019 в 23:13
поделиться

Вы могли использовать RandomAccessFile. Использовать readLine() прочитать простой текст в запуске (отмечают ограничения этого, как описано в API), и затем readByte() или readFully() считывать последующие двоичные данные.

Используя базовое FileInputStream считать возвраты пустые массивы байтов.

Поэтому Вы перенесли поток в a BufferedReader, который, вероятно, использовал все байты от потока при заполнении его буфера.

5
ответ дан 6 December 2019 в 23:13
поделиться

Необходимо использовать InputStream. Читатели для символьных данных. Изучите обертывание Вашего входного потока с DataInputStream, как:

stream=new DataInputStream(new BufferedInputStream(new FileInputStream(...)));

Поток ввода данных даст Вам много полезных методов для чтения различных типов данных, и конечно, основные методы InputStream для чтения байтов.

(Это на самом деле точно, что сервер HTTP должен сделать для чтения запроса с содержанием.)


readUTF не читает строку, он читает строку, которая была записана в (измененном) формате UTF8 - относятся к JavaDoc.

2
ответ дан 6 December 2019 в 23:13
поделиться

Корректный путь состоит в том, чтобы использовать InputStream некоторой формы, вероятно, FileInputStream, если это не становится барьером производительности.

Что делает Вы означаете "Используя базовый FileInputStream читать возвраты пустые массивы байтов".? Это кажется очень маловероятным и, вероятно, где Ваша ошибка. Можно ли показать нам пример кода, который Вы попробовали?

0
ответ дан 6 December 2019 в 23:13
поделиться

Можно прочитать текст с BufferedReader. Когда Вы знаете, где двоичный файл запускается, можно закрыть файл и открыть его с RandomAccessFile и считать двоичный файл из любой точки в файле. Или можно считать файл, столь же двоичный, и преобразовать для отправки текстовых сообщений разделам, которые Вы определяете как текст. {Используя новую Строку (байты, кодируя)}

0
ответ дан 6 December 2019 в 23:13
поделиться

Я рекомендую использовать DataInputStream. У Вас есть следующие опции:

  • Прочитайте и текст и двоичное содержание с DataInputStream
  • Откройте BufferedReader, прочитайте текст и закройте поток. Затем откройте DataInputStream, пропустите байты, равные размеру текста, и считайте двоичные данные.
0
ответ дан 6 December 2019 в 23:13
поделиться

Увы, DataInputStream устарел и не поддерживает UTF. Но это должно помочь (он считывает строку из двоичного потока без предварительного просмотра).

public static String lineFrom(InputStream in) throws IOException {
    byte[] buf = new byte[128];
    int pos = 0;
    for (;;) {
        int ch = in.read();
        if (ch == '\n' || ch < 0) break;
        buf[pos++] = (byte) ch;
        if (pos == buf.length) buf = Arrays.copyOf(buf, pos + 128);
    }
    return new String(Arrays.copyOf(buf, pos), "UTF-8");
}
1
ответ дан 6 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

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