Android NDK char数组初始化超过1Mb

时间:2018-03-21 08:58:59

标签: android c android-ndk kotlin

初始化一个简单的char数组时遇到问题。 (值为0' s)char数组的大小更高和/或等于2Mb。我已经搜索了互联网并阅读了我能找到的所有内容(从source到...我不知道)并尝试了许多不同的过程(尝试将值附加到char数组中以尝试... 。)此代码的目的是使用C库(NDK)写入文件。如果我尝试写入等于或低于1Mb的值,则下面显示的snipper工作正常。请帮我提出可以取代" memset"的建议。以下是示例代码:

我的c库:

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <linux/errno.h>
#include <errno.h>
#include <fcntl.h>


#define APPNAME "AppLogger2"

#define  ALOG(...)  __android_log_print(ANDROID_LOG_INFO,APPNAME,__VA_ARGS__)

int fd_is_valid(int fd) {
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}


extern "C"
JNIEXPORT jboolean


JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
        JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {

    char str[80];
    sprintf(str, "FileDescriptor Primit = %d", fd);
    ALOG(str, __LINE__);

    if (fd_is_valid(fd)) {
        char buf[bufferSize];//allocate buffer
        memset(buf, patterntoWrite, (size_t) bufferSize);// init buffer

        while (true) {
            if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
                if (0 > fsync(fd)) //write to the raw disk
                {
                    ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                    break;
                }
            } else {
                ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                break;
            }
        }
        return JNI_TRUE;
    } else {
        ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
    }

    return JNI_FALSE;
}

Java代码:

class WiperWorkerImpl(val pathToFile: DocumentFile, ...): Runnable{

    companion object {

        const val useCExternalFunctionToOverWriteSpace = true

        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun executeWiping(fileDescriptorValue: Int, bytesToWrite:Long, patternToUse:Int): Boolean


override fun run() {
val pfd: ParcelFileDescriptor = contentResolver.openFileDescriptor(pathToFile.uri, "w")
                        if(checkTheRamSpaceForTheBytestThatAreGoingToBeWritten(bytesPerBlockToWriteLocalThread.get())) {
                            if (executeWiping(pfd.fd, bytesPerBlockToWriteLocalThread.get(), 0)) {
                                AppLogger.i("WiperWorkerImpl. Finish with success")
                            } else {
                                AppLogger.e("WiperWorkerImpl. Finished with error!")
                            }
                        }
                        closeFileDescriptor(pfd)
}

}

错误: What is the maximum size of buffers memcpy/memset etc. can handle?

1 个答案:

答案 0 :(得分:1)

谢谢unwind,你救了我。现在它工作正常。这是正确的代码:

JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
        JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {

    char str[80];
    sprintf(str, "FileDescriptor Primit = %d", fd);
    ALOG(str, __LINE__);

    if (fd_is_valid(fd)) {

        char *buf = (char*) calloc(bufferSize, sizeof(char));//allocate buffer. Now it doesn't matter how big is the buffer
        for(int i=0;i<bufferSize;i++)
        {
            buf[i] = 0;
        }

        while (true) {
            if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
                if (0 > fsync(fd)) //write to the raw disk
                {
                    ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                    break;
                }
            } else {
                ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
                break;
            }
        }
        return JNI_TRUE;
    } else {
        ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
    }

    return JNI_FALSE;
}