原理在上一篇已经说好了,在这就不再赘述了,直接上代码,代码只是实现了一个基本框架,需要完善的东西大家可以自己加:
NamedPipe.java
public class NamedPipe implements Pipe {
static{
System.loadLibrary("NPJNI");
}
NamedPipeInputStream is;
NamedPipeOutputStream os;
int handle = -1;
private String name;
public String getName() {
return name;
}
public NamedPipe(String name){
this.name = name;
this.handle = this.create(name);
if(handle == -1){
throw new NamedPipeCreateException(name);
}
}
/**
* 等待接受一个客户端连接(堵塞)
* @return
*/
public boolean accept(){
return this.connect(this.handle);
}
/**
* 得到一个PipeInputStream以读入数据
*/
public PipeInputStream getInputStream() {
if(is == null){
is = new NamedPipeInputStream(this);
}
return is;
}
/**
* 得到一个PipeOutputStream以写入数据
*/
public PipeOutputStream getOutputStream() {
if(os == null){
os = new NamedPipeOutputStream(this);
}
return os;
}
/**
* 关闭此NamedPipe
*/
public void close() {
if(this.handle != -1){
this.close(this.handle);
}
}
/**
* 断开当前的客户端连接
*/
public void disconnect(){
disconnect(handle);
}
private native void disconnect(int handle);
private native void close(int handle);
private native int create(String name);
private native boolean connect(int handle);
}
NamedPipeInputStream:
public class NamedPipeInputStream extends PipeInputStream {
NamedPipe pipe;
static{
System.loadLibrary("NPJNI");
}
NamedPipeInputStream(NamedPipe pipe){
this.pipe = pipe;
}
private native int readBytes(int handle, byte b[], int len) throws IOException;
/**
* 读入数据到一个beye数组(堵塞)
* @return 实际读取的字节数
*/
public int read(byte b[]) throws IOException {
return readBytes(pipe.handle, b, b.length);
}
/**
* 读入数据到一个beye数组(堵塞)
* @param b
* @return 读取信息
*/
public ReadPipeInfo readPipe(byte b[]){
return this.readPipe(pipe.handle,b,b.length);
}
public native ReadPipeInfo readPipe(int handle, byte b[], int len);
}
NamedPipeOutputStream.java:
public class NamedPipeOutputStream extends PipeOutputStream {
NamedPipe pipe;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
static{
System.loadLibrary("NPJNI");
}
NamedPipeOutputStream(NamedPipe pipe){
this.pipe = pipe;
}
/*public final NamedPipe getPipe(){
return pipe;
}*/
private native void writeBytes(int handle, byte b[], int len)
throws IOException;
private native void writeBytesOff(int handle, byte b[], int offset, int len)
throws IOException;
/**
* 将一个byte数组写入管道
*/
public void write(byte b[]) throws IOException {
buffer.write(b);
}
/**
* 将字符串s写入管道
* @throws IOException
*/
public void write(String s) throws IOException{
buffer.write(s.getBytes());
}
/**
* 将byte数组写入管道。off指定了写入的偏移值,len指定写入的长度
*/
@Override
public void write(byte[] b, int off, int len) throws IOException {
this.writeBytesOff(pipe.handle,b,off,len);
}
/**
* flush此NamedPipeOutputStream,将所有数据写入管道
*/
public void flush() {
byte[] bytes = buffer.toByteArray();
if(bytes.length > 0){
try {
writeBytes(pipe.handle, bytes, bytes.length);
} catch (IOException e) {
e.printStackTrace();
}
buffer = new ByteArrayOutputStream();
flush(pipe.handle);
}
}
private native void flush(int handle);
}
ReadPipeInfo.java:
public class ReadPipeInfo {
boolean more = false;
int count = -1;
public boolean hasMoreData(){
return this.more;
}
public int readCount(){
return count;
}
}
C++代码:
#define BUFSIZE 4096*500
JNIEXPORT jint JNICALL Java_pipe_NamedPipe_create
(JNIEnv *env, jobject obj, jstring name)
{
const wchar_t *str = (const wchar_t *)env->GetStringChars(name,NULL);
if(str == NULL)
{
return -1;
}
HANDLE hPipe;
hPipe = CreateNamedPipe(
str, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
0, // client time-out
NULL); // default security attribute
if (hPipe == INVALID_HANDLE_VALUE)
{
env->ReleaseStringChars(name, (const jchar *)str);
printf("CreatePipe failed");
return -1;
}
env->ReleaseStringChars(name, (const jchar *)str);
return (long)hPipe;
}
JNIEXPORT jboolean JNICALL Java_pipe_NamedPipe_connect
(JNIEnv *env, jobject obj, jint handle)
{
HANDLE hPipe = (void *)((int)handle);
BOOL fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
return fConnected;
}
JNIEXPORT void JNICALL Java_pipe_NamedPipe_close
(JNIEnv *env, jobject obj, jint handle)
{
CloseHandle((void *)((int)handle));
}
JNIEXPORT void JNICALL Java_pipe_NamedPipe_disconnect
(JNIEnv *env, jobject obj, jint handle)
{
HANDLE hPipe = (void *)((int)handle);
DisconnectNamedPipe(hPipe);
}
JNIEXPORT jint JNICALL Java_pipe_NamedPipeInputStream_readBytes
(JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
//jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
char *cBuffer = new char[len+1];
DWORD cbBytesRead;
HANDLE hPipe = (void *)((int)handle);
BOOL fSuccess = ReadFile(
hPipe, // handle to pipe
cBuffer, // buffer to receive data
len, // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
{
delete cBuffer;
return -1;
}
env->SetByteArrayRegion(buffer,0,cbBytesRead,(const jbyte *)cBuffer);
delete cBuffer;
return cbBytesRead;
}
JNIEXPORT jobject JNICALL Java_pipe_NamedPipeInputStream_readPipe
(JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
//jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
char *cBuffer = new char[len+1];
DWORD cbBytesRead;
HANDLE hPipe = (void *)((int)handle);
BOOL fSuccess = ReadFile(
hPipe, // handle to pipe
cBuffer, // buffer to receive data
len, // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
DWORD le = GetLastError();
if (! fSuccess && le != ERROR_MORE_DATA)
{
jclass jclass = env->FindClass("pipe/ReadPipeInfo");
jfieldID moreData = env->GetFieldID(jclass,"more","Z");
jfieldID count = env->GetFieldID(jclass,"count","I");
jmethodID mID = env->GetMethodID(jclass, "<init>", "()V");
jobject info = env->NewObject(jclass,mID);
delete cBuffer;
env->SetBooleanField(info,moreData,false);
env->SetIntField(info,count,-1);
env->DeleteLocalRef(jclass);
return info;
}
jclass jclass = env->FindClass("pipe/ReadPipeInfo");
jfieldID moreData = env->GetFieldID(jclass,"more","Z");
jfieldID count = env->GetFieldID(jclass,"count","I");
jmethodID mID = env->GetMethodID(jclass, "<init>", "()V");
jobject info = env->NewObject(jclass,mID);
env->SetByteArrayRegion(buffer,0,cbBytesRead,(const jbyte *)cBuffer);
delete cBuffer;
if(le == ERROR_MORE_DATA){
env->SetBooleanField(info,moreData,true);
}else{
env->SetBooleanField(info,moreData,false);
}
env->SetIntField(info,count,cbBytesRead);
//env->SetShortField(info,count,10);
env->DeleteLocalRef(jclass);
return info;
}
JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_writeBytes
(JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
DWORD cbWritten;
HANDLE hPipe = (void *)((int)handle);
// Write to the pipe.
BOOL fSuccess = WriteFile(
hPipe, // handle to pipe
jBuffer, // buffer to write from
len, // number of bytes to write
&cbWritten, // number of bytes written
NULL); // not overlapped I/O
}
JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_writeBytesOff
(JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint off, jint len)
{
jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
DWORD cbWritten;
HANDLE hPipe = (void *)((int)handle);
// Write to the pipe.
BOOL fSuccess = WriteFile(
hPipe, // handle to pipe
jBuffer+off, // buffer to write from
len, // number of bytes to write
&cbWritten, // number of bytes written
NULL); // not overlapped I/O
}
JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_flush
(JNIEnv *env, jobject obj, jint handle)
{
HANDLE hPipe = (void *)((int)handle);
BOOL flag = FlushFileBuffers(hPipe);
}
分享到:
相关推荐
这篇博客文章“Java中JNI的使用(一)——native”很可能是对Java程序员如何首次接触和使用JNI的一个入门教程。 首先,我们来理解“native”关键字。在Java中,`native`是用来标记一个方法的,表示这个方法的实现是在...
NULL 博文链接:https://zhoucl.iteye.com/blog/1101661
这篇博客“JNI编程(二) —— 让C++和Java相互调用(2)”显然深入探讨了如何利用JNI实现Java与C++之间的互调用。在Java应用程序中,有时为了性能优化或者利用已有的C/C++库,我们需要借助JNI来实现这种跨语言的通信。 ...
在本案例中,JNI被用来连接OPC(OLE for Process Control)服务器,这是一种工业自动化领域的标准接口,用于不同设备和系统之间的数据交换。 OPC服务器是一个中间件,它提供了与工业控制系统设备通信的标准接口。...
综上所述,"Android中JNI实现AES加密源代码"涉及的知识点包括Android JNI的使用、AES加密算法的实现、NDK开发环境的配置、C/C++与Java的交互,以及数据安全和性能优化。通过这样的实现,开发者可以在Android应用中...
JNI(Java Native Interface)是Java语言的一个重要特性,它允许Java代码和其他语言编写的本地代码进行交互,这在Java应用中实现与底层系统特定功能的访问时尤其有用。要深入理解JNI的实现原理,本书《JNI实现原理...
在Android开发中,有时为了提高性能或利用C/C++库的优势,我们会选择使用JNI(Java Native Interface)来实现部分功能。本资源提供了一个具体的实例,即在Android环境下使用JNI实现AES(Advanced Encryption ...
本项目主要探讨了如何使用C++语言通过JNI(Java Native Interface)与Android应用交互,实现基于OpenSSL库的加解密算法,包括RSA、AES、3DES、BASE64和MD5。以下是关于这些技术的详细解释: 1. **JNI(Java Native ...
"安卓手机音频调用JNI实现"的项目就是利用JNI来优化音频处理的效率,减少时间延迟,提升用户体验。 JNI在Android中的应用主要涉及以下几个方面: 1. **性能优化**:Java虚拟机(JVM)对于一些底层操作,如硬件直接...
Java 通过JNI(Java Native Interface)实现口令屏蔽是一种在Java应用程序中安全处理敏感数据,如密码或密钥,的方法。JNI是Java平台提供的一种机制,允许Java代码和其他语言写的代码进行交互。在这个场景中,C++代码...
熟练掌握JNI能够帮助你充分利用Java的跨平台特性,同时结合本地代码的优势,提升应用性能或者实现特定功能。在进行JNI编程时,确保理解并正确处理内存管理、线程安全以及错误处理是非常重要的。
在这个“jni例子——使用int数组”的示例中,我们将深入探讨如何在Java和C/C++之间传递和操作int数组。 1. **JNI基础知识**: - JNI接口提供了Java与本地代码(如C/C++)通信的桥梁,使得开发者可以在Java应用中...
本示例中,我们将深入探讨如何使用JNI实现回调机制以及在JNI中开启线程。 1. **JNI回调JAVA的函数**: 在Java中,我们通常通过定义`native`关键字声明本地方法,这些方法将在JNI层实现。为了在JNI中调用Java的方法...
yuv420p转yuv420sp的jni实现 修改下全类名就可以使用
标题中的“使用JNI和DES实现两次加密”是指在Java编程中结合使用JNI(Java Native Interface)和DES(Data Encryption Standard)加密算法来实现双重安全保护的一种技术。这种技术通常用于提高程序的安全性,防止数据在...
在本文中,我们将深入探讨如何将SeetaFace6JNI集成到SpringBoot应用中,实现高效的人脸检测和识别功能。SeetaFace6JNI是SeetaFace6库的一个Java封装,它提供了一种与Java应用程序交互的方式,使得在Java环境中也能...
本主题探讨的是如何利用JNI来实现高斯模糊图片的功能。高斯模糊是一种图像处理技术,通过模拟人类视觉系统对图像进行平滑处理,减少图像的噪声和细节,使图像呈现出柔和的效果。 首先,我们要理解高斯模糊的基本...
在这个"通过JNI实现C++与JAVA相互调用之TCP编程"的示例中,我们探讨的是如何使用JNI来实现TCP通信,其中C++作为底层通信引擎,而Java则负责上层应用逻辑。 首先,TCP(Transmission Control Protocol)是一种面向...